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 "AliITSPlaneEff.h"
38 #include "AliITSCalibrationSPD.h"
39 #include "AliITSCalibrationSDD.h"
40 #include "AliITSCalibrationSSD.h"
41 #include "AliCDBEntry.h"
42 #include "AliCDBManager.h"
43 #include "AliAlignObj.h"
44 #include "AliTrackPointArray.h"
45 #include "AliESDVertex.h"
46 #include "AliESDEvent.h"
47 #include "AliESDtrack.h"
50 #include "AliITSChannelStatus.h"
51 #include "AliITSDetTypeRec.h"
52 #include "AliITSRecPoint.h"
53 #include "AliITSRecPointContainer.h"
54 #include "AliITSgeomTGeo.h"
55 #include "AliITSReconstructor.h"
56 #include "AliITSClusterParam.h"
57 #include "AliITSsegmentation.h"
58 #include "AliITSCalibration.h"
59 #include "AliITSPlaneEffSPD.h"
60 #include "AliITSPlaneEffSDD.h"
61 #include "AliITSPlaneEffSSD.h"
62 #include "AliITSV0Finder.h"
63 #include "AliITStrackerMI.h"
65 ClassImp(AliITStrackerMI)
67 AliITStrackerMI::AliITSlayer AliITStrackerMI::fgLayers[AliITSgeomTGeo::kNLayers]; // ITS layers
69 AliITStrackerMI::AliITStrackerMI():AliTracker(),
79 fLastLayerToTrackTo(0),
82 fTrackingPhase("Default"),
88 fxTimesRhoPipeTrks(0),
89 fxOverX0ShieldTrks(0),
90 fxTimesRhoShieldTrks(0),
92 fxTimesRhoLayerTrks(0),
99 for(i=0;i<4;i++) fSPDdetzcentre[i]=0.;
100 for(i=0;i<2;i++) {fxOverX0Shield[i]=-1.;fxTimesRhoShield[i]=-1.;}
101 for(i=0;i<6;i++) {fxOverX0Layer[i]=-1.;fxTimesRhoLayer[i]=-1.;}
103 //------------------------------------------------------------------------
104 AliITStrackerMI::AliITStrackerMI(const Char_t *geom) : AliTracker(),
105 fI(AliITSgeomTGeo::GetNLayers()),
114 fLastLayerToTrackTo(AliITSRecoParam::GetLastLayerToTrackTo()),
117 fTrackingPhase("Default"),
123 fxTimesRhoPipeTrks(0),
124 fxOverX0ShieldTrks(0),
125 fxTimesRhoShieldTrks(0),
126 fxOverX0LayerTrks(0),
127 fxTimesRhoLayerTrks(0),
129 fITSChannelStatus(0),
132 //--------------------------------------------------------------------
133 //This is the AliITStrackerMI constructor
134 //--------------------------------------------------------------------
136 AliWarning("\"geom\" is actually a dummy argument !");
142 for (Int_t i=1; i<AliITSgeomTGeo::GetNLayers()+1; i++) {
143 Int_t nlad=AliITSgeomTGeo::GetNLadders(i);
144 Int_t ndet=AliITSgeomTGeo::GetNDetectors(i);
146 Double_t xyz[3], &x=xyz[0], &y=xyz[1], &z=xyz[2];
147 AliITSgeomTGeo::GetOrigTranslation(i,1,1,xyz);
148 Double_t poff=TMath::ATan2(y,x);
150 Double_t r=TMath::Sqrt(x*x + y*y);
152 AliITSgeomTGeo::GetOrigTranslation(i,1,2,xyz);
153 r += TMath::Sqrt(x*x + y*y);
154 AliITSgeomTGeo::GetOrigTranslation(i,2,1,xyz);
155 r += TMath::Sqrt(x*x + y*y);
156 AliITSgeomTGeo::GetOrigTranslation(i,2,2,xyz);
157 r += TMath::Sqrt(x*x + y*y);
160 new (fgLayers+i-1) AliITSlayer(r,poff,zoff,nlad,ndet);
162 for (Int_t j=1; j<nlad+1; j++) {
163 for (Int_t k=1; k<ndet+1; k++) { //Fill this layer with detectors
164 TGeoHMatrix m; AliITSgeomTGeo::GetOrigMatrix(i,j,k,m);
165 const TGeoHMatrix *tm=AliITSgeomTGeo::GetTracking2LocalMatrix(i,j,k);
167 Double_t txyz[3]={0.};
168 xyz[0]=0.;xyz[1]=0.;xyz[2]=0.;
169 m.LocalToMaster(txyz,xyz);
170 r=TMath::Sqrt(xyz[0]*xyz[0] + xyz[1]*xyz[1]);
171 Double_t phi=TMath::ATan2(xyz[1],xyz[0]);
173 if (phi<0) phi+=TMath::TwoPi();
174 else if (phi>=TMath::TwoPi()) phi-=TMath::TwoPi();
176 AliITSdetector &det=fgLayers[i-1].GetDetector((j-1)*ndet + k-1);
177 new(&det) AliITSdetector(r,phi);
178 // compute the real radius (with misalignment)
179 TGeoHMatrix mmisal(*(AliITSgeomTGeo::GetMatrix(i,j,k)));
181 xyz[0]=0.;xyz[1]=0.;xyz[2]=0.;
182 mmisal.LocalToMaster(txyz,xyz);
183 Double_t rmisal=TMath::Sqrt(xyz[0]*xyz[0] + xyz[1]*xyz[1]);
184 det.SetRmisal(rmisal);
186 } // end loop on detectors
187 } // end loop on ladders
188 fForceSkippingOfLayer[i] = 0;
189 } // end loop on layers
192 fI=AliITSgeomTGeo::GetNLayers();
195 fConstraint[0]=1; fConstraint[1]=0;
197 Double_t xyzVtx[]={AliITSReconstructor::GetRecoParam()->GetXVdef(),
198 AliITSReconstructor::GetRecoParam()->GetYVdef(),
199 AliITSReconstructor::GetRecoParam()->GetZVdef()};
200 Double_t ersVtx[]={AliITSReconstructor::GetRecoParam()->GetSigmaXVdef(),
201 AliITSReconstructor::GetRecoParam()->GetSigmaYVdef(),
202 AliITSReconstructor::GetRecoParam()->GetSigmaZVdef()};
203 SetVertex(xyzVtx,ersVtx);
205 fLastLayerToTrackTo=AliITSRecoParam::GetLastLayerToTrackTo();
206 for (Int_t i=0;i<100000;i++){
207 fBestTrackIndex[i]=0;
210 // store positions of centre of SPD modules (in z)
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];
221 fUseTGeo = AliITSReconstructor::GetRecoParam()->GetUseTGeoInTracker();
222 if(AliITSReconstructor::GetRecoParam()->GetExtendedEtaAcceptance() && fUseTGeo!=1 && fUseTGeo!=3) {
223 AliWarning("fUseTGeo changed to 3 because fExtendedEtaAcceptance is kTRUE");
227 for(Int_t i=0;i<2;i++) {fxOverX0Shield[i]=-1.;fxTimesRhoShield[i]=-1.;}
228 for(Int_t i=0;i<6;i++) {fxOverX0Layer[i]=-1.;fxTimesRhoLayer[i]=-1.;}
230 fDebugStreamer = new TTreeSRedirector("ITSdebug.root");
232 // only for plane efficiency evaluation
233 if (AliITSReconstructor::GetRecoParam()->GetComputePlaneEff() &&
234 AliITSReconstructor::GetRecoParam()->GetIPlanePlaneEff()>=0) {
235 Int_t iplane=AliITSReconstructor::GetRecoParam()->GetIPlanePlaneEff();
236 if(!AliITSReconstructor::GetRecoParam()->GetLayersToSkip(iplane)==1)
237 AliWarning(Form("Evaluation of Plane Eff for layer %d will be attempted without removing it from tracker",iplane));
238 if (iplane<2) fPlaneEff = new AliITSPlaneEffSPD();
239 else if (iplane<4) fPlaneEff = new AliITSPlaneEffSDD();
240 else fPlaneEff = new AliITSPlaneEffSSD();
241 if(AliITSReconstructor::GetRecoParam()->GetReadPlaneEffFromOCDB())
242 if(!fPlaneEff->ReadFromCDB()) {AliWarning("AliITStrackerMI reading of AliITSPlaneEff from OCDB failed") ;}
243 if(AliITSReconstructor::GetRecoParam()->GetHistoPlaneEff()) fPlaneEff->SetCreateHistos(kTRUE);
246 //------------------------------------------------------------------------
247 AliITStrackerMI::AliITStrackerMI(const AliITStrackerMI &tracker):AliTracker(tracker),
249 fBestTrack(tracker.fBestTrack),
250 fTrackToFollow(tracker.fTrackToFollow),
251 fTrackHypothesys(tracker.fTrackHypothesys),
252 fBestHypothesys(tracker.fBestHypothesys),
253 fOriginal(tracker.fOriginal),
254 fCurrentEsdTrack(tracker.fCurrentEsdTrack),
255 fPass(tracker.fPass),
256 fAfterV0(tracker.fAfterV0),
257 fLastLayerToTrackTo(tracker.fLastLayerToTrackTo),
258 fCoefficients(tracker.fCoefficients),
260 fTrackingPhase(tracker.fTrackingPhase),
261 fUseTGeo(tracker.fUseTGeo),
262 fNtracks(tracker.fNtracks),
263 fxOverX0Pipe(tracker.fxOverX0Pipe),
264 fxTimesRhoPipe(tracker.fxTimesRhoPipe),
266 fxTimesRhoPipeTrks(0),
267 fxOverX0ShieldTrks(0),
268 fxTimesRhoShieldTrks(0),
269 fxOverX0LayerTrks(0),
270 fxTimesRhoLayerTrks(0),
271 fDebugStreamer(tracker.fDebugStreamer),
272 fITSChannelStatus(tracker.fITSChannelStatus),
273 fkDetTypeRec(tracker.fkDetTypeRec),
274 fPlaneEff(tracker.fPlaneEff) {
278 fSPDdetzcentre[i]=tracker.fSPDdetzcentre[i];
281 fxOverX0Layer[i]=tracker.fxOverX0Layer[i];
282 fxTimesRhoLayer[i]=tracker.fxTimesRhoLayer[i];
285 fxOverX0Shield[i]=tracker.fxOverX0Shield[i];
286 fxTimesRhoShield[i]=tracker.fxTimesRhoShield[i];
289 //------------------------------------------------------------------------
290 AliITStrackerMI & AliITStrackerMI::operator=(const AliITStrackerMI &tracker){
291 //Assignment operator
292 this->~AliITStrackerMI();
293 new(this) AliITStrackerMI(tracker);
296 //------------------------------------------------------------------------
297 AliITStrackerMI::~AliITStrackerMI()
302 if (fCoefficients) delete [] fCoefficients;
303 DeleteTrksMaterialLUT();
304 if (fDebugStreamer) {
305 //fDebugStreamer->Close();
306 delete fDebugStreamer;
308 if(fITSChannelStatus) delete fITSChannelStatus;
309 if(fPlaneEff) delete fPlaneEff;
311 //------------------------------------------------------------------------
312 void AliITStrackerMI::ReadBadFromDetTypeRec() {
313 //--------------------------------------------------------------------
314 //This function read ITS bad detectors, chips, channels from AliITSDetTypeRec
316 //--------------------------------------------------------------------
318 if(!AliITSReconstructor::GetRecoParam()->GetUseBadZonesFromOCDB()) return;
320 Info("ReadBadFromDetTypeRec","Reading info about bad ITS detectors and channels");
322 if(!fkDetTypeRec) Error("ReadBadFromDetTypeRec","AliITSDetTypeRec nof found!\n");
325 if(fITSChannelStatus) delete fITSChannelStatus;
326 fITSChannelStatus = new AliITSChannelStatus(fkDetTypeRec);
328 // ITS detectors and chips
329 Int_t i=0,j=0,k=0,ndet=0;
330 for (i=1; i<AliITSgeomTGeo::GetNLayers()+1; i++) {
331 Int_t nBadDetsPerLayer=0;
332 ndet=AliITSgeomTGeo::GetNDetectors(i);
333 for (j=1; j<AliITSgeomTGeo::GetNLadders(i)+1; j++) {
334 for (k=1; k<ndet+1; k++) {
335 AliITSdetector &det=fgLayers[i-1].GetDetector((j-1)*ndet + k-1);
336 det.ReadBadDetectorAndChips(i-1,(j-1)*ndet + k-1,fkDetTypeRec);
337 if(det.IsBad()) {nBadDetsPerLayer++;}
338 } // end loop on detectors
339 } // end loop on ladders
340 Info("ReadBadFromDetTypeRec",Form("Layer %d: %d bad out of %d",i-1,nBadDetsPerLayer,ndet*AliITSgeomTGeo::GetNLadders(i)));
341 } // end loop on layers
345 //------------------------------------------------------------------------
346 Int_t AliITStrackerMI::LoadClusters(TTree *cTree) {
347 //--------------------------------------------------------------------
348 //This function loads ITS clusters
349 //--------------------------------------------------------------------
351 TClonesArray *clusters = NULL;
352 AliITSRecPointContainer* rpcont=AliITSRecPointContainer::Instance();
353 clusters=rpcont->FetchClusters(0,cTree);
354 if(!(rpcont->IsSPDActive() || rpcont->IsSDDActive() || rpcont->IsSSDActive())){
355 AliError("ITS is not in a known running configuration: SPD, SDD and SSD are not active");
358 Int_t i=0,j=0,ndet=0;
360 for (i=0; i<AliITSgeomTGeo::GetNLayers(); i++) {
361 ndet=fgLayers[i].GetNdetectors();
362 Int_t jmax = j + fgLayers[i].GetNladders()*ndet;
363 for (; j<jmax; j++) {
364 // if (!cTree->GetEvent(j)) continue;
365 clusters = rpcont->UncheckedGetClusters(j);
366 if(!clusters)continue;
367 Int_t ncl=clusters->GetEntriesFast();
368 SignDeltas(clusters,GetZ());
371 AliITSRecPoint *c=(AliITSRecPoint*)clusters->UncheckedAt(ncl);
372 detector=c->GetDetectorIndex();
374 if (!c->Misalign()) AliWarning("Can't misalign this cluster !");
376 Int_t retval = fgLayers[i].InsertCluster(new AliITSRecPoint(*c));
378 AliWarning(Form("Too many clusters on layer %d!",i));
383 // add dead zone "virtual" cluster in SPD, if there is a cluster within
384 // zwindow cm from the dead zone
385 if (i<2 && AliITSReconstructor::GetRecoParam()->GetAddVirtualClustersInDeadZone()) {
386 for (Float_t xdead = 0; xdead < AliITSRecoParam::GetSPDdetxlength(); xdead += (i+1.)*AliITSReconstructor::GetRecoParam()->GetXPassDeadZoneHits()) {
387 Int_t lab[4] = {0,0,0,detector};
388 Int_t info[3] = {0,0,i};
389 Float_t q = 0.; // this identifies virtual clusters
390 Float_t hit[5] = {xdead,
392 AliITSReconstructor::GetRecoParam()->GetSigmaXDeadZoneHit2(),
393 AliITSReconstructor::GetRecoParam()->GetSigmaZDeadZoneHit2(),
395 Bool_t local = kTRUE;
396 Double_t zwindow = AliITSReconstructor::GetRecoParam()->GetZWindowDeadZone();
397 hit[1] = fSPDdetzcentre[0]+0.5*AliITSRecoParam::GetSPDdetzlength();
398 if (TMath::Abs(fgLayers[i].GetDetector(detector).GetZmax()-hit[1])<zwindow)
399 fgLayers[i].InsertCluster(new AliITSRecPoint(lab,hit,info,local));
400 hit[1] = fSPDdetzcentre[1]-0.5*AliITSRecoParam::GetSPDdetzlength();
401 if (TMath::Abs(fgLayers[i].GetDetector(detector).GetZmax()-hit[1])<zwindow)
402 fgLayers[i].InsertCluster(new AliITSRecPoint(lab,hit,info,local));
403 hit[1] = fSPDdetzcentre[1]+0.5*AliITSRecoParam::GetSPDdetzlength();
404 if (TMath::Abs(fgLayers[i].GetDetector(detector).GetZmax()-hit[1])<zwindow)
405 fgLayers[i].InsertCluster(new AliITSRecPoint(lab,hit,info,local));
406 hit[1] = fSPDdetzcentre[2]-0.5*AliITSRecoParam::GetSPDdetzlength();
407 if (TMath::Abs(fgLayers[i].GetDetector(detector).GetZmax()-hit[1])<zwindow)
408 fgLayers[i].InsertCluster(new AliITSRecPoint(lab,hit,info,local));
409 hit[1] = fSPDdetzcentre[2]+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[3]-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));
416 } // "virtual" clusters in SPD
420 fgLayers[i].ResetRoad(); //road defined by the cluster density
421 fgLayers[i].SortClusters();
424 // check whether we have to skip some layers
425 SetForceSkippingOfLayer();
429 //------------------------------------------------------------------------
430 void AliITStrackerMI::UnloadClusters() {
431 //--------------------------------------------------------------------
432 //This function unloads ITS clusters
433 //--------------------------------------------------------------------
434 for (Int_t i=0; i<AliITSgeomTGeo::GetNLayers(); i++) fgLayers[i].ResetClusters();
436 //------------------------------------------------------------------------
437 void AliITStrackerMI::FillClusterArray(TObjArray* array) const {
438 //--------------------------------------------------------------------
439 // Publishes all pointers to clusters known to the tracker into the
440 // passed object array.
441 // The ownership is not transfered - the caller is not expected to delete
443 //--------------------------------------------------------------------
445 for(Int_t i=0; i<AliITSgeomTGeo::GetNLayers(); i++) {
446 for(Int_t icl=0; icl<fgLayers[i].GetNumberOfClusters(); icl++) {
447 AliCluster *cl = (AliCluster*)fgLayers[i].GetCluster(icl);
454 //------------------------------------------------------------------------
455 Int_t AliITStrackerMI::CorrectForTPCtoITSDeadZoneMaterial(AliITStrackMI *t) {
456 //--------------------------------------------------------------------
457 // Correction for the material between the TPC and the ITS
458 //--------------------------------------------------------------------
459 if (t->GetX() > AliITSRecoParam::Getriw()) { // inward direction
460 if (!t->PropagateToTGeo(AliITSRecoParam::Getriw(),1)) return 0;// TPC inner wall
461 if (!t->PropagateToTGeo(AliITSRecoParam::Getrcd(),1)) return 0;// TPC central drum
462 if (!t->PropagateToTGeo(AliITSRecoParam::Getrs(),1)) return 0;// ITS screen
463 } else if (t->GetX() < AliITSRecoParam::Getrs()) { // outward direction
464 if (!t->PropagateToTGeo(AliITSRecoParam::Getrs(),1)) return 0;// ITS screen
465 if (!t->PropagateToTGeo(AliITSRecoParam::Getrcd(),1)) return 0;// TPC central drum
466 if (!t->PropagateToTGeo(AliITSRecoParam::Getriw()+0.001,1)) return 0;// TPC inner wall
468 printf("CorrectForTPCtoITSDeadZoneMaterial: Track is already in the dead zone !\n");
474 //------------------------------------------------------------------------
475 Int_t AliITStrackerMI::Clusters2Tracks(AliESDEvent *event) {
476 //--------------------------------------------------------------------
477 // This functions reconstructs ITS tracks
478 // The clusters must be already loaded !
479 //--------------------------------------------------------------------
481 AliDebug(2,Form("SKIPPING %d %d %d %d %d %d",ForceSkippingOfLayer(0),ForceSkippingOfLayer(1),ForceSkippingOfLayer(2),ForceSkippingOfLayer(3),ForceSkippingOfLayer(4),ForceSkippingOfLayer(5)));
483 fTrackingPhase="Clusters2Tracks";
485 TObjArray itsTracks(15000);
487 fEsd = event; // store pointer to the esd
489 // temporary (for cosmics)
490 if(event->GetVertex()) {
491 TString title = event->GetVertex()->GetTitle();
492 if(title.Contains("cosmics")) {
493 Double_t xyz[3]={GetX(),GetY(),GetZ()};
494 Double_t exyz[3]={0.1,0.1,0.1};
500 {/* Read ESD tracks */
501 Double_t pimass = TDatabasePDG::Instance()->GetParticle(211)->Mass();
502 Int_t nentr=event->GetNumberOfTracks();
504 // Info("Clusters2Tracks", "Number of ESD tracks: %d\n", nentr);
506 AliESDtrack *esd=event->GetTrack(nentr);
507 // ---- for debugging:
508 //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); }
510 if ((esd->GetStatus()&AliESDtrack::kTPCin)==0) continue;
511 if (esd->GetStatus()&AliESDtrack::kTPCout) continue;
512 if (esd->GetStatus()&AliESDtrack::kITSin) continue;
513 if (esd->GetKinkIndex(0)>0) continue; //kink daughter
516 t=new AliITStrackMI(*esd);
517 } catch (const Char_t *msg) {
518 //Warning("Clusters2Tracks",msg);
522 t->GetDZ(GetX(),GetY(),GetZ(),t->GetDP()); //I.B.
523 Double_t vdist = TMath::Sqrt(t->GetD(0)*t->GetD(0)+t->GetD(1)*t->GetD(1));
526 // look at the ESD mass hypothesys !
527 if (t->GetMass()<0.9*pimass) t->SetMass(pimass);
529 t->SetExpQ(TMath::Max(0.8*t->GetESDtrack()->GetTPCsignal(),30.));
531 if (esd->GetV0Index(0)>0 && t->GetD(0)<AliITSReconstructor::GetRecoParam()->GetMaxDforV0dghtrForProlongation()){
532 //track - can be V0 according to TPC
534 if (TMath::Abs(t->GetD(0))>AliITSReconstructor::GetRecoParam()->GetMaxDForProlongation()) {
538 if (TMath::Abs(vdist)>AliITSReconstructor::GetRecoParam()->GetMaxDZForProlongation()) {
542 if (t->Pt()<AliITSReconstructor::GetRecoParam()->GetMinPtForProlongation()) {
546 if (!CorrectForTPCtoITSDeadZoneMaterial(t)) {
551 t->SetReconstructed(kFALSE);
552 itsTracks.AddLast(t);
553 fOriginal.AddLast(t);
555 } /* End Read ESD tracks */
559 Int_t nentr=itsTracks.GetEntriesFast();
560 fTrackHypothesys.Expand(nentr);
561 fBestHypothesys.Expand(nentr);
562 MakeCoefficients(nentr);
563 if(fUseTGeo==3 || fUseTGeo==4) MakeTrksMaterialLUT(event->GetNumberOfTracks());
565 // THE TWO TRACKING PASSES
566 for (fPass=0; fPass<2; fPass++) {
567 Int_t &constraint=fConstraint[fPass]; if (constraint<0) continue;
568 for (fCurrentEsdTrack=0; fCurrentEsdTrack<nentr; fCurrentEsdTrack++) {
569 AliITStrackMI *t=(AliITStrackMI*)itsTracks.UncheckedAt(fCurrentEsdTrack);
570 if (t==0) continue; //this track has been already tracked
571 //cout<<"========== "<<fPass<<" "<<fCurrentEsdTrack<<" =========\n";
572 if (t->GetReconstructed()&&(t->GetNUsed()<1.5)) continue; //this track was already "succesfully" reconstructed
573 Float_t dz[2]; t->GetDZ(GetX(),GetY(),GetZ(),dz); //I.B.
574 if (fConstraint[fPass]) {
575 if (TMath::Abs(dz[0])>AliITSReconstructor::GetRecoParam()->GetMaxDZToUseConstraint() ||
576 TMath::Abs(dz[1])>AliITSReconstructor::GetRecoParam()->GetMaxDZToUseConstraint()) continue;
579 Int_t tpcLabel=t->GetLabel(); //save the TPC track label
580 AliDebug(2,Form("LABEL %d pass %d",tpcLabel,fPass));
582 ResetTrackToFollow(*t);
585 FollowProlongationTree(t,fCurrentEsdTrack,fConstraint[fPass]);
588 SortTrackHypothesys(fCurrentEsdTrack,20,0); //MI change
590 AliITStrackMI *besttrack = GetBestHypothesys(fCurrentEsdTrack,t,15);
591 if (!besttrack) continue;
592 besttrack->SetLabel(tpcLabel);
593 // besttrack->CookdEdx();
595 besttrack->SetFakeRatio(1.);
596 CookLabel(besttrack,0.); //For comparison only
597 UpdateESDtrack(besttrack,AliESDtrack::kITSin);
599 if (fConstraint[fPass]&&(!besttrack->IsGoldPrimary())) continue; //to be tracked also without vertex constrain
601 t->SetReconstructed(kTRUE);
603 AliDebug(2,Form("TRACK! (label %d) ncls %d",besttrack->GetLabel(),besttrack->GetNumberOfClusters()));
605 GetBestHypothesysMIP(itsTracks);
606 } // end loop on the two tracking passes
608 if(event->GetNumberOfV0s()>0) AliITSV0Finder::UpdateTPCV0(event,this);
609 if(AliITSReconstructor::GetRecoParam()->GetFindV0s()) AliITSV0Finder::FindV02(event,this);
614 Int_t entries = fTrackHypothesys.GetEntriesFast();
615 for (Int_t ientry=0; ientry<entries; ientry++) {
616 TObjArray * array =(TObjArray*)fTrackHypothesys.UncheckedAt(ientry);
617 if (array) array->Delete();
618 delete fTrackHypothesys.RemoveAt(ientry);
621 fTrackHypothesys.Delete();
622 fBestHypothesys.Delete();
624 delete [] fCoefficients;
626 DeleteTrksMaterialLUT();
628 AliInfo(Form("Number of prolonged tracks: %d out of %d ESD tracks",ntrk,noesd));
630 fTrackingPhase="Default";
634 //------------------------------------------------------------------------
635 Int_t AliITStrackerMI::PropagateBack(AliESDEvent *event) {
636 //--------------------------------------------------------------------
637 // This functions propagates reconstructed ITS tracks back
638 // The clusters must be loaded !
639 //--------------------------------------------------------------------
640 fTrackingPhase="PropagateBack";
641 Int_t nentr=event->GetNumberOfTracks();
642 // Info("PropagateBack", "Number of ESD tracks: %d\n", nentr);
645 for (Int_t i=0; i<nentr; i++) {
646 AliESDtrack *esd=event->GetTrack(i);
648 if ((esd->GetStatus()&AliESDtrack::kITSin)==0) continue;
649 if (esd->GetStatus()&AliESDtrack::kITSout) continue;
653 t=new AliITStrackMI(*esd);
654 } catch (const Char_t *msg) {
655 //Warning("PropagateBack",msg);
659 t->SetExpQ(TMath::Max(0.8*t->GetESDtrack()->GetTPCsignal(),30.));
661 ResetTrackToFollow(*t);
664 // propagate to vertex [SR, GSI 17.02.2003]
665 // Start Time measurement [SR, GSI 17.02.2003], corrected by I.Belikov
666 if (CorrectForPipeMaterial(&fTrackToFollow,"inward")) {
667 if (fTrackToFollow.PropagateToVertex(event->GetVertex()))
668 fTrackToFollow.StartTimeIntegral();
669 // from vertex to outside pipe
670 CorrectForPipeMaterial(&fTrackToFollow,"outward");
672 // Start time integral and add distance from current position to vertex
673 Double_t xyzTrk[3],xyzVtx[3]={GetX(),GetY(),GetZ()};
674 fTrackToFollow.GetXYZ(xyzTrk);
676 for (Int_t icoord=0; icoord<3; icoord++) {
677 Double_t di = xyzTrk[icoord] - xyzVtx[icoord];
680 fTrackToFollow.StartTimeIntegral();
681 fTrackToFollow.AddTimeStep(TMath::Sqrt(dst2));
683 fTrackToFollow.ResetCovariance(10.); fTrackToFollow.ResetClusters();
684 if (RefitAt(AliITSRecoParam::GetrInsideITSscreen(),&fTrackToFollow,t)) {
685 if (!CorrectForTPCtoITSDeadZoneMaterial(&fTrackToFollow)) {
689 fTrackToFollow.SetLabel(t->GetLabel());
690 //fTrackToFollow.CookdEdx();
691 CookLabel(&fTrackToFollow,0.); //For comparison only
692 fTrackToFollow.UpdateESDtrack(AliESDtrack::kITSout);
693 //UseClusters(&fTrackToFollow);
699 AliInfo(Form("Number of back propagated ITS tracks: %d out of %d ESD tracks",ntrk,nentr));
701 fTrackingPhase="Default";
705 //------------------------------------------------------------------------
706 Int_t AliITStrackerMI::RefitInward(AliESDEvent *event) {
707 //--------------------------------------------------------------------
708 // This functions refits ITS tracks using the
709 // "inward propagated" TPC tracks
710 // The clusters must be loaded !
711 //--------------------------------------------------------------------
712 fTrackingPhase="RefitInward";
714 if(AliITSReconstructor::GetRecoParam()->GetFindV0s()) AliITSV0Finder::RefitV02(event,this);
716 Int_t nentr=event->GetNumberOfTracks();
717 // Info("RefitInward", "Number of ESD tracks: %d\n", nentr);
720 for (Int_t i=0; i<nentr; i++) {
721 AliESDtrack *esd=event->GetTrack(i);
723 if ((esd->GetStatus()&AliESDtrack::kITSout) == 0) continue;
724 if (esd->GetStatus()&AliESDtrack::kITSrefit) continue;
725 if (esd->GetStatus()&AliESDtrack::kTPCout)
726 if ((esd->GetStatus()&AliESDtrack::kTPCrefit)==0) continue;
730 t=new AliITStrackMI(*esd);
731 } catch (const Char_t *msg) {
732 //Warning("RefitInward",msg);
736 t->SetExpQ(TMath::Max(0.8*t->GetESDtrack()->GetTPCsignal(),30.));
737 if (!CorrectForTPCtoITSDeadZoneMaterial(t)) {
742 ResetTrackToFollow(*t);
743 fTrackToFollow.ResetClusters();
745 if ((esd->GetStatus()&AliESDtrack::kTPCin)==0)
746 fTrackToFollow.ResetCovariance(10.);
749 Bool_t pe=(AliITSReconstructor::GetRecoParam()->GetComputePlaneEff() &&
750 AliITSReconstructor::GetRecoParam()->GetIPlanePlaneEff()>=0);
752 AliDebug(2,Form("Refit LABEL %d %d",t->GetLabel(),t->GetNumberOfClusters()));
753 if (RefitAt(AliITSRecoParam::GetrInsideSPD1(),&fTrackToFollow,t,kTRUE,pe)) {
754 AliDebug(2," refit OK");
755 fTrackToFollow.SetLabel(t->GetLabel());
756 // fTrackToFollow.CookdEdx();
757 CookdEdx(&fTrackToFollow);
759 CookLabel(&fTrackToFollow,0.0); //For comparison only
762 if (CorrectForPipeMaterial(&fTrackToFollow,"inward")) {
763 fTrackToFollow.UpdateESDtrack(AliESDtrack::kITSrefit);
764 AliESDtrack *esdTrack =fTrackToFollow.GetESDtrack();
765 //printf(" %d\n",esdTrack->GetITSModuleIndex(0));
766 //esdTrack->UpdateTrackParams(&fTrackToFollow,AliESDtrack::kITSrefit); //original line
767 Double_t r[3]={0.,0.,0.};
769 esdTrack->RelateToVertex(event->GetVertex(),GetBz(r),maxD);
776 AliInfo(Form("Number of refitted tracks: %d out of %d ESD tracks",ntrk,nentr));
778 fTrackingPhase="Default";
782 //------------------------------------------------------------------------
783 AliCluster *AliITStrackerMI::GetCluster(Int_t index) const {
784 //--------------------------------------------------------------------
785 // Return pointer to a given cluster
786 //--------------------------------------------------------------------
787 Int_t l=(index & 0xf0000000) >> 28;
788 Int_t c=(index & 0x0fffffff) >> 00;
789 return fgLayers[l].GetCluster(c);
791 //------------------------------------------------------------------------
792 Bool_t AliITStrackerMI::GetTrackPoint(Int_t index, AliTrackPoint& p) const {
793 //--------------------------------------------------------------------
794 // Get track space point with index i
795 //--------------------------------------------------------------------
797 Int_t l=(index & 0xf0000000) >> 28;
798 Int_t c=(index & 0x0fffffff) >> 00;
799 AliITSRecPoint *cl = fgLayers[l].GetCluster(c);
800 Int_t idet = cl->GetDetectorIndex();
804 cl->GetGlobalXYZ(xyz);
805 cl->GetGlobalCov(cov);
807 p.SetCharge(cl->GetQ());
808 p.SetDriftTime(cl->GetDriftTime());
809 p.SetChargeRatio(cl->GetChargeRatio());
810 p.SetClusterType(cl->GetClusterType());
811 AliGeomManager::ELayerID iLayer = AliGeomManager::kInvalidLayer;
814 iLayer = AliGeomManager::kSPD1;
817 iLayer = AliGeomManager::kSPD2;
820 iLayer = AliGeomManager::kSDD1;
823 iLayer = AliGeomManager::kSDD2;
826 iLayer = AliGeomManager::kSSD1;
829 iLayer = AliGeomManager::kSSD2;
832 AliWarning(Form("Wrong layer index in ITS (%d) !",l));
835 UShort_t volid = AliGeomManager::LayerToVolUID(iLayer,idet);
836 p.SetVolumeID((UShort_t)volid);
839 //------------------------------------------------------------------------
840 Bool_t AliITStrackerMI::GetTrackPointTrackingError(Int_t index,
841 AliTrackPoint& p, const AliESDtrack *t) {
842 //--------------------------------------------------------------------
843 // Get track space point with index i
844 // (assign error estimated during the tracking)
845 //--------------------------------------------------------------------
847 Int_t l=(index & 0xf0000000) >> 28;
848 Int_t c=(index & 0x0fffffff) >> 00;
849 const AliITSRecPoint *cl = fgLayers[l].GetCluster(c);
850 Int_t idet = cl->GetDetectorIndex();
852 const AliITSdetector &det=fgLayers[l].GetDetector(idet);
854 // tgphi and tglambda of the track in tracking frame with alpha=det.GetPhi
856 detxy[0] = det.GetR()*TMath::Cos(det.GetPhi());
857 detxy[1] = det.GetR()*TMath::Sin(det.GetPhi());
858 Double_t alpha = t->GetAlpha();
859 Double_t xdetintrackframe = detxy[0]*TMath::Cos(alpha)+detxy[1]*TMath::Sin(alpha);
860 Float_t phi = TMath::ASin(t->GetSnpAt(xdetintrackframe,GetBz()));
861 phi += alpha-det.GetPhi();
862 Float_t tgphi = TMath::Tan(phi);
864 Float_t tgl = t->GetTgl(); // tgl about const along track
865 Float_t expQ = TMath::Max(0.8*t->GetTPCsignal(),30.);
867 Float_t errtrky,errtrkz,covyz;
868 Bool_t addMisalErr=kFALSE;
869 AliITSClusterParam::GetError(l,cl,tgl,tgphi,expQ,errtrky,errtrkz,covyz,addMisalErr);
873 cl->GetGlobalXYZ(xyz);
874 // cl->GetGlobalCov(cov);
875 Float_t pos[3] = {0.,0.,0.};
876 AliCluster tmpcl((UShort_t)cl->GetVolumeId(),pos[0],pos[1],pos[2],errtrky*errtrky,errtrkz*errtrkz,covyz);
877 tmpcl.GetGlobalCov(cov);
880 p.SetCharge(cl->GetQ());
881 p.SetDriftTime(cl->GetDriftTime());
882 p.SetChargeRatio(cl->GetChargeRatio());
883 p.SetClusterType(cl->GetClusterType());
885 AliGeomManager::ELayerID iLayer = AliGeomManager::kInvalidLayer;
888 iLayer = AliGeomManager::kSPD1;
891 iLayer = AliGeomManager::kSPD2;
894 iLayer = AliGeomManager::kSDD1;
897 iLayer = AliGeomManager::kSDD2;
900 iLayer = AliGeomManager::kSSD1;
903 iLayer = AliGeomManager::kSSD2;
906 AliWarning(Form("Wrong layer index in ITS (%d) !",l));
909 UShort_t volid = AliGeomManager::LayerToVolUID(iLayer,idet);
911 p.SetVolumeID((UShort_t)volid);
914 //------------------------------------------------------------------------
915 void AliITStrackerMI::FollowProlongationTree(AliITStrackMI * otrack, Int_t esdindex, Bool_t constrain)
917 //--------------------------------------------------------------------
918 // Follow prolongation tree
919 //--------------------------------------------------------------------
921 Double_t xyzVtx[]={GetX(),GetY(),GetZ()};
922 Double_t ersVtx[]={GetSigmaX(),GetSigmaY(),GetSigmaZ()};
925 AliESDtrack * esd = otrack->GetESDtrack();
926 if (esd->GetV0Index(0)>0) {
927 // TEMPORARY SOLLUTION: map V0 indexes to point to proper track
928 // mapping of ESD track is different as ITS track in Containers
929 // Need something more stable
930 // Indexes are set back again to the ESD track indexes in UpdateTPCV0
931 for (Int_t i=0;i<3;i++){
932 Int_t index = esd->GetV0Index(i);
934 AliESDv0 * vertex = fEsd->GetV0(index);
935 if (vertex->GetStatus()<0) continue; // rejected V0
937 if (esd->GetSign()>0) {
938 vertex->SetIndex(0,esdindex);
940 vertex->SetIndex(1,esdindex);
944 TObjArray *bestarray = (TObjArray*)fBestHypothesys.At(esdindex);
946 bestarray = new TObjArray(5);
947 fBestHypothesys.AddAt(bestarray,esdindex);
951 //setup tree of the prolongations
953 static AliITStrackMI tracks[7][100];
954 AliITStrackMI *currenttrack;
955 static AliITStrackMI currenttrack1;
956 static AliITStrackMI currenttrack2;
957 static AliITStrackMI backuptrack;
959 Int_t nindexes[7][100];
960 Float_t normalizedchi2[100];
961 for (Int_t ilayer=0;ilayer<6;ilayer++) ntracks[ilayer]=0;
962 otrack->SetNSkipped(0);
963 new (&(tracks[6][0])) AliITStrackMI(*otrack);
965 for (Int_t i=0;i<7;i++) nindexes[i][0]=0;
966 Int_t modstatus = 1; // found
970 // follow prolongations
971 for (Int_t ilayer=5; ilayer>=0; ilayer--) {
972 AliDebug(2,Form("FollowProlongationTree: layer %d",ilayer));
975 AliITSlayer &layer=fgLayers[ilayer];
976 Double_t r = layer.GetR();
982 for (Int_t itrack =0; itrack<ntracks[ilayer+1]; itrack++) {
984 if (ntracks[ilayer]>=100) break;
985 if (tracks[ilayer+1][nindexes[ilayer+1][itrack]].GetNSkipped()>0) nskipped++;
986 if (tracks[ilayer+1][nindexes[ilayer+1][itrack]].GetNUsed()>2.) nused++;
987 if (ntracks[ilayer]>15+ilayer){
988 if (itrack>1&&tracks[ilayer+1][nindexes[ilayer+1][itrack]].GetNSkipped()>0 && nskipped>4+ilayer) continue;
989 if (itrack>1&&tracks[ilayer+1][nindexes[ilayer+1][itrack]].GetNUsed()>2. && nused>3) continue;
992 new(¤ttrack1) AliITStrackMI(tracks[ilayer+1][nindexes[ilayer+1][itrack]]);
994 // material between SSD and SDD, SDD and SPD
996 if(!CorrectForShieldMaterial(¤ttrack1,"SDD","inward")) continue;
998 if(!CorrectForShieldMaterial(¤ttrack1,"SPD","inward")) continue;
1002 if (!currenttrack1.GetPhiZat(r,phi,z)) continue;
1003 Int_t idet=layer.FindDetectorIndex(phi,z);
1005 Double_t trackGlobXYZ1[3];
1006 if (!currenttrack1.GetXYZ(trackGlobXYZ1)) continue;
1008 // Get the budget to the primary vertex for the current track being prolonged
1009 Double_t budgetToPrimVertex = GetEffectiveThickness();
1011 // check if we allow a prolongation without point
1012 Int_t skip = CheckSkipLayer(¤ttrack1,ilayer,idet);
1014 AliITStrackMI* vtrack = new (&tracks[ilayer][ntracks[ilayer]]) AliITStrackMI(currenttrack1);
1015 // propagate to the layer radius
1016 Double_t xToGo; if (!vtrack->GetLocalXat(r,xToGo)) continue;
1017 if(!vtrack->Propagate(xToGo)) continue;
1018 // apply correction for material of the current layer
1019 CorrectForLayerMaterial(vtrack,ilayer,trackGlobXYZ1,"inward");
1020 vtrack->SetNDeadZone(vtrack->GetNDeadZone()+1);
1021 vtrack->SetDeadZoneProbability(ilayer,1.); // no penalty for missing cluster
1022 vtrack->SetClIndex(ilayer,-1);
1023 modstatus = (skip==1 ? 3 : 4); // skipped : out in z
1024 if(LocalModuleCoord(ilayer,idet,vtrack,xloc,zloc)) { // local module coords
1025 vtrack->SetModuleIndexInfo(ilayer,idet,modstatus,xloc,zloc);
1027 if(constrain) vtrack->Improve(budgetToPrimVertex,xyzVtx,ersVtx);
1032 // track outside layer acceptance in z
1033 if (idet<0) continue;
1035 //propagate to the intersection with the detector plane
1036 const AliITSdetector &det=layer.GetDetector(idet);
1037 new(¤ttrack2) AliITStrackMI(currenttrack1);
1038 if (!currenttrack1.Propagate(det.GetPhi(),det.GetR())) continue;
1039 if (!currenttrack2.Propagate(det.GetPhi(),det.GetR())) continue;
1040 currenttrack1.SetDetectorIndex(idet);
1041 currenttrack2.SetDetectorIndex(idet);
1042 if(!LocalModuleCoord(ilayer,idet,¤ttrack1,xloc,zloc)) continue; // local module coords
1045 // DEFINITION OF SEARCH ROAD AND CLUSTERS SELECTION
1047 // road in global (rphi,z) [i.e. in tracking ref. system]
1048 Double_t zmin,zmax,ymin,ymax;
1049 if (!ComputeRoad(¤ttrack1,ilayer,idet,zmin,zmax,ymin,ymax)) continue;
1051 // select clusters in road
1052 layer.SelectClusters(zmin,zmax,ymin,ymax);
1053 //********************
1055 // Define criteria for track-cluster association
1056 Double_t msz = currenttrack1.GetSigmaZ2() +
1057 AliITSReconstructor::GetRecoParam()->GetNSigmaZLayerForRoadZ()*
1058 AliITSReconstructor::GetRecoParam()->GetNSigmaZLayerForRoadZ()*
1059 AliITSReconstructor::GetRecoParam()->GetSigmaZ2(ilayer);
1060 Double_t msy = currenttrack1.GetSigmaY2() +
1061 AliITSReconstructor::GetRecoParam()->GetNSigmaYLayerForRoadY()*
1062 AliITSReconstructor::GetRecoParam()->GetNSigmaYLayerForRoadY()*
1063 AliITSReconstructor::GetRecoParam()->GetSigmaY2(ilayer);
1065 msz *= AliITSReconstructor::GetRecoParam()->GetNSigma2RoadZC();
1066 msy *= AliITSReconstructor::GetRecoParam()->GetNSigma2RoadYC();
1068 msz *= AliITSReconstructor::GetRecoParam()->GetNSigma2RoadZNonC();
1069 msy *= AliITSReconstructor::GetRecoParam()->GetNSigma2RoadYNonC();
1071 msz = 1./msz; // 1/RoadZ^2
1072 msy = 1./msy; // 1/RoadY^2
1076 // LOOP OVER ALL POSSIBLE TRACK PROLONGATIONS ON THIS LAYER
1078 const AliITSRecPoint *cl=0;
1080 Double_t chi2trkcl=AliITSReconstructor::GetRecoParam()->GetMaxChi2(); // init with big value
1081 Bool_t deadzoneSPD=kFALSE;
1082 currenttrack = ¤ttrack1;
1084 // check if the road contains a dead zone
1085 Bool_t noClusters = kFALSE;
1086 if (!layer.GetNextCluster(clidx,kTRUE)) noClusters=kTRUE;
1087 if (noClusters) AliDebug(2,"no clusters in road");
1088 Double_t dz=0.5*(zmax-zmin);
1089 Double_t dy=0.5*(ymax-ymin);
1090 Int_t dead = CheckDeadZone(¤ttrack1,ilayer,idet,dz,dy,noClusters);
1091 if(dead) AliDebug(2,Form("DEAD (%d)\n",dead));
1092 // create a prolongation without clusters (check also if there are no clusters in the road)
1095 AliITSReconstructor::GetRecoParam()->GetAllowProlongationWithEmptyRoad())) {
1096 AliITStrackMI * updatetrack = new (&tracks[ilayer][ntracks[ilayer]]) AliITStrackMI(*currenttrack);
1097 updatetrack->SetClIndex(ilayer,-1);
1099 modstatus = 5; // no cls in road
1100 } else if (dead==1) {
1101 modstatus = 7; // holes in z in SPD
1102 } else if (dead==2 || dead==3 || dead==4) {
1103 modstatus = 2; // dead from OCDB
1105 updatetrack->SetModuleIndexInfo(ilayer,idet,modstatus,xloc,zloc);
1106 // apply correction for material of the current layer
1107 CorrectForLayerMaterial(updatetrack,ilayer,trackGlobXYZ1,"inward");
1108 if (constrain) { // apply vertex constrain
1109 updatetrack->SetConstrain(constrain);
1110 Bool_t isPrim = kTRUE;
1111 if (ilayer<4) { // check that it's close to the vertex
1112 updatetrack->GetDZ(GetX(),GetY(),GetZ(),updatetrack->GetDP()); //I.B.
1113 if (TMath::Abs(updatetrack->GetD(0)/(1.+ilayer)) > // y
1114 AliITSReconstructor::GetRecoParam()->GetMaxDZforPrimTrk() ||
1115 TMath::Abs(updatetrack->GetD(1)/(1.+ilayer)) > // z
1116 AliITSReconstructor::GetRecoParam()->GetMaxDZforPrimTrk()) isPrim=kFALSE;
1118 if (isPrim) updatetrack->Improve(budgetToPrimVertex,xyzVtx,ersVtx);
1120 updatetrack->SetNDeadZone(updatetrack->GetNDeadZone()+1);
1122 if (dead==1) { // dead zone at z=0,+-7cm in SPD
1123 updatetrack->SetDeadZoneProbability(ilayer,GetSPDDeadZoneProbability(updatetrack->GetZ(),TMath::Sqrt(updatetrack->GetSigmaZ2())));
1125 } else if (dead==2 || dead==3) { // dead module or chip from OCDB
1126 updatetrack->SetDeadZoneProbability(ilayer,1.);
1127 } else if (dead==4) { // at least a single dead channel from OCDB
1128 updatetrack->SetDeadZoneProbability(ilayer,0.);
1135 // loop over clusters in the road
1136 while ((cl=layer.GetNextCluster(clidx))!=0) {
1137 if (ntracks[ilayer]>95) break; //space for skipped clusters
1138 Bool_t changedet =kFALSE;
1139 if (cl->GetQ()==0 && deadzoneSPD==kTRUE) continue;
1140 Int_t idetc=cl->GetDetectorIndex();
1142 if (currenttrack->GetDetectorIndex()==idetc) { // track already on the cluster's detector
1143 // take into account misalignment (bring track to real detector plane)
1144 Double_t xTrOrig = currenttrack->GetX();
1145 if (!currenttrack->Propagate(xTrOrig+cl->GetX())) continue;
1146 // a first cut on track-cluster distance
1147 if ( (currenttrack->GetZ()-cl->GetZ())*(currenttrack->GetZ()-cl->GetZ())*msz +
1148 (currenttrack->GetY()-cl->GetY())*(currenttrack->GetY()-cl->GetY())*msy > 1. )
1149 { // cluster not associated to track
1150 AliDebug(2,"not associated");
1153 // bring track back to ideal detector plane
1154 if (!currenttrack->Propagate(xTrOrig)) continue;
1155 } else { // have to move track to cluster's detector
1156 const AliITSdetector &detc=layer.GetDetector(idetc);
1157 // a first cut on track-cluster distance
1159 if (!currenttrack2.GetProlongationFast(detc.GetPhi(),detc.GetR()+cl->GetX(),y,z)) continue;
1160 if ( (z-cl->GetZ())*(z-cl->GetZ())*msz +
1161 (y-cl->GetY())*(y-cl->GetY())*msy > 1. )
1162 continue; // cluster not associated to track
1164 new (&backuptrack) AliITStrackMI(currenttrack2);
1166 currenttrack =¤ttrack2;
1167 if (!currenttrack->Propagate(detc.GetPhi(),detc.GetR())) {
1168 new (currenttrack) AliITStrackMI(backuptrack);
1172 currenttrack->SetDetectorIndex(idetc);
1173 // Get again the budget to the primary vertex
1174 // for the current track being prolonged, if had to change detector
1175 //budgetToPrimVertex = GetEffectiveThickness();// not needed at the moment because anyway we take a mean material for this correction
1178 // calculate track-clusters chi2
1179 chi2trkcl = GetPredictedChi2MI(currenttrack,cl,ilayer);
1181 AliDebug(2,Form("chi2 %f max %f",chi2trkcl,AliITSReconstructor::GetRecoParam()->GetMaxChi2s(ilayer)));
1182 if (chi2trkcl < AliITSReconstructor::GetRecoParam()->GetMaxChi2s(ilayer)) {
1183 if (cl->GetQ()==0) deadzoneSPD=kTRUE; // only 1 prolongation with virtual cluster
1184 if (ntracks[ilayer]>=100) continue;
1185 AliITStrackMI * updatetrack = new (&tracks[ilayer][ntracks[ilayer]]) AliITStrackMI(*currenttrack);
1186 updatetrack->SetClIndex(ilayer,-1);
1187 if (changedet) new (¤ttrack2) AliITStrackMI(backuptrack);
1189 if (cl->GetQ()!=0) { // real cluster
1190 if (!UpdateMI(updatetrack,cl,chi2trkcl,(ilayer<<28)+clidx)) {
1191 AliDebug(2,"update failed");
1194 updatetrack->SetSampledEdx(cl->GetQ(),ilayer-2);
1195 modstatus = 1; // found
1196 } else { // virtual cluster in dead zone
1197 updatetrack->SetNDeadZone(updatetrack->GetNDeadZone()+1);
1198 updatetrack->SetDeadZoneProbability(ilayer,GetSPDDeadZoneProbability(updatetrack->GetZ(),TMath::Sqrt(updatetrack->GetSigmaZ2())));
1199 modstatus = 7; // holes in z in SPD
1203 Float_t xlocnewdet,zlocnewdet;
1204 if(LocalModuleCoord(ilayer,idet,updatetrack,xlocnewdet,zlocnewdet)) { // local module coords
1205 updatetrack->SetModuleIndexInfo(ilayer,idet,modstatus,xlocnewdet,zlocnewdet);
1208 updatetrack->SetModuleIndexInfo(ilayer,idet,modstatus,xloc,zloc);
1210 if (cl->IsUsed()) updatetrack->IncrementNUsed();
1212 // apply correction for material of the current layer
1213 CorrectForLayerMaterial(updatetrack,ilayer,trackGlobXYZ1,"inward");
1215 if (constrain) { // apply vertex constrain
1216 updatetrack->SetConstrain(constrain);
1217 Bool_t isPrim = kTRUE;
1218 if (ilayer<4) { // check that it's close to the vertex
1219 updatetrack->GetDZ(GetX(),GetY(),GetZ(),updatetrack->GetDP()); //I.B.
1220 if (TMath::Abs(updatetrack->GetD(0)/(1.+ilayer)) > // y
1221 AliITSReconstructor::GetRecoParam()->GetMaxDZforPrimTrk() ||
1222 TMath::Abs(updatetrack->GetD(1)/(1.+ilayer)) > // z
1223 AliITSReconstructor::GetRecoParam()->GetMaxDZforPrimTrk()) isPrim=kFALSE;
1225 if (isPrim) updatetrack->Improve(budgetToPrimVertex,xyzVtx,ersVtx);
1226 } //apply vertex constrain
1228 } // create new hypothesis
1230 AliDebug(2,"chi2 too large");
1233 } // loop over possible prolongations
1235 // allow one prolongation without clusters
1236 if (constrain && itrack<=1 && currenttrack1.GetNSkipped()==0 && deadzoneSPD==kFALSE && ntracks[ilayer]<100) {
1237 AliITStrackMI* vtrack = new (&tracks[ilayer][ntracks[ilayer]]) AliITStrackMI(currenttrack1);
1238 // apply correction for material of the current layer
1239 CorrectForLayerMaterial(vtrack,ilayer,trackGlobXYZ1,"inward");
1240 vtrack->SetClIndex(ilayer,-1);
1241 modstatus = 3; // skipped
1242 vtrack->SetModuleIndexInfo(ilayer,idet,modstatus,xloc,zloc);
1243 vtrack->Improve(budgetToPrimVertex,xyzVtx,ersVtx);
1244 vtrack->IncrementNSkipped();
1249 } // loop over tracks in layer ilayer+1
1251 //loop over track candidates for the current layer
1257 for (Int_t itrack=0;itrack<ntracks[ilayer];itrack++){
1258 normalizedchi2[itrack] = NormalizedChi2(&tracks[ilayer][itrack],ilayer);
1259 if (normalizedchi2[itrack] <
1260 AliITSReconstructor::GetRecoParam()->GetMaxNormChi2ForGolden(ilayer)) golden++;
1264 if (constrain) { // constrain
1265 if (normalizedchi2[itrack]<AliITSReconstructor::GetRecoParam()->GetMaxNormChi2C(ilayer)+1)
1267 } else { // !constrain
1268 if (normalizedchi2[itrack]<AliITSReconstructor::GetRecoParam()->GetMaxNormChi2NonC(ilayer)+1)
1273 // sort tracks by increasing normalized chi2
1274 TMath::Sort(ntracks[ilayer],normalizedchi2,nindexes[ilayer],kFALSE);
1275 ntracks[ilayer] = TMath::Min(accepted,7+2*ilayer);
1276 if (ntracks[ilayer]<golden+2+ilayer) ntracks[ilayer]=TMath::Min(golden+2+ilayer,accepted);
1277 if (ntracks[ilayer]>90) ntracks[ilayer]=90;
1278 } // end loop over layers
1282 // Now select tracks to be kept
1284 Int_t max = constrain ? 20 : 5;
1286 // tracks that reach layer 0 (SPD inner)
1287 for (Int_t i=0; i<TMath::Min(max,ntracks[0]); i++) {
1288 AliITStrackMI & track= tracks[0][nindexes[0][i]];
1289 if (track.GetNumberOfClusters()<2) continue;
1290 if (!constrain && track.GetNormChi2(0) >
1291 AliITSReconstructor::GetRecoParam()->GetMaxNormChi2NonCForHypothesis()) {
1294 AddTrackHypothesys(new AliITStrackMI(track), esdindex);
1297 // tracks that reach layer 1 (SPD outer)
1298 for (Int_t i=0;i<TMath::Min(2,ntracks[1]);i++) {
1299 AliITStrackMI & track= tracks[1][nindexes[1][i]];
1300 if (track.GetNumberOfClusters()<4) continue;
1301 if (!constrain && track.GetNormChi2(1) >
1302 AliITSReconstructor::GetRecoParam()->GetMaxNormChi2NonCForHypothesis()) continue;
1303 if (constrain) track.IncrementNSkipped();
1305 track.SetD(0,track.GetD(GetX(),GetY()));
1306 track.SetNSkipped(track.GetNSkipped()+4./(4.+8.*TMath::Abs(track.GetD(0))));
1307 if (track.GetNumberOfClusters()+track.GetNDeadZone()+track.GetNSkipped()>6) {
1308 track.SetNSkipped(6-track.GetNumberOfClusters()+track.GetNDeadZone());
1311 AddTrackHypothesys(new AliITStrackMI(track), esdindex);
1314 // tracks that reach layer 2 (SDD inner), only during non-constrained pass
1316 for (Int_t i=0;i<TMath::Min(2,ntracks[2]);i++) {
1317 AliITStrackMI & track= tracks[2][nindexes[2][i]];
1318 if (track.GetNumberOfClusters()<3) continue;
1319 if (!constrain && track.GetNormChi2(2) >
1320 AliITSReconstructor::GetRecoParam()->GetMaxNormChi2NonCForHypothesis()) continue;
1321 if (constrain) track.SetNSkipped(track.GetNSkipped()+2);
1323 track.SetD(0,track.GetD(GetX(),GetY()));
1324 track.SetNSkipped(track.GetNSkipped()+7./(7.+8.*TMath::Abs(track.GetD(0))));
1325 if (track.GetNumberOfClusters()+track.GetNDeadZone()+track.GetNSkipped()>6) {
1326 track.SetNSkipped(6-track.GetNumberOfClusters()+track.GetNDeadZone());
1329 AddTrackHypothesys(new AliITStrackMI(track), esdindex);
1335 // register best track of each layer - important for V0 finder
1337 for (Int_t ilayer=0;ilayer<5;ilayer++){
1338 if (ntracks[ilayer]==0) continue;
1339 AliITStrackMI & track= tracks[ilayer][nindexes[ilayer][0]];
1340 if (track.GetNumberOfClusters()<1) continue;
1341 CookLabel(&track,0);
1342 bestarray->AddAt(new AliITStrackMI(track),ilayer);
1346 // update TPC V0 information
1348 if (otrack->GetESDtrack()->GetV0Index(0)>0){
1349 Float_t fprimvertex[3]={GetX(),GetY(),GetZ()};
1350 for (Int_t i=0;i<3;i++){
1351 Int_t index = otrack->GetESDtrack()->GetV0Index(i);
1352 if (index==0) break;
1353 AliV0 *vertex = (AliV0*)fEsd->GetV0(index);
1354 if (vertex->GetStatus()<0) continue; // rejected V0
1356 if (otrack->GetSign()>0) {
1357 vertex->SetIndex(0,esdindex);
1360 vertex->SetIndex(1,esdindex);
1362 //find nearest layer with track info
1363 Double_t xrp[3]; vertex->GetXYZ(xrp[0],xrp[1],xrp[2]); //I.B.
1364 Int_t nearestold = GetNearestLayer(xrp); //I.B.
1365 Int_t nearest = nearestold;
1366 for (Int_t ilayer =nearest;ilayer<8;ilayer++){
1367 if (ntracks[nearest]==0){
1372 AliITStrackMI & track= tracks[nearest][nindexes[nearest][0]];
1373 if (nearestold<5&&nearest<5){
1374 Bool_t accept = track.GetNormChi2(nearest)<10;
1376 if (track.GetSign()>0) {
1377 vertex->SetParamP(track);
1378 vertex->Update(fprimvertex);
1379 //vertex->SetIndex(0,track.fESDtrack->GetID());
1380 if (track.GetNumberOfClusters()>2) AddTrackHypothesys(new AliITStrackMI(track), esdindex);
1382 vertex->SetParamN(track);
1383 vertex->Update(fprimvertex);
1384 //vertex->SetIndex(1,track.fESDtrack->GetID());
1385 if (track.GetNumberOfClusters()>2) AddTrackHypothesys(new AliITStrackMI(track), esdindex);
1387 vertex->SetStatus(vertex->GetStatus()+1);
1389 //vertex->SetStatus(-2); // reject V0 - not enough clusters
1396 //------------------------------------------------------------------------
1397 AliITStrackerMI::AliITSlayer & AliITStrackerMI::GetLayer(Int_t layer) const
1399 //--------------------------------------------------------------------
1402 return fgLayers[layer];
1404 //------------------------------------------------------------------------
1405 AliITStrackerMI::AliITSlayer::AliITSlayer():
1435 //--------------------------------------------------------------------
1436 //default AliITSlayer constructor
1437 //--------------------------------------------------------------------
1438 for (Int_t i=0; i<AliITSRecoParam::GetMaxClusterPerLayer(); i++) {
1439 fClusterWeight[i]=0;
1440 fClusterTracks[0][i]=-1;
1441 fClusterTracks[1][i]=-1;
1442 fClusterTracks[2][i]=-1;
1443 fClusterTracks[3][i]=-1;
1446 //------------------------------------------------------------------------
1447 AliITStrackerMI::AliITSlayer::
1448 AliITSlayer(Double_t r,Double_t p,Double_t z,Int_t nl,Int_t nd):
1477 //--------------------------------------------------------------------
1478 //main AliITSlayer constructor
1479 //--------------------------------------------------------------------
1480 fDetectors=new AliITSdetector[fNladders*fNdetectors];
1481 fRoad=2*fR*TMath::Sqrt(TMath::Pi()/1.);//assuming that there's only one cluster
1483 //------------------------------------------------------------------------
1484 AliITStrackerMI::AliITSlayer::AliITSlayer(const AliITSlayer& layer):
1486 fPhiOffset(layer.fPhiOffset),
1487 fNladders(layer.fNladders),
1488 fZOffset(layer.fZOffset),
1489 fNdetectors(layer.fNdetectors),
1490 fDetectors(layer.fDetectors),
1495 fClustersCs(layer.fClustersCs),
1496 fClusterIndexCs(layer.fClusterIndexCs),
1500 fCurrentSlice(layer.fCurrentSlice),
1508 fAccepted(layer.fAccepted),
1510 fMaxSigmaClY(layer.fMaxSigmaClY),
1511 fMaxSigmaClZ(layer.fMaxSigmaClZ),
1512 fNMaxSigmaCl(layer.fNMaxSigmaCl)
1516 //------------------------------------------------------------------------
1517 AliITStrackerMI::AliITSlayer::~AliITSlayer() {
1518 //--------------------------------------------------------------------
1519 // AliITSlayer destructor
1520 //--------------------------------------------------------------------
1521 delete [] fDetectors;
1522 for (Int_t i=0; i<fN; i++) delete fClusters[i];
1523 for (Int_t i=0; i<AliITSRecoParam::GetMaxClusterPerLayer(); i++) {
1524 fClusterWeight[i]=0;
1525 fClusterTracks[0][i]=-1;
1526 fClusterTracks[1][i]=-1;
1527 fClusterTracks[2][i]=-1;
1528 fClusterTracks[3][i]=-1;
1531 //------------------------------------------------------------------------
1532 void AliITStrackerMI::AliITSlayer::ResetClusters() {
1533 //--------------------------------------------------------------------
1534 // This function removes loaded clusters
1535 //--------------------------------------------------------------------
1536 for (Int_t i=0; i<fN; i++) delete fClusters[i];
1537 for (Int_t i=0; i<AliITSRecoParam::GetMaxClusterPerLayer(); i++){
1538 fClusterWeight[i]=0;
1539 fClusterTracks[0][i]=-1;
1540 fClusterTracks[1][i]=-1;
1541 fClusterTracks[2][i]=-1;
1542 fClusterTracks[3][i]=-1;
1548 //------------------------------------------------------------------------
1549 void AliITStrackerMI::AliITSlayer::ResetWeights() {
1550 //--------------------------------------------------------------------
1551 // This function reset weights of the clusters
1552 //--------------------------------------------------------------------
1553 for (Int_t i=0; i<AliITSRecoParam::GetMaxClusterPerLayer(); i++) {
1554 fClusterWeight[i]=0;
1555 fClusterTracks[0][i]=-1;
1556 fClusterTracks[1][i]=-1;
1557 fClusterTracks[2][i]=-1;
1558 fClusterTracks[3][i]=-1;
1560 for (Int_t i=0; i<fN;i++) {
1561 AliITSRecPoint * cl = (AliITSRecPoint*)GetCluster(i);
1562 if (cl&&cl->IsUsed()) cl->Use();
1566 //------------------------------------------------------------------------
1567 void AliITStrackerMI::AliITSlayer::ResetRoad() {
1568 //--------------------------------------------------------------------
1569 // This function calculates the road defined by the cluster density
1570 //--------------------------------------------------------------------
1572 for (Int_t i=0; i<fN; i++) {
1573 if (TMath::Abs(fClusters[i]->GetZ())<fR) n++;
1575 if (n>1) fRoad=2*fR*TMath::Sqrt(TMath::Pi()/n);
1577 //------------------------------------------------------------------------
1578 Int_t AliITStrackerMI::AliITSlayer::InsertCluster(AliITSRecPoint *cl) {
1579 //--------------------------------------------------------------------
1580 //This function adds a cluster to this layer
1581 //--------------------------------------------------------------------
1582 if (fN==AliITSRecoParam::GetMaxClusterPerLayer()) {
1588 AliITSdetector &det=GetDetector(cl->GetDetectorIndex());
1590 Double_t nSigmaY=fNMaxSigmaCl*TMath::Sqrt(cl->GetSigmaY2());
1591 Double_t nSigmaZ=fNMaxSigmaCl*TMath::Sqrt(cl->GetSigmaZ2());
1592 if (cl->GetY()-nSigmaY<det.GetYmin()) det.SetYmin(cl->GetY()-nSigmaY);
1593 if (cl->GetY()+nSigmaY>det.GetYmax()) det.SetYmax(cl->GetY()+nSigmaY);
1594 if (cl->GetZ()-nSigmaZ<det.GetZmin()) det.SetZmin(cl->GetZ()-nSigmaZ);
1595 if (cl->GetZ()+nSigmaZ>det.GetZmax()) det.SetZmax(cl->GetZ()+nSigmaZ);
1598 if (cl->GetY()<det.GetYmin()) det.SetYmin(cl->GetY());
1599 if (cl->GetY()>det.GetYmax()) det.SetYmax(cl->GetY());
1600 if (cl->GetZ()<det.GetZmin()) det.SetZmin(cl->GetZ());
1601 if (cl->GetZ()>det.GetZmax()) det.SetZmax(cl->GetZ());
1605 //------------------------------------------------------------------------
1606 void AliITStrackerMI::AliITSlayer::SortClusters()
1611 AliITSRecPoint **clusters = new AliITSRecPoint*[fN];
1612 Float_t *z = new Float_t[fN];
1613 Int_t * index = new Int_t[fN];
1615 fMaxSigmaClY=0.; //AD
1616 fMaxSigmaClZ=0.; //AD
1618 for (Int_t i=0;i<fN;i++){
1619 z[i] = fClusters[i]->GetZ();
1620 // save largest errors in y and z for this layer
1621 fMaxSigmaClY=TMath::Max(fMaxSigmaClY,TMath::Sqrt(fClusters[i]->GetSigmaY2()));
1622 fMaxSigmaClZ=TMath::Max(fMaxSigmaClZ,TMath::Sqrt(fClusters[i]->GetSigmaZ2()));
1624 TMath::Sort(fN,z,index,kFALSE);
1625 for (Int_t i=0;i<fN;i++){
1626 clusters[i] = fClusters[index[i]];
1629 for (Int_t i=0;i<fN;i++){
1630 fClusters[i] = clusters[i];
1631 fZ[i] = fClusters[i]->GetZ();
1632 AliITSdetector &det=GetDetector(fClusters[i]->GetDetectorIndex());
1633 Double_t y=fR*det.GetPhi() + fClusters[i]->GetY();
1634 if (y>2.*fR*TMath::Pi()) y -= 2.*fR*TMath::Pi();
1644 for (Int_t i=0;i<fN;i++){
1645 if (fY[i]<fYB[0]) fYB[0]=fY[i];
1646 if (fY[i]>fYB[1]) fYB[1]=fY[i];
1647 fClusterIndex[i] = i;
1651 fDy5 = (fYB[1]-fYB[0])/5.;
1652 fDy10 = (fYB[1]-fYB[0])/10.;
1653 fDy20 = (fYB[1]-fYB[0])/20.;
1654 for (Int_t i=0;i<6;i++) fN5[i] =0;
1655 for (Int_t i=0;i<11;i++) fN10[i]=0;
1656 for (Int_t i=0;i<21;i++) fN20[i]=0;
1658 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;}
1659 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;}
1660 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;}
1663 for (Int_t i=0;i<fN;i++)
1664 for (Int_t irot=-1;irot<=1;irot++){
1665 Float_t curY = fY[i]+irot*TMath::TwoPi()*fR;
1667 for (Int_t slice=0; slice<6;slice++){
1668 if (fBy5[slice][0]<curY && curY<fBy5[slice][1]&&fN5[slice]<AliITSRecoParam::GetMaxClusterPerLayer5()){
1669 fClusters5[slice][fN5[slice]] = fClusters[i];
1670 fY5[slice][fN5[slice]] = curY;
1671 fZ5[slice][fN5[slice]] = fZ[i];
1672 fClusterIndex5[slice][fN5[slice]]=i;
1677 for (Int_t slice=0; slice<11;slice++){
1678 if (fBy10[slice][0]<curY && curY<fBy10[slice][1]&&fN10[slice]<AliITSRecoParam::GetMaxClusterPerLayer10()){
1679 fClusters10[slice][fN10[slice]] = fClusters[i];
1680 fY10[slice][fN10[slice]] = curY;
1681 fZ10[slice][fN10[slice]] = fZ[i];
1682 fClusterIndex10[slice][fN10[slice]]=i;
1687 for (Int_t slice=0; slice<21;slice++){
1688 if (fBy20[slice][0]<curY && curY<fBy20[slice][1]&&fN20[slice]<AliITSRecoParam::GetMaxClusterPerLayer20()){
1689 fClusters20[slice][fN20[slice]] = fClusters[i];
1690 fY20[slice][fN20[slice]] = curY;
1691 fZ20[slice][fN20[slice]] = fZ[i];
1692 fClusterIndex20[slice][fN20[slice]]=i;
1699 // consistency check
1701 for (Int_t i=0;i<fN-1;i++){
1707 for (Int_t slice=0;slice<21;slice++)
1708 for (Int_t i=0;i<fN20[slice]-1;i++){
1709 if (fZ20[slice][i]>fZ20[slice][i+1]){
1716 //------------------------------------------------------------------------
1717 Int_t AliITStrackerMI::AliITSlayer::FindClusterIndex(Float_t z) const {
1718 //--------------------------------------------------------------------
1719 // This function returns the index of the nearest cluster
1720 //--------------------------------------------------------------------
1723 if (fCurrentSlice<0) {
1732 if (ncl==0) return 0;
1733 Int_t b=0, e=ncl-1, m=(b+e)/2;
1734 for (; b<e; m=(b+e)/2) {
1735 // if (z > fClusters[m]->GetZ()) b=m+1;
1736 if (z > zcl[m]) b=m+1;
1741 //------------------------------------------------------------------------
1742 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 {
1743 //--------------------------------------------------------------------
1744 // This function computes the rectangular road for this track
1745 //--------------------------------------------------------------------
1748 AliITSdetector &det = fgLayers[ilayer].GetDetector(idet);
1749 // take into account the misalignment: propagate track to misaligned detector plane
1750 if (!track->Propagate(det.GetPhi(),det.GetRmisal())) return kFALSE;
1752 Double_t dz=AliITSReconstructor::GetRecoParam()->GetNSigmaRoadZ()*
1753 TMath::Sqrt(track->GetSigmaZ2() +
1754 AliITSReconstructor::GetRecoParam()->GetNSigmaZLayerForRoadZ()*
1755 AliITSReconstructor::GetRecoParam()->GetNSigmaZLayerForRoadZ()*
1756 AliITSReconstructor::GetRecoParam()->GetSigmaZ2(ilayer));
1757 Double_t dy=AliITSReconstructor::GetRecoParam()->GetNSigmaRoadY()*
1758 TMath::Sqrt(track->GetSigmaY2() +
1759 AliITSReconstructor::GetRecoParam()->GetNSigmaYLayerForRoadY()*
1760 AliITSReconstructor::GetRecoParam()->GetNSigmaYLayerForRoadY()*
1761 AliITSReconstructor::GetRecoParam()->GetSigmaY2(ilayer));
1763 // track at boundary between detectors, enlarge road
1764 Double_t boundaryWidth=AliITSRecoParam::GetBoundaryWidth();
1765 if ( (track->GetY()-dy < det.GetYmin()+boundaryWidth) ||
1766 (track->GetY()+dy > det.GetYmax()-boundaryWidth) ||
1767 (track->GetZ()-dz < det.GetZmin()+boundaryWidth) ||
1768 (track->GetZ()+dz > det.GetZmax()-boundaryWidth) ) {
1769 Float_t tgl = TMath::Abs(track->GetTgl());
1770 if (tgl > 1.) tgl=1.;
1771 Double_t deltaXNeighbDets=AliITSRecoParam::GetDeltaXNeighbDets();
1772 dz = TMath::Sqrt(dz*dz+deltaXNeighbDets*deltaXNeighbDets*tgl*tgl);
1773 Float_t snp = TMath::Abs(track->GetSnp());
1774 if (snp > AliITSReconstructor::GetRecoParam()->GetMaxSnp()) return kFALSE;
1775 dy = TMath::Sqrt(dy*dy+deltaXNeighbDets*deltaXNeighbDets*snp*snp);
1778 // add to the road a term (up to 2-3 mm) to deal with misalignments
1779 dy = TMath::Sqrt(dy*dy + AliITSReconstructor::GetRecoParam()->GetRoadMisal()*AliITSReconstructor::GetRecoParam()->GetRoadMisal());
1780 dz = TMath::Sqrt(dz*dz + AliITSReconstructor::GetRecoParam()->GetRoadMisal()*AliITSReconstructor::GetRecoParam()->GetRoadMisal());
1782 Double_t r = fgLayers[ilayer].GetR();
1783 zmin = track->GetZ() - dz;
1784 zmax = track->GetZ() + dz;
1785 ymin = track->GetY() + r*det.GetPhi() - dy;
1786 ymax = track->GetY() + r*det.GetPhi() + dy;
1788 // bring track back to idead detector plane
1789 if (!track->Propagate(det.GetPhi(),det.GetR())) return kFALSE;
1793 //------------------------------------------------------------------------
1794 void AliITStrackerMI::AliITSlayer::
1795 SelectClusters(Double_t zmin,Double_t zmax,Double_t ymin, Double_t ymax) {
1796 //--------------------------------------------------------------------
1797 // This function sets the "window"
1798 //--------------------------------------------------------------------
1800 Double_t circle=2*TMath::Pi()*fR;
1806 // enlarge road in y by maximum cluster error on this layer (3 sigma)
1807 fYmin -= fNMaxSigmaCl*fMaxSigmaClY;
1808 fYmax += fNMaxSigmaCl*fMaxSigmaClY;
1809 fZmin -= fNMaxSigmaCl*fMaxSigmaClZ;
1810 fZmax += fNMaxSigmaCl*fMaxSigmaClZ;
1812 Float_t ymiddle = (fYmin+fYmax)*0.5;
1813 if (ymiddle<fYB[0]) {
1814 fYmin+=circle; fYmax+=circle; ymiddle+=circle;
1815 } else if (ymiddle>fYB[1]) {
1816 fYmin-=circle; fYmax-=circle; ymiddle-=circle;
1822 fClustersCs = fClusters;
1823 fClusterIndexCs = fClusterIndex;
1829 if (fCurrentSlice<0&&TMath::Abs(fYmax-fYmin)<1.49*fDy20){
1830 Int_t slice = int(0.5+(ymiddle-fYB[0])/fDy20);
1831 if (slice<0) slice=0;
1832 if (slice>20) slice=20;
1833 Bool_t isOK = (fYmin>fBy20[slice][0]&&fYmax<fBy20[slice][1]);
1835 fCurrentSlice=slice;
1836 fClustersCs = fClusters20[fCurrentSlice];
1837 fClusterIndexCs = fClusterIndex20[fCurrentSlice];
1838 fYcs = fY20[fCurrentSlice];
1839 fZcs = fZ20[fCurrentSlice];
1840 fNcs = fN20[fCurrentSlice];
1845 if (fCurrentSlice<0&&TMath::Abs(fYmax-fYmin)<1.49*fDy10){
1846 Int_t slice = int(0.5+(ymiddle-fYB[0])/fDy10);
1847 if (slice<0) slice=0;
1848 if (slice>10) slice=10;
1849 Bool_t isOK = (fYmin>fBy10[slice][0]&&fYmax<fBy10[slice][1]);
1851 fCurrentSlice=slice;
1852 fClustersCs = fClusters10[fCurrentSlice];
1853 fClusterIndexCs = fClusterIndex10[fCurrentSlice];
1854 fYcs = fY10[fCurrentSlice];
1855 fZcs = fZ10[fCurrentSlice];
1856 fNcs = fN10[fCurrentSlice];
1861 if (fCurrentSlice<0&&TMath::Abs(fYmax-fYmin)<1.49*fDy5){
1862 Int_t slice = int(0.5+(ymiddle-fYB[0])/fDy5);
1863 if (slice<0) slice=0;
1864 if (slice>5) slice=5;
1865 Bool_t isOK = (fYmin>fBy5[slice][0]&&fYmax<fBy5[slice][1]);
1867 fCurrentSlice=slice;
1868 fClustersCs = fClusters5[fCurrentSlice];
1869 fClusterIndexCs = fClusterIndex5[fCurrentSlice];
1870 fYcs = fY5[fCurrentSlice];
1871 fZcs = fZ5[fCurrentSlice];
1872 fNcs = fN5[fCurrentSlice];
1876 fI = FindClusterIndex(fZmin);
1877 fImax = TMath::Min(FindClusterIndex(fZmax)+1,fNcs);
1883 //------------------------------------------------------------------------
1884 Int_t AliITStrackerMI::AliITSlayer::
1885 FindDetectorIndex(Double_t phi, Double_t z) const {
1886 //--------------------------------------------------------------------
1887 //This function finds the detector crossed by the track
1888 //--------------------------------------------------------------------
1890 if (fZOffset<0) // old geometry
1891 dphi = -(phi-fPhiOffset);
1892 else // new geometry
1893 dphi = phi-fPhiOffset;
1896 if (dphi < 0) dphi += 2*TMath::Pi();
1897 else if (dphi >= 2*TMath::Pi()) dphi -= 2*TMath::Pi();
1898 Int_t np=Int_t(dphi*fNladders*0.5/TMath::Pi()+0.5);
1899 if (np>=fNladders) np-=fNladders;
1900 if (np<0) np+=fNladders;
1903 Double_t dz=fZOffset-z;
1904 Double_t nnz = dz*(fNdetectors-1)*0.5/fZOffset+0.5;
1905 Int_t nz = (nnz<0 ? -1 : (Int_t)nnz);
1906 if (nz>=fNdetectors) return -1;
1907 if (nz<0) return -1;
1909 // ad hoc correction for 3rd ladder of SDD inner layer,
1910 // which is reversed (rotated by pi around local y)
1911 // this correction is OK only from AliITSv11Hybrid onwards
1912 if (GetR()>12. && GetR()<20.) { // SDD inner
1913 if(np==2) { // 3rd ladder
1914 nz = (fNdetectors-1) - nz;
1917 //printf("ndet %d phi %f z %f np %d nz %d\n",fNdetectors,phi,z,np,nz);
1920 return np*fNdetectors + nz;
1922 //------------------------------------------------------------------------
1923 const AliITSRecPoint *AliITStrackerMI::AliITSlayer::GetNextCluster(Int_t &ci,Bool_t test)
1925 //--------------------------------------------------------------------
1926 // This function returns clusters within the "window"
1927 //--------------------------------------------------------------------
1929 if (fCurrentSlice<0) {
1930 Double_t rpi2 = 2.*fR*TMath::Pi();
1931 for (Int_t i=fI; i<fImax; i++) {
1934 if (fYmax<y) y -= rpi2;
1935 if (fYmin>y) y += rpi2;
1936 if (y<fYmin) continue;
1937 if (y>fYmax) continue;
1939 // skip clusters that are in "extended" road but they
1940 // 3sigma error does not touch the original road
1941 if (z+fNMaxSigmaCl*TMath::Sqrt(fClusters[i]->GetSigmaZ2())<fZmin+fNMaxSigmaCl*fMaxSigmaClZ) continue;
1942 if (z-fNMaxSigmaCl*TMath::Sqrt(fClusters[i]->GetSigmaZ2())>fZmax-fNMaxSigmaCl*fMaxSigmaClZ) continue;
1944 if (fClusters[i]->GetQ()==0&&fSkip==2) continue;
1947 return fClusters[i];
1950 for (Int_t i=fI; i<fImax; i++) {
1951 if (fYcs[i]<fYmin) continue;
1952 if (fYcs[i]>fYmax) continue;
1953 if (fClustersCs[i]->GetQ()==0&&fSkip==2) continue;
1954 ci=fClusterIndexCs[i];
1956 return fClustersCs[i];
1961 //------------------------------------------------------------------------
1962 Double_t AliITStrackerMI::AliITSlayer::GetThickness(Double_t y,Double_t z,Double_t &x0)
1964 //--------------------------------------------------------------------
1965 // This function returns the layer thickness at this point (units X0)
1966 //--------------------------------------------------------------------
1968 x0=AliITSRecoParam::GetX0Air();
1969 if (43<fR&&fR<45) { //SSD2
1972 if (TMath::Abs(y-0.00)>3.40) d+=dd;
1973 if (TMath::Abs(y-1.90)<0.45) {d+=(0.013-0.0034);}
1974 if (TMath::Abs(y+1.90)<0.45) {d+=(0.013-0.0034);}
1975 for (Int_t i=0; i<12; i++) {
1976 if (TMath::Abs(z-3.9*(i+0.5))<0.15) {
1977 if (TMath::Abs(y-0.00)>3.40) d+=dd;
1981 if (TMath::Abs(z+3.9*(i+0.5))<0.15) {
1982 if (TMath::Abs(y-0.00)>3.40) d+=dd;
1986 if (TMath::Abs(z-3.4-3.9*i)<0.50) {d+=(0.016-0.0034); break;}
1987 if (TMath::Abs(z+0.5+3.9*i)<0.50) {d+=(0.016-0.0034); break;}
1990 if (37<fR&&fR<41) { //SSD1
1993 if (TMath::Abs(y-0.00)>3.40) d+=dd;
1994 if (TMath::Abs(y-1.90)<0.45) {d+=(0.013-0.0034);}
1995 if (TMath::Abs(y+1.90)<0.45) {d+=(0.013-0.0034);}
1996 for (Int_t i=0; i<11; i++) {
1997 if (TMath::Abs(z-3.9*i)<0.15) {
1998 if (TMath::Abs(y-0.00)>3.40) d+=dd;
2002 if (TMath::Abs(z+3.9*i)<0.15) {
2003 if (TMath::Abs(y-0.00)>3.40) d+=dd;
2007 if (TMath::Abs(z-1.85-3.9*i)<0.50) {d+=(0.016-0.0034); break;}
2008 if (TMath::Abs(z+2.05+3.9*i)<0.50) {d+=(0.016-0.0034); break;}
2011 if (13<fR&&fR<26) { //SDD
2014 if (TMath::Abs(y-0.00)>3.30) d+=dd;
2016 if (TMath::Abs(y-1.80)<0.55) {
2018 for (Int_t j=0; j<20; j++) {
2019 if (TMath::Abs(z+0.7+1.47*j)<0.12) {d+=0.08; x0=9.; break;}
2020 if (TMath::Abs(z-0.7-1.47*j)<0.12) {d+=0.08; x0=9.; break;}
2023 if (TMath::Abs(y+1.80)<0.55) {
2025 for (Int_t j=0; j<20; j++) {
2026 if (TMath::Abs(z-0.7-1.47*j)<0.12) {d+=0.08; x0=9.; break;}
2027 if (TMath::Abs(z+0.7+1.47*j)<0.12) {d+=0.08; x0=9.; break;}
2031 for (Int_t i=0; i<4; i++) {
2032 if (TMath::Abs(z-7.3*i)<0.60) {
2034 if (TMath::Abs(y-0.00)>3.30) d+=dd;
2037 if (TMath::Abs(z+7.3*i)<0.60) {
2039 if (TMath::Abs(y-0.00)>3.30) d+=dd;
2044 if (6<fR&&fR<8) { //SPD2
2045 Double_t dd=0.0063; x0=21.5;
2047 if (TMath::Abs(y-3.08)>0.5) d+=dd;
2048 if (TMath::Abs(y-3.03)<0.10) d+=0.014;
2050 if (3<fR&&fR<5) { //SPD1
2051 Double_t dd=0.0063; x0=21.5;
2053 if (TMath::Abs(y+0.21)>0.6) d+=dd;
2054 if (TMath::Abs(y+0.10)<0.10) d+=0.014;
2059 //------------------------------------------------------------------------
2060 AliITStrackerMI::AliITSdetector::AliITSdetector(const AliITSdetector& det):
2062 fRmisal(det.fRmisal),
2064 fSinPhi(det.fSinPhi),
2065 fCosPhi(det.fCosPhi),
2071 fNChips(det.fNChips),
2072 fChipIsBad(det.fChipIsBad)
2076 //------------------------------------------------------------------------
2077 void AliITStrackerMI::AliITSdetector::ReadBadDetectorAndChips(Int_t ilayer,Int_t idet,
2078 const AliITSDetTypeRec *detTypeRec)
2080 //--------------------------------------------------------------------
2081 // Read bad detectors and chips from calibration objects in AliITSDetTypeRec
2082 //--------------------------------------------------------------------
2084 // In AliITSDetTypeRec, detector numbers go from 0 to 2197
2085 // while in the tracker they start from 0 for each layer
2086 for(Int_t il=0; il<ilayer; il++)
2087 idet += AliITSgeomTGeo::GetNLadders(il+1)*AliITSgeomTGeo::GetNDetectors(il+1);
2090 if (ilayer==0 || ilayer==1) { // ---------- SPD
2092 } else if (ilayer==2 || ilayer==3) { // ---------- SDD
2094 } else if (ilayer==4 || ilayer==5) { // ---------- SSD
2097 printf("AliITStrackerMI::AliITSdetector::InitBadFromOCDB: Wrong layer number %d\n",ilayer);
2101 // Get calibration from AliITSDetTypeRec
2102 AliITSCalibration *calib = (AliITSCalibration*)detTypeRec->GetCalibrationModel(idet);
2103 calib->SetModuleIndex(idet);
2104 AliITSCalibration *calibSPDdead = 0;
2105 if(detType==0) calibSPDdead = (AliITSCalibration*)detTypeRec->GetSPDDeadModel(idet); // TEMPORARY
2106 if (calib->IsBad() ||
2107 (detType==0 && calibSPDdead->IsBad())) // TEMPORARY
2110 // printf("lay %d bad %d\n",ilayer,idet);
2113 // Get segmentation from AliITSDetTypeRec
2114 AliITSsegmentation *segm = (AliITSsegmentation*)detTypeRec->GetSegmentationModel(detType);
2116 // Read info about bad chips
2117 fNChips = segm->GetMaximumChipIndex()+1;
2118 //printf("ilayer %d detType %d idet %d fNChips %d %d GetNumberOfChips %d\n",ilayer,detType,idet,fNChips,segm->GetMaximumChipIndex(),segm->GetNumberOfChips());
2119 if(fChipIsBad) { delete [] fChipIsBad; fChipIsBad=NULL; }
2120 fChipIsBad = new Bool_t[fNChips];
2121 for (Int_t iCh=0;iCh<fNChips;iCh++) {
2122 fChipIsBad[iCh] = calib->IsChipBad(iCh);
2123 if (detType==0 && calibSPDdead->IsChipBad(iCh)) fChipIsBad[iCh] = kTRUE; // TEMPORARY
2124 //if(fChipIsBad[iCh]) {printf("lay %d det %d bad chip %d\n",ilayer,idet,iCh);}
2129 //------------------------------------------------------------------------
2130 Double_t AliITStrackerMI::GetEffectiveThickness()
2132 //--------------------------------------------------------------------
2133 // Returns the thickness between the current layer and the vertex (units X0)
2134 //--------------------------------------------------------------------
2137 if(fxOverX0Layer[0]<0) BuildMaterialLUT("Layers");
2138 if(fxOverX0Shield[0]<0) BuildMaterialLUT("Shields");
2139 if(fxOverX0Pipe<0) BuildMaterialLUT("Pipe");
2143 Double_t dPipe = (fUseTGeo==0 ? AliITSRecoParam::GetdPipe() : fxOverX0Pipe);
2144 Double_t d=dPipe*AliITSRecoParam::GetrPipe()*AliITSRecoParam::GetrPipe();
2148 Double_t xn=fgLayers[fI].GetR();
2149 for (Int_t i=0; i<fI; i++) {
2150 Double_t xi=fgLayers[i].GetR();
2151 Double_t dLayer = (fUseTGeo==0 ? fgLayers[i].GetThickness(0,0,x0) : fxOverX0Layer[i]);
2157 Double_t dshieldSPD = (fUseTGeo==0 ? AliITSRecoParam::Getdshield(0) : fxOverX0Shield[0]);
2158 d+=dshieldSPD*AliITSRecoParam::GetrInsideShield(0)*AliITSRecoParam::GetrInsideShield(0);
2161 Double_t dshieldSDD = (fUseTGeo==0 ? AliITSRecoParam::Getdshield(1) : fxOverX0Shield[1]);
2162 d+=dshieldSDD*AliITSRecoParam::GetrInsideShield(1)*AliITSRecoParam::GetrInsideShield(1);
2166 //------------------------------------------------------------------------
2167 Int_t AliITStrackerMI::AliITSlayer::InRoad() const {
2168 //-------------------------------------------------------------------
2169 // This function returns number of clusters within the "window"
2170 //--------------------------------------------------------------------
2172 for (Int_t i=fI; i<fN; i++) {
2173 const AliITSRecPoint *c=fClusters[i];
2174 if (c->GetZ() > fZmax) break;
2175 if (c->IsUsed()) continue;
2176 const AliITSdetector &det=GetDetector(c->GetDetectorIndex());
2177 Double_t y=fR*det.GetPhi() + c->GetY();
2179 if (y>2.*fR*TMath::Pi()) y -= 2*fR*TMath::Pi();
2180 if (y>1.*fR*TMath::Pi() && fYmax<y) y -= 2*fR*TMath::Pi();
2182 if (y<fYmin) continue;
2183 if (y>fYmax) continue;
2188 //------------------------------------------------------------------------
2189 Bool_t AliITStrackerMI::RefitAt(Double_t xx,AliITStrackMI *track,
2190 const AliITStrackMI *clusters,Bool_t extra, Bool_t planeeff)
2192 //--------------------------------------------------------------------
2193 // This function refits the track "track" at the position "x" using
2194 // the clusters from "clusters"
2195 // If "extra"==kTRUE,
2196 // the clusters from overlapped modules get attached to "track"
2197 // If "planeff"==kTRUE,
2198 // special approach for plane efficiency evaluation is applyed
2199 //--------------------------------------------------------------------
2201 Int_t index[AliITSgeomTGeo::kNLayers];
2203 for (k=0; k<AliITSgeomTGeo::GetNLayers(); k++) index[k]=-1;
2204 Int_t nc=clusters->GetNumberOfClusters();
2205 for (k=0; k<nc; k++) {
2206 Int_t idx=clusters->GetClusterIndex(k);
2207 Int_t ilayer=(idx&0xf0000000)>>28;
2211 return RefitAt(xx,track,index,extra,planeeff); // call the method below
2213 //------------------------------------------------------------------------
2214 Bool_t AliITStrackerMI::RefitAt(Double_t xx,AliITStrackMI *track,
2215 const Int_t *clusters,Bool_t extra, Bool_t planeeff)
2217 //--------------------------------------------------------------------
2218 // This function refits the track "track" at the position "x" using
2219 // the clusters from array
2220 // If "extra"==kTRUE,
2221 // the clusters from overlapped modules get attached to "track"
2222 // If "planeff"==kTRUE,
2223 // special approach for plane efficiency evaluation is applyed
2224 //--------------------------------------------------------------------
2225 Int_t index[AliITSgeomTGeo::kNLayers];
2227 for (k=0; k<AliITSgeomTGeo::GetNLayers(); k++) index[k]=-1;
2229 for (k=0; k<AliITSgeomTGeo::GetNLayers(); k++) {
2230 index[k]=clusters[k];
2233 // special for cosmics: check which the innermost layer crossed
2235 Int_t innermostlayer=5;
2236 Double_t drphi = TMath::Abs(track->GetD(0.,0.));
2237 for(innermostlayer=0; innermostlayer<AliITSgeomTGeo::GetNLayers(); innermostlayer++) {
2238 if(drphi < fgLayers[innermostlayer].GetR()) break;
2240 AliDebug(2,Form(" drphi %f innermost %d",drphi,innermostlayer));
2242 Int_t modstatus=1; // found
2244 Int_t from, to, step;
2245 if (xx > track->GetX()) {
2246 from=innermostlayer; to=AliITSgeomTGeo::GetNLayers();
2249 from=AliITSgeomTGeo::GetNLayers()-1; to=innermostlayer-1;
2252 TString dir = (step>0 ? "outward" : "inward");
2254 for (Int_t ilayer = from; ilayer != to; ilayer += step) {
2255 AliITSlayer &layer=fgLayers[ilayer];
2256 Double_t r=layer.GetR();
2258 if (step<0 && xx>r) break;
2260 // material between SSD and SDD, SDD and SPD
2261 Double_t hI=ilayer-0.5*step;
2262 if (TMath::Abs(hI-3.5)<0.01) // SDDouter
2263 if(!CorrectForShieldMaterial(track,"SDD",dir)) return kFALSE;
2264 if (TMath::Abs(hI-1.5)<0.01) // SPDouter
2265 if(!CorrectForShieldMaterial(track,"SPD",dir)) return kFALSE;
2268 Double_t oldGlobXYZ[3];
2269 if (!track->GetXYZ(oldGlobXYZ)) return kFALSE;
2271 // continue if we are already beyond this layer
2272 Double_t oldGlobR = TMath::Sqrt(oldGlobXYZ[0]*oldGlobXYZ[0]+oldGlobXYZ[1]*oldGlobXYZ[1]);
2273 if(step>0 && oldGlobR > r) continue; // going outward
2274 if(step<0 && oldGlobR < r) continue; // going inward
2277 if (!track->GetPhiZat(r,phi,z)) return kFALSE;
2279 Int_t idet=layer.FindDetectorIndex(phi,z);
2281 // check if we allow a prolongation without point for large-eta tracks
2282 Int_t skip = CheckSkipLayer(track,ilayer,idet);
2284 modstatus = 4; // out in z
2285 if(LocalModuleCoord(ilayer,idet,track,xloc,zloc)) { // local module coords
2286 track->SetModuleIndexInfo(ilayer,idet,modstatus,xloc,zloc);
2289 // apply correction for material of the current layer
2290 // add time if going outward
2291 CorrectForLayerMaterial(track,ilayer,oldGlobXYZ,dir);
2295 if (idet<0) return kFALSE;
2298 const AliITSdetector &det=layer.GetDetector(idet);
2299 if (!track->Propagate(det.GetPhi(),det.GetR())) return kFALSE;
2301 track->SetDetectorIndex(idet);
2302 if(!LocalModuleCoord(ilayer,idet,track,xloc,zloc)) return kFALSE; // local module coords
2304 Double_t dz,zmin,zmax,dy,ymin,ymax;
2306 const AliITSRecPoint *clAcc=0;
2307 Double_t maxchi2=1000.*AliITSReconstructor::GetRecoParam()->GetMaxChi2();
2309 Int_t idx=index[ilayer];
2310 if (idx>=0) { // cluster in this layer
2311 modstatus = 6; // no refit
2312 const AliITSRecPoint *cl=(AliITSRecPoint *)GetCluster(idx);
2314 if (idet != cl->GetDetectorIndex()) {
2315 idet=cl->GetDetectorIndex();
2316 const AliITSdetector &detc=layer.GetDetector(idet);
2317 if (!track->Propagate(detc.GetPhi(),detc.GetR())) return kFALSE;
2318 track->SetDetectorIndex(idet);
2319 if(!LocalModuleCoord(ilayer,idet,track,xloc,zloc)) return kFALSE; // local module coords
2321 Int_t cllayer = (idx & 0xf0000000) >> 28;;
2322 Double_t chi2=GetPredictedChi2MI(track,cl,cllayer);
2326 modstatus = 1; // found
2331 } else { // no cluster in this layer
2333 modstatus = 3; // skipped
2334 // Plane Eff determination:
2335 if (planeeff && ilayer==AliITSReconstructor::GetRecoParam()->GetIPlanePlaneEff()) {
2336 if (IsOKForPlaneEff(track,clusters,ilayer)) // only adequate track for plane eff. evaluation
2337 UseTrackForPlaneEff(track,ilayer);
2340 modstatus = 5; // no cls in road
2342 if (!ComputeRoad(track,ilayer,idet,zmin,zmax,ymin,ymax)) return kFALSE;
2343 dz = 0.5*(zmax-zmin);
2344 dy = 0.5*(ymax-ymin);
2345 Int_t dead = CheckDeadZone(track,ilayer,idet,dz,dy,kTRUE);
2346 if (dead==1) modstatus = 7; // holes in z in SPD
2347 if (dead==2 || dead==3 || dead==4) modstatus = 2; // dead from OCDB
2352 if (!UpdateMI(track,clAcc,maxchi2,idx)) return kFALSE;
2353 track->SetSampledEdx(clAcc->GetQ(),ilayer-2);
2355 track->SetModuleIndexInfo(ilayer,idet,modstatus,xloc,zloc);
2358 if (extra) { // search for extra clusters in overlapped modules
2359 AliITStrackV2 tmp(*track);
2360 if (!ComputeRoad(track,ilayer,idet,zmin,zmax,ymin,ymax)) return kFALSE;
2361 layer.SelectClusters(zmin,zmax,ymin,ymax);
2363 const AliITSRecPoint *clExtra=0; Int_t ci=-1,cci=-1;
2365 maxchi2=1000.*AliITSReconstructor::GetRecoParam()->GetMaxChi2();
2366 Double_t tolerance=0.1;
2367 while ((clExtra=layer.GetNextCluster(ci))!=0) {
2368 // only clusters in another module! (overlaps)
2369 idetExtra = clExtra->GetDetectorIndex();
2370 if (idet == idetExtra) continue;
2372 const AliITSdetector &detx=layer.GetDetector(idetExtra);
2374 if (!tmp.Propagate(detx.GetPhi(),detx.GetR()+clExtra->GetX())) continue;
2375 if (TMath::Abs(tmp.GetZ() - clExtra->GetZ()) > tolerance) continue;
2376 if (TMath::Abs(tmp.GetY() - clExtra->GetY()) > tolerance) continue;
2377 if (!tmp.Propagate(detx.GetPhi(),detx.GetR())) continue;
2379 Double_t chi2=tmp.GetPredictedChi2(clExtra);
2380 if (chi2<maxchi2) { maxchi2=chi2; cci=ci; }
2383 track->SetExtraCluster(ilayer,(ilayer<<28)+cci);
2384 track->SetExtraModule(ilayer,idetExtra);
2386 } // end search for extra clusters in overlapped modules
2388 // Correct for material of the current layer
2390 // add time if going outward
2391 if(!CorrectForLayerMaterial(track,ilayer,oldGlobXYZ,dir)) return kFALSE;
2393 } // end loop on layers
2395 if (!track->PropagateTo(xx,0.,0.)) return kFALSE;
2399 //------------------------------------------------------------------------
2400 Double_t AliITStrackerMI::GetNormalizedChi2(AliITStrackMI * track, Int_t mode)
2403 // calculate normalized chi2
2404 // return NormalizedChi2(track,0);
2407 Float_t *erry = GetErrY(fCurrentEsdTrack), *errz = GetErrZ(fCurrentEsdTrack);
2408 // track->fdEdxMismatch=0;
2409 Float_t dedxmismatch =0;
2410 Float_t *ny = GetNy(fCurrentEsdTrack), *nz = GetNz(fCurrentEsdTrack);
2412 for (Int_t i = 0;i<6;i++){
2413 if (track->GetClIndex(i)>=0){
2414 Float_t cerry, cerrz;
2415 if (ny[i]>0) {cerry = erry[i]; cerrz=errz[i];}
2417 { cerry= track->GetSigmaY(i); cerrz = track->GetSigmaZ(i);}
2420 Float_t cchi2 = (track->GetDy(i)*track->GetDy(i)/cerry)+(track->GetDz(i)*track->GetDz(i)/cerrz);
2421 if (i>1 && AliITSReconstructor::GetRecoParam()->GetUseAmplitudeInfo(i)) {
2422 Float_t ratio = track->GetNormQ(i)/track->GetExpQ();
2424 cchi2+=(0.5-ratio)*10.;
2425 //track->fdEdxMismatch+=(0.5-ratio)*10.;
2426 dedxmismatch+=(0.5-ratio)*10.;
2430 AliITSRecPoint * cl = (AliITSRecPoint*)GetCluster( track->GetClIndex(i));
2431 Double_t delta = cl->GetNy()+cl->GetNz()-ny[i]-nz[i];
2432 if (delta>1) chi2 +=0.5*TMath::Min(delta/2,2.);
2433 if (i<2) chi2+=2*cl->GetDeltaProbability();
2439 if (TMath::Abs(track->GetdEdxMismatch()-dedxmismatch)>0.0001){
2440 track->SetdEdxMismatch(dedxmismatch);
2444 for (Int_t i = 0;i<4;i++){
2445 if (track->GetClIndex(i)>=0){
2446 Float_t cerry, cerrz;
2447 if (ny[i]>0) {cerry = erry[i]; cerrz=errz[i];}
2448 else { cerry= track->GetSigmaY(i); cerrz = track->GetSigmaZ(i);}
2451 chi2+= (track->GetDy(i)*track->GetDy(i)/cerry);
2452 chi2+= (track->GetDz(i)*track->GetDz(i)/cerrz);
2456 for (Int_t i = 4;i<6;i++){
2457 if (track->GetClIndex(i)>=0){
2458 Float_t cerry, cerrz;
2459 if (ny[i]>0) {cerry = erry[i]; cerrz=errz[i];}
2460 else { cerry= track->GetSigmaY(i); cerrz = track->GetSigmaZ(i);}
2463 Float_t cerryb, cerrzb;
2464 if (ny[i+6]>0) {cerryb = erry[i+6]; cerrzb=errz[i+6];}
2465 else { cerryb= track->GetSigmaY(i+6); cerrzb = track->GetSigmaZ(i+6);}
2468 chi2+= TMath::Min((track->GetDy(i+6)*track->GetDy(i+6)/cerryb),track->GetDy(i)*track->GetDy(i)/cerry);
2469 chi2+= TMath::Min((track->GetDz(i+6)*track->GetDz(i+6)/cerrzb),track->GetDz(i)*track->GetDz(i)/cerrz);
2474 if (track->GetESDtrack()->GetTPCsignal()>85){
2475 Float_t ratio = track->GetdEdx()/track->GetESDtrack()->GetTPCsignal();
2477 chi2+=(0.5-ratio)*5.;
2480 chi2+=(ratio-2.0)*3;
2484 Double_t match = TMath::Sqrt(track->GetChi22());
2485 if (track->GetConstrain()) match/=track->GetNumberOfClusters();
2486 if (!track->GetConstrain()) {
2487 if (track->GetNumberOfClusters()>2) {
2488 match/=track->GetNumberOfClusters()-2.;
2493 if (match<0) match=0;
2495 // penalty factor for missing points (NDeadZone>0), but no penalty
2496 // for layer with deadZoneProb close to 1 (either we wanted to skip layer
2497 // or there is a dead from OCDB)
2498 Float_t deadzonefactor = 0.;
2499 if (track->GetNDeadZone()>0.) {
2500 Float_t sumDeadZoneProbability=0;
2501 for(Int_t ilay=0;ilay<6;ilay++) sumDeadZoneProbability+=track->GetDeadZoneProbability(ilay);
2502 Float_t nDeadZoneWithProbNot1=(Float_t)(track->GetNDeadZone())-sumDeadZoneProbability;
2503 if(nDeadZoneWithProbNot1>0.) {
2504 Float_t deadZoneProbability = sumDeadZoneProbability - (Float_t)((Int_t)sumDeadZoneProbability);
2505 deadZoneProbability /= nDeadZoneWithProbNot1;
2506 deadzonefactor = 3.*(1.1-deadZoneProbability);
2510 Double_t normchi2 = 2*track->GetNSkipped()+match+deadzonefactor+(1+(2*track->GetNSkipped()+deadzonefactor)/track->GetNumberOfClusters())*
2511 (chi2)/TMath::Max(double(sum-track->GetNSkipped()),
2512 1./(1.+track->GetNSkipped()));
2516 //------------------------------------------------------------------------
2517 Double_t AliITStrackerMI::GetMatchingChi2(const AliITStrackMI * track1,const AliITStrackMI * track2)
2520 // return matching chi2 between two tracks
2521 Double_t largeChi2=1000.;
2523 AliITStrackMI track3(*track2);
2524 if (!track3.Propagate(track1->GetAlpha(),track1->GetX())) return largeChi2;
2526 vec(0,0)=track1->GetY() - track3.GetY();
2527 vec(1,0)=track1->GetZ() - track3.GetZ();
2528 vec(2,0)=track1->GetSnp() - track3.GetSnp();
2529 vec(3,0)=track1->GetTgl() - track3.GetTgl();
2530 vec(4,0)=track1->GetSigned1Pt() - track3.GetSigned1Pt();
2533 cov(0,0) = track1->GetSigmaY2()+track3.GetSigmaY2();
2534 cov(1,1) = track1->GetSigmaZ2()+track3.GetSigmaZ2();
2535 cov(2,2) = track1->GetSigmaSnp2()+track3.GetSigmaSnp2();
2536 cov(3,3) = track1->GetSigmaTgl2()+track3.GetSigmaTgl2();
2537 cov(4,4) = track1->GetSigma1Pt2()+track3.GetSigma1Pt2();
2539 cov(0,1)=cov(1,0) = track1->GetSigmaZY()+track3.GetSigmaZY();
2540 cov(0,2)=cov(2,0) = track1->GetSigmaSnpY()+track3.GetSigmaSnpY();
2541 cov(0,3)=cov(3,0) = track1->GetSigmaTglY()+track3.GetSigmaTglY();
2542 cov(0,4)=cov(4,0) = track1->GetSigma1PtY()+track3.GetSigma1PtY();
2544 cov(1,2)=cov(2,1) = track1->GetSigmaSnpZ()+track3.GetSigmaSnpZ();
2545 cov(1,3)=cov(3,1) = track1->GetSigmaTglZ()+track3.GetSigmaTglZ();
2546 cov(1,4)=cov(4,1) = track1->GetSigma1PtZ()+track3.GetSigma1PtZ();
2548 cov(2,3)=cov(3,2) = track1->GetSigmaTglSnp()+track3.GetSigmaTglSnp();
2549 cov(2,4)=cov(4,2) = track1->GetSigma1PtSnp()+track3.GetSigma1PtSnp();
2551 cov(3,4)=cov(4,3) = track1->GetSigma1PtTgl()+track3.GetSigma1PtTgl();
2554 TMatrixD vec2(cov,TMatrixD::kMult,vec);
2555 TMatrixD chi2(vec2,TMatrixD::kTransposeMult,vec);
2558 //------------------------------------------------------------------------
2559 Double_t AliITStrackerMI::GetSPDDeadZoneProbability(Double_t zpos, Double_t zerr) const
2562 // return probability that given point (characterized by z position and error)
2563 // is in SPD dead zone
2565 Double_t probability = 0.;
2566 Double_t absz = TMath::Abs(zpos);
2567 Double_t nearestz = (absz<2.) ? 0.5*(fSPDdetzcentre[1]+fSPDdetzcentre[2]) :
2568 0.5*(fSPDdetzcentre[2]+fSPDdetzcentre[3]);
2569 if (TMath::Abs(absz-nearestz)>0.25+3.*zerr) return probability;
2570 Double_t zmin, zmax;
2571 if (zpos<-6.) { // dead zone at z = -7
2572 zmin = fSPDdetzcentre[0] + 0.5*AliITSRecoParam::GetSPDdetzlength();
2573 zmax = fSPDdetzcentre[1] - 0.5*AliITSRecoParam::GetSPDdetzlength();
2574 } else if (zpos>6.) { // dead zone at z = +7
2575 zmin = fSPDdetzcentre[2] + 0.5*AliITSRecoParam::GetSPDdetzlength();
2576 zmax = fSPDdetzcentre[3] - 0.5*AliITSRecoParam::GetSPDdetzlength();
2577 } else if (absz<2.) { // dead zone at z = 0
2578 zmin = fSPDdetzcentre[1] + 0.5*AliITSRecoParam::GetSPDdetzlength();
2579 zmax = fSPDdetzcentre[2] - 0.5*AliITSRecoParam::GetSPDdetzlength();
2584 // probability that the true z is in the range [zmin,zmax] (i.e. inside
2586 probability = 0.5*( TMath::Erf((zpos-zmin)/zerr/TMath::Sqrt(2.)) -
2587 TMath::Erf((zpos-zmax)/zerr/TMath::Sqrt(2.)) );
2590 //------------------------------------------------------------------------
2591 Double_t AliITStrackerMI::GetTruncatedChi2(const AliITStrackMI * track, Float_t fac)
2594 // calculate normalized chi2
2596 Float_t *erry = GetErrY(fCurrentEsdTrack), *errz = GetErrZ(fCurrentEsdTrack);
2598 for (Int_t i = 0;i<6;i++){
2599 if (TMath::Abs(track->GetDy(i))>0){
2600 chi2[i]= (track->GetDy(i)/erry[i])*(track->GetDy(i)/erry[i]);
2601 chi2[i]+= (track->GetDz(i)/errz[i])*(track->GetDz(i)/errz[i]);
2604 else{chi2[i]=10000;}
2607 TMath::Sort(6,chi2,index,kFALSE);
2608 Float_t max = float(ncl)*fac-1.;
2609 Float_t sumchi=0, sumweight=0;
2610 for (Int_t i=0;i<max+1;i++){
2611 Float_t weight = (i<max)?1.:(max+1.-i);
2612 sumchi+=weight*chi2[index[i]];
2615 Double_t normchi2 = sumchi/sumweight;
2618 //------------------------------------------------------------------------
2619 Double_t AliITStrackerMI::GetInterpolatedChi2(const AliITStrackMI * forwardtrack,const AliITStrackMI * backtrack)
2622 // calculate normalized chi2
2623 // if (forwardtrack->fNUsed>0.3*float(forwardtrack->GetNumberOfClusters())) return 10000;
2626 for (Int_t i=0;i<6;i++){
2627 if ( (backtrack->GetSigmaY(i)<0.000000001) || (forwardtrack->GetSigmaY(i)<0.000000001)) continue;
2628 Double_t sy1 = forwardtrack->GetSigmaY(i);
2629 Double_t sz1 = forwardtrack->GetSigmaZ(i);
2630 Double_t sy2 = backtrack->GetSigmaY(i);
2631 Double_t sz2 = backtrack->GetSigmaZ(i);
2632 if (i<2){ sy2=1000.;sz2=1000;}
2634 Double_t dy0 = (forwardtrack->GetDy(i)/(sy1*sy1) +backtrack->GetDy(i)/(sy2*sy2))/(1./(sy1*sy1)+1./(sy2*sy2));
2635 Double_t dz0 = (forwardtrack->GetDz(i)/(sz1*sz1) +backtrack->GetDz(i)/(sz2*sz2))/(1./(sz1*sz1)+1./(sz2*sz2));
2637 Double_t nz0 = dz0*TMath::Sqrt((1./(sz1*sz1)+1./(sz2*sz2)));
2638 Double_t ny0 = dy0*TMath::Sqrt((1./(sy1*sy1)+1./(sy2*sy2)));
2640 res+= nz0*nz0+ny0*ny0;
2643 if (npoints>1) return
2644 TMath::Max(0.3*forwardtrack->OneOverPt()-0.5,0.)+
2645 //2*forwardtrack->fNUsed+
2646 res/TMath::Max(double(npoints-forwardtrack->GetNSkipped()),
2647 1./(1.+forwardtrack->GetNSkipped()));
2650 //------------------------------------------------------------------------
2651 Float_t *AliITStrackerMI::GetWeight(Int_t index) {
2652 //--------------------------------------------------------------------
2653 // Return pointer to a given cluster
2654 //--------------------------------------------------------------------
2655 Int_t l=(index & 0xf0000000) >> 28;
2656 Int_t c=(index & 0x0fffffff) >> 00;
2657 return fgLayers[l].GetWeight(c);
2659 //------------------------------------------------------------------------
2660 void AliITStrackerMI::RegisterClusterTracks(const AliITStrackMI* track,Int_t id)
2662 //---------------------------------------------
2663 // register track to the list
2665 if (track->GetESDtrack()->GetKinkIndex(0)!=0) return; //don't register kink tracks
2668 for (Int_t icluster=0;icluster<track->GetNumberOfClusters();icluster++){
2669 Int_t index = track->GetClusterIndex(icluster);
2670 Int_t l=(index & 0xf0000000) >> 28;
2671 Int_t c=(index & 0x0fffffff) >> 00;
2672 if (c>fgLayers[l].GetNumberOfClusters()) continue;
2673 for (Int_t itrack=0;itrack<4;itrack++){
2674 if (fgLayers[l].GetClusterTracks(itrack,c)<0){
2675 fgLayers[l].SetClusterTracks(itrack,c,id);
2681 //------------------------------------------------------------------------
2682 void AliITStrackerMI::UnRegisterClusterTracks(const AliITStrackMI* track, Int_t id)
2684 //---------------------------------------------
2685 // unregister track from the list
2686 for (Int_t icluster=0;icluster<track->GetNumberOfClusters();icluster++){
2687 Int_t index = track->GetClusterIndex(icluster);
2688 Int_t l=(index & 0xf0000000) >> 28;
2689 Int_t c=(index & 0x0fffffff) >> 00;
2690 if (c>fgLayers[l].GetNumberOfClusters()) continue;
2691 for (Int_t itrack=0;itrack<4;itrack++){
2692 if (fgLayers[l].GetClusterTracks(itrack,c)==id){
2693 fgLayers[l].SetClusterTracks(itrack,c,-1);
2698 //------------------------------------------------------------------------
2699 Float_t AliITStrackerMI::GetNumberOfSharedClusters(AliITStrackMI* track,Int_t id, Int_t list[6], AliITSRecPoint *clist[6])
2701 //-------------------------------------------------------------
2702 //get number of shared clusters
2703 //-------------------------------------------------------------
2705 for (Int_t i=0;i<6;i++) { list[i]=-1, clist[i]=0;}
2706 // mean number of clusters
2707 Float_t *ny = GetNy(id), *nz = GetNz(id);
2710 for (Int_t icluster=0;icluster<track->GetNumberOfClusters();icluster++){
2711 Int_t index = track->GetClusterIndex(icluster);
2712 Int_t l=(index & 0xf0000000) >> 28;
2713 Int_t c=(index & 0x0fffffff) >> 00;
2714 if (c>fgLayers[l].GetNumberOfClusters()) continue;
2716 printf("problem\n");
2718 AliITSRecPoint *cl = (AliITSRecPoint*)GetCluster(index);
2722 if (l>3&&cl->GetNy()+cl->GetNz()>6) continue;
2723 if (l>2&&AliITSReconstructor::GetRecoParam()->GetUseAmplitudeInfo(l))
2724 if (track->GetNormQ(l)/track->GetExpQ()>3.5) continue;
2726 deltan = (cl->GetNy()+cl->GetNz()-ny[l]-nz[l]);
2729 deltan = (cl->GetNz()-nz[l]);
2731 if (deltan>2.0) continue; // extended - highly probable shared cluster
2732 weight = 2./TMath::Max(3.+deltan,2.);
2734 for (Int_t itrack=0;itrack<4;itrack++){
2735 if (fgLayers[l].GetClusterTracks(itrack,c)>=0 && fgLayers[l].GetClusterTracks(itrack,c)!=id){
2737 clist[l] = (AliITSRecPoint*)GetCluster(index);
2743 track->SetNUsed(shared);
2746 //------------------------------------------------------------------------
2747 Int_t AliITStrackerMI::GetOverlapTrack(const AliITStrackMI *track, Int_t trackID, Int_t &shared, Int_t clusterlist[6],Int_t overlist[6])
2750 // find first shared track
2752 // mean number of clusters
2753 Float_t *ny = GetNy(trackID), *nz = GetNz(trackID);
2755 for (Int_t i=0;i<6;i++) overlist[i]=-1;
2756 Int_t sharedtrack=100000;
2757 Int_t tracks[24],trackindex=0;
2758 for (Int_t i=0;i<24;i++) {tracks[i]=-1;}
2760 for (Int_t icluster=0;icluster<6;icluster++){
2761 if (clusterlist[icluster]<0) continue;
2762 Int_t index = clusterlist[icluster];
2763 Int_t l=(index & 0xf0000000) >> 28;
2764 Int_t c=(index & 0x0fffffff) >> 00;
2766 printf("problem\n");
2768 if (c>fgLayers[l].GetNumberOfClusters()) continue;
2769 //if (l>3) continue;
2770 AliITSRecPoint *cl = (AliITSRecPoint*)GetCluster(index);
2773 if (l>3&&cl->GetNy()+cl->GetNz()>6) continue;
2774 if (l>2&&AliITSReconstructor::GetRecoParam()->GetUseAmplitudeInfo(l))
2775 if (track->GetNormQ(l)/track->GetExpQ()>3.5) continue;
2777 deltan = (cl->GetNy()+cl->GetNz()-ny[l]-nz[l]);
2780 deltan = (cl->GetNz()-nz[l]);
2782 if (deltan>2.0) continue; // extended - highly probable shared cluster
2784 for (Int_t itrack=3;itrack>=0;itrack--){
2785 if (fgLayers[l].GetClusterTracks(itrack,c)<0) continue;
2786 if (fgLayers[l].GetClusterTracks(itrack,c)!=trackID){
2787 tracks[trackindex] = fgLayers[l].GetClusterTracks(itrack,c);
2792 if (trackindex==0) return -1;
2794 sharedtrack = tracks[0];
2796 if (trackindex==2) sharedtrack =TMath::Min(tracks[0],tracks[1]);
2799 Int_t tracks2[24], cluster[24];
2800 for (Int_t i=0;i<trackindex;i++){ tracks2[i]=-1; cluster[i]=0;}
2803 for (Int_t i=0;i<trackindex;i++){
2804 if (tracks[i]<0) continue;
2805 tracks2[index] = tracks[i];
2807 for (Int_t j=i+1;j<trackindex;j++){
2808 if (tracks[j]<0) continue;
2809 if (tracks[j]==tracks[i]){
2817 for (Int_t i=0;i<index;i++){
2818 if (cluster[index]>max) {
2819 sharedtrack=tracks2[index];
2826 if (sharedtrack>=100000) return -1;
2828 // make list of overlaps
2830 for (Int_t icluster=0;icluster<6;icluster++){
2831 if (clusterlist[icluster]<0) continue;
2832 Int_t index = clusterlist[icluster];
2833 Int_t l=(index & 0xf0000000) >> 28;
2834 Int_t c=(index & 0x0fffffff) >> 00;
2835 if (c>fgLayers[l].GetNumberOfClusters()) continue;
2836 AliITSRecPoint *cl = (AliITSRecPoint*)GetCluster(index);
2838 if (cl->GetNy()>2) continue;
2839 if (cl->GetNz()>2) continue;
2842 if (cl->GetNy()>3) continue;
2843 if (cl->GetNz()>3) continue;
2846 for (Int_t itrack=3;itrack>=0;itrack--){
2847 if (fgLayers[l].GetClusterTracks(itrack,c)<0) continue;
2848 if (fgLayers[l].GetClusterTracks(itrack,c)==sharedtrack){
2856 //------------------------------------------------------------------------
2857 AliITStrackMI * AliITStrackerMI::GetBest2Tracks(Int_t trackID1, Int_t trackID2, Float_t th0, Float_t th1){
2859 // try to find track hypothesys without conflicts
2860 // with minimal chi2;
2861 TClonesArray *arr1 = (TClonesArray*)fTrackHypothesys.At(trackID1);
2862 Int_t entries1 = arr1->GetEntriesFast();
2863 TClonesArray *arr2 = (TClonesArray*)fTrackHypothesys.At(trackID2);
2864 if (!arr2) return (AliITStrackMI*) arr1->UncheckedAt(0);
2865 Int_t entries2 = arr2->GetEntriesFast();
2866 if (entries2<=0) return (AliITStrackMI*) arr1->UncheckedAt(0);
2868 AliITStrackMI * track10=(AliITStrackMI*) arr1->UncheckedAt(0);
2869 AliITStrackMI * track20=(AliITStrackMI*) arr2->UncheckedAt(0);
2870 if (track10->Pt()>0.5+track20->Pt()) return track10;
2872 for (Int_t itrack=0;itrack<entries1;itrack++){
2873 AliITStrackMI * track=(AliITStrackMI*) arr1->UncheckedAt(itrack);
2874 UnRegisterClusterTracks(track,trackID1);
2877 for (Int_t itrack=0;itrack<entries2;itrack++){
2878 AliITStrackMI * track=(AliITStrackMI*) arr2->UncheckedAt(itrack);
2879 UnRegisterClusterTracks(track,trackID2);
2883 Float_t maxconflicts=6;
2884 Double_t maxchi2 =1000.;
2886 // get weight of hypothesys - using best hypothesy
2889 Int_t list1[6],list2[6];
2890 AliITSRecPoint *clist1[6], *clist2[6] ;
2891 RegisterClusterTracks(track10,trackID1);
2892 RegisterClusterTracks(track20,trackID2);
2893 Float_t conflict1 = GetNumberOfSharedClusters(track10,trackID1,list1,clist1);
2894 Float_t conflict2 = GetNumberOfSharedClusters(track20,trackID2,list2,clist2);
2895 UnRegisterClusterTracks(track10,trackID1);
2896 UnRegisterClusterTracks(track20,trackID2);
2899 Float_t chi21 =0,chi22=0,ncl1=0,ncl2=0;
2900 Float_t nerry[6],nerrz[6];
2901 Float_t *erry1=GetErrY(trackID1),*errz1 = GetErrZ(trackID1);
2902 Float_t *erry2=GetErrY(trackID2),*errz2 = GetErrZ(trackID2);
2903 for (Int_t i=0;i<6;i++){
2904 if ( (erry1[i]>0) && (erry2[i]>0)) {
2905 nerry[i] = TMath::Min(erry1[i],erry2[i]);
2906 nerrz[i] = TMath::Min(errz1[i],errz2[i]);
2908 nerry[i] = TMath::Max(erry1[i],erry2[i]);
2909 nerrz[i] = TMath::Max(errz1[i],errz2[i]);
2911 if (TMath::Abs(track10->GetDy(i))>0.000000000000001){
2912 chi21 += track10->GetDy(i)*track10->GetDy(i)/(nerry[i]*nerry[i]);
2913 chi21 += track10->GetDz(i)*track10->GetDz(i)/(nerrz[i]*nerrz[i]);
2916 if (TMath::Abs(track20->GetDy(i))>0.000000000000001){
2917 chi22 += track20->GetDy(i)*track20->GetDy(i)/(nerry[i]*nerry[i]);
2918 chi22 += track20->GetDz(i)*track20->GetDz(i)/(nerrz[i]*nerrz[i]);
2926 Float_t d1 = TMath::Sqrt(track10->GetD(0)*track10->GetD(0)+track10->GetD(1)*track10->GetD(1))+0.1;
2927 Float_t d2 = TMath::Sqrt(track20->GetD(0)*track20->GetD(0)+track20->GetD(1)*track20->GetD(1))+0.1;
2928 Float_t s1 = TMath::Sqrt(track10->GetSigmaY2()*track10->GetSigmaZ2());
2929 Float_t s2 = TMath::Sqrt(track20->GetSigmaY2()*track20->GetSigmaZ2());
2931 w1 = (d2/(d1+d2)+ 2*s2/(s1+s2)+
2932 +s2/(s1+s2)*0.5*(chi22+2.)/(chi21+chi22+4.)
2933 +1.*track10->Pt()/(track10->Pt()+track20->Pt())
2935 w2 = (d1/(d1+d2)+ 2*s1/(s1+s2)+
2936 s1/(s1+s2)*0.5*(chi21+2.)/(chi21+chi22+4.)
2937 +1.*track20->Pt()/(track10->Pt()+track20->Pt())
2940 Double_t sumw = w1+w2;
2944 w1 = (d2+0.5)/(d1+d2+1.);
2945 w2 = (d1+0.5)/(d1+d2+1.);
2947 // Float_t maxmax = w1*track10->fChi2MIP[0]+w2*track20->fChi2MIP[0]+w1*conflict1+w2*conflict2+1.;
2948 //Float_t maxconflicts0 = w1*conflict1+w2*conflict2;
2950 // get pair of "best" hypothesys
2952 Float_t * ny1 = GetNy(trackID1), * nz1 = GetNz(trackID1);
2953 Float_t * ny2 = GetNy(trackID2), * nz2 = GetNz(trackID2);
2955 for (Int_t itrack1=0;itrack1<entries1;itrack1++){
2956 AliITStrackMI * track1=(AliITStrackMI*) arr1->UncheckedAt(itrack1);
2957 //if (track1->fFakeRatio>0) continue;
2958 RegisterClusterTracks(track1,trackID1);
2959 for (Int_t itrack2=0;itrack2<entries2;itrack2++){
2960 AliITStrackMI * track2=(AliITStrackMI*) arr2->UncheckedAt(itrack2);
2962 // Float_t current = w1*track1->fChi2MIP[0]+w2*track2->fChi2MIP[0];
2963 //if (track2->fFakeRatio>0) continue;
2965 RegisterClusterTracks(track2,trackID2);
2966 Float_t cconflict1 = GetNumberOfSharedClusters(track1,trackID1,list1,clist1);
2967 Float_t cconflict2 = GetNumberOfSharedClusters(track2,trackID2,list2,clist2);
2968 UnRegisterClusterTracks(track2,trackID2);
2970 if (track1->GetConstrain()) nskipped+=w1*track1->GetNSkipped();
2971 if (track2->GetConstrain()) nskipped+=w2*track2->GetNSkipped();
2972 if (nskipped>0.5) continue;
2974 //if ( w1*conflict1+w2*conflict2>maxconflicts0) continue;
2975 if (conflict1+1<cconflict1) continue;
2976 if (conflict2+1<cconflict2) continue;
2980 for (Int_t i=0;i<6;i++){
2982 Float_t c1 =0.; // conflict coeficients
2984 if (clist1[i]&&clist2[i]){
2987 deltan = (clist1[i]->GetNy()+clist1[i]->GetNz()-TMath::Max(ny1[i],ny2[i])-TMath::Max(nz1[i],nz2[i]));
2990 deltan = (clist1[i]->GetNz()-TMath::Max(nz1[i],nz2[i]));
2992 c1 = 2./TMath::Max(3.+deltan,2.);
2993 c2 = 2./TMath::Max(3.+deltan,2.);
2999 deltan = (clist1[i]->GetNy()+clist1[i]->GetNz()-ny1[i]-nz1[i]);
3002 deltan = (clist1[i]->GetNz()-nz1[i]);
3004 c1 = 2./TMath::Max(3.+deltan,2.);
3011 deltan = (clist2[i]->GetNy()+clist2[i]->GetNz()-ny2[i]-nz2[i]);
3014 deltan = (clist2[i]->GetNz()-nz2[i]);
3016 c2 = 2./TMath::Max(3.+deltan,2.);
3022 if (TMath::Abs(track1->GetDy(i))>0.) {
3023 chi21 = (track1->GetDy(i)/track1->GetSigmaY(i))*(track1->GetDy(i)/track1->GetSigmaY(i))+
3024 (track1->GetDz(i)/track1->GetSigmaZ(i))*(track1->GetDz(i)/track1->GetSigmaZ(i));
3025 //chi21 = (track1->fDy[i]*track1->fDy[i])/(nerry[i]*nerry[i])+
3026 // (track1->GetDz(i)*track1->GetDz(i))/(nerrz[i]*nerrz[i]);
3028 if (TMath::Abs(track1->GetSigmaY(i)>0.)) c1=1;
3031 if (TMath::Abs(track2->GetDy(i))>0.) {
3032 chi22 = (track2->GetDy(i)/track2->GetSigmaY(i))*(track2->GetDy(i)/track2->GetSigmaY(i))+
3033 (track2->GetDz(i)/track2->GetSigmaZ(i))*(track2->GetDz(i)/track2->GetSigmaZ(i));
3034 //chi22 = (track2->fDy[i]*track2->fDy[i])/(nerry[i]*nerry[i])+
3035 // (track2->fDz[i]*track2->fDz[i])/(nerrz[i]*nerrz[i]);
3038 if (TMath::Abs(track2->GetSigmaY(i)>0.)) c2=1;
3040 sumchi2+=w1*(1.+c1)*(1+c1)*(chi21+c1)+w2*(1.+c2)*(1+c2)*(chi22+c2);
3041 if (chi21>0) sum+=w1;
3042 if (chi22>0) sum+=w2;
3045 Double_t norm = sum-w1*track1->GetNSkipped()-w2*track2->GetNSkipped();
3046 if (norm<0) norm =1/(w1*track1->GetNSkipped()+w2*track2->GetNSkipped());
3047 Double_t normchi2 = 2*conflict+sumchi2/sum;
3048 if ( normchi2 <maxchi2 ){
3051 maxconflicts = conflict;
3055 UnRegisterClusterTracks(track1,trackID1);
3058 // if (maxconflicts<4 && maxchi2<th0){
3059 if (maxchi2<th0*2.){
3060 Float_t orig = track10->GetFakeRatio()*track10->GetNumberOfClusters();
3061 AliITStrackMI* track1=(AliITStrackMI*) arr1->UncheckedAt(index1);
3062 track1->SetChi2MIP(5,maxconflicts);
3063 track1->SetChi2MIP(6,maxchi2);
3064 track1->SetChi2MIP(7,0.01+orig-(track1->GetFakeRatio()*track1->GetNumberOfClusters()));
3065 // track1->UpdateESDtrack(AliESDtrack::kITSin);
3066 track1->SetChi2MIP(8,index1);
3067 fBestTrackIndex[trackID1] =index1;
3068 UpdateESDtrack(track1, AliESDtrack::kITSin);
3070 else if (track10->GetChi2MIP(0)<th1){
3071 track10->SetChi2MIP(5,maxconflicts);
3072 track10->SetChi2MIP(6,maxchi2);
3073 // track10->UpdateESDtrack(AliESDtrack::kITSin);
3074 UpdateESDtrack(track10,AliESDtrack::kITSin);
3077 for (Int_t itrack=0;itrack<entries1;itrack++){
3078 AliITStrackMI * track=(AliITStrackMI*) arr1->UncheckedAt(itrack);
3079 UnRegisterClusterTracks(track,trackID1);
3082 for (Int_t itrack=0;itrack<entries2;itrack++){
3083 AliITStrackMI * track=(AliITStrackMI*) arr2->UncheckedAt(itrack);
3084 UnRegisterClusterTracks(track,trackID2);
3087 if (track10->GetConstrain()&&track10->GetChi2MIP(0)<AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(0)&&track10->GetChi2MIP(1)<AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(1)
3088 &&track10->GetChi2MIP(2)<AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(2)&&track10->GetChi2MIP(3)<AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(3)){
3089 // if (track10->fChi2MIP[0]<AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(0)&&track10->fChi2MIP[1]<AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(1)
3090 // &&track10->fChi2MIP[2]<AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(2)&&track10->fChi2MIP[3]<AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(3)){
3091 RegisterClusterTracks(track10,trackID1);
3093 if (track20->GetConstrain()&&track20->GetChi2MIP(0)<AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(0)&&track20->GetChi2MIP(1)<AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(1)
3094 &&track20->GetChi2MIP(2)<AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(2)&&track20->GetChi2MIP(3)<AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(3)){
3095 //if (track20->fChi2MIP[0]<AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(0)&&track20->fChi2MIP[1]<AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(1)
3096 // &&track20->fChi2MIP[2]<AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(2)&&track20->fChi2MIP[3]<AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(3)){
3097 RegisterClusterTracks(track20,trackID2);
3102 //------------------------------------------------------------------------
3103 void AliITStrackerMI::UseClusters(const AliKalmanTrack *t, Int_t from) const {
3104 //--------------------------------------------------------------------
3105 // This function marks clusters assigned to the track
3106 //--------------------------------------------------------------------
3107 AliTracker::UseClusters(t,from);
3109 AliITSRecPoint *c=(AliITSRecPoint *)GetCluster(t->GetClusterIndex(0));
3110 //if (c->GetQ()>2) c->Use();
3111 if (c->GetSigmaZ2()>0.1) c->Use();
3112 c=(AliITSRecPoint *)GetCluster(t->GetClusterIndex(1));
3113 //if (c->GetQ()>2) c->Use();
3114 if (c->GetSigmaZ2()>0.1) c->Use();
3117 //------------------------------------------------------------------------
3118 void AliITStrackerMI::AddTrackHypothesys(AliITStrackMI * track, Int_t esdindex)
3120 //------------------------------------------------------------------
3121 // add track to the list of hypothesys
3122 //------------------------------------------------------------------
3124 if (esdindex>=fTrackHypothesys.GetEntriesFast())
3125 fTrackHypothesys.Expand(TMath::Max(fTrackHypothesys.GetSize(),esdindex*2+10));
3127 TObjArray * array = (TObjArray*) fTrackHypothesys.At(esdindex);
3129 array = new TObjArray(10);
3130 fTrackHypothesys.AddAt(array,esdindex);
3132 array->AddLast(track);
3134 //------------------------------------------------------------------------
3135 void AliITStrackerMI::SortTrackHypothesys(Int_t esdindex, Int_t maxcut, Int_t mode)
3137 //-------------------------------------------------------------------
3138 // compress array of track hypothesys
3139 // keep only maxsize best hypothesys
3140 //-------------------------------------------------------------------
3141 if (esdindex>fTrackHypothesys.GetEntriesFast()) return;
3142 if (! (fTrackHypothesys.At(esdindex)) ) return;
3143 TObjArray * array = (TObjArray*) fTrackHypothesys.At(esdindex);
3144 Int_t entries = array->GetEntriesFast();
3146 //- find preliminary besttrack as a reference
3147 Float_t minchi2=10000;
3149 AliITStrackMI * besttrack=0;
3150 for (Int_t itrack=0;itrack<array->GetEntriesFast();itrack++){
3151 AliITStrackMI * track = (AliITStrackMI*)array->At(itrack);
3152 if (!track) continue;
3153 Float_t chi2 = NormalizedChi2(track,0);
3155 Int_t tpcLabel=track->GetESDtrack()->GetTPCLabel();
3156 track->SetLabel(tpcLabel);
3158 track->SetFakeRatio(1.);
3159 CookLabel(track,0.); //For comparison only
3161 //if (chi2<AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(0)&&track->fFakeRatio==0){
3162 if (chi2<AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(0)){
3163 if (track->GetNumberOfClusters()<maxn) continue;
3164 maxn = track->GetNumberOfClusters();
3171 if (track->GetConstrain() || track->GetNumberOfClusters()>5){ //keep best short tracks - without vertex constrain
3172 delete array->RemoveAt(itrack);
3176 if (!besttrack) return;
3179 //take errors of best track as a reference
3180 Float_t *erry = GetErrY(esdindex), *errz = GetErrZ(esdindex);
3181 Float_t *ny = GetNy(esdindex), *nz = GetNz(esdindex);
3182 for (Int_t j=0;j<6;j++) {
3183 if (besttrack->GetClIndex(j)>=0){
3184 erry[j] = besttrack->GetSigmaY(j); erry[j+6] = besttrack->GetSigmaY(j+6);
3185 errz[j] = besttrack->GetSigmaZ(j); errz[j+6] = besttrack->GetSigmaZ(j+6);
3186 ny[j] = besttrack->GetNy(j);
3187 nz[j] = besttrack->GetNz(j);
3191 // calculate normalized chi2
3193 Float_t * chi2 = new Float_t[entries];
3194 Int_t * index = new Int_t[entries];
3195 for (Int_t i=0;i<entries;i++) chi2[i] =10000;
3196 for (Int_t itrack=0;itrack<entries;itrack++){
3197 AliITStrackMI * track = (AliITStrackMI*)array->At(itrack);
3199 track->SetChi2MIP(0,GetNormalizedChi2(track, mode));
3200 if (track->GetChi2MIP(0)<AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(0))
3201 chi2[itrack] = track->GetChi2MIP(0);
3203 if (track->GetConstrain() || track->GetNumberOfClusters()>5){ //keep best short tracks - without vertex constrain
3204 delete array->RemoveAt(itrack);
3210 TMath::Sort(entries,chi2,index,kFALSE);
3211 besttrack = (AliITStrackMI*)array->At(index[0]);
3212 if (besttrack&&besttrack->GetChi2MIP(0)<AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(0)){
3213 for (Int_t j=0;j<6;j++){
3214 if (besttrack->GetClIndex(j)>=0){
3215 erry[j] = besttrack->GetSigmaY(j); erry[j+6] = besttrack->GetSigmaY(j+6);
3216 errz[j] = besttrack->GetSigmaZ(j); erry[j+6] = besttrack->GetSigmaY(j+6);
3217 ny[j] = besttrack->GetNy(j);
3218 nz[j] = besttrack->GetNz(j);
3223 // calculate one more time with updated normalized errors
3224 for (Int_t i=0;i<entries;i++) chi2[i] =10000;
3225 for (Int_t itrack=0;itrack<entries;itrack++){
3226 AliITStrackMI * track = (AliITStrackMI*)array->At(itrack);
3228 track->SetChi2MIP(0,GetNormalizedChi2(track,mode));
3229 if (track->GetChi2MIP(0)<AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(0))
3230 chi2[itrack] = track->GetChi2MIP(0)-0*(track->GetNumberOfClusters()+track->GetNDeadZone());
3233 if (track->GetConstrain() || track->GetNumberOfClusters()>5){ //keep best short tracks - without vertex constrain
3234 delete array->RemoveAt(itrack);
3239 entries = array->GetEntriesFast();
3243 TObjArray * newarray = new TObjArray();
3244 TMath::Sort(entries,chi2,index,kFALSE);
3245 besttrack = (AliITStrackMI*)array->At(index[0]);
3248 for (Int_t j=0;j<6;j++){
3249 if (besttrack->GetNz(j)>0&&besttrack->GetNy(j)>0){
3250 erry[j] = besttrack->GetSigmaY(j); erry[j+6] = besttrack->GetSigmaY(j+6);
3251 errz[j] = besttrack->GetSigmaZ(j); errz[j+6] = besttrack->GetSigmaZ(j+6);
3252 ny[j] = besttrack->GetNy(j);
3253 nz[j] = besttrack->GetNz(j);
3256 besttrack->SetChi2MIP(0,GetNormalizedChi2(besttrack,mode));
3257 minchi2 = TMath::Min(besttrack->GetChi2MIP(0)+5.+besttrack->GetNUsed(), double(AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(0)));
3258 Float_t minn = besttrack->GetNumberOfClusters()-3;
3260 for (Int_t i=0;i<entries;i++){
3261 AliITStrackMI * track = (AliITStrackMI*)array->At(index[i]);
3262 if (!track) continue;
3263 if (accepted>maxcut) break;
3264 track->SetChi2MIP(0,GetNormalizedChi2(track,mode));
3265 if (track->GetConstrain() || track->GetNumberOfClusters()>5){ //keep best short tracks - without vertex constrain
3266 if (track->GetNumberOfClusters()<6 && (track->GetChi2MIP(0)+track->GetNUsed()>minchi2)){
3267 delete array->RemoveAt(index[i]);
3271 Bool_t shortbest = !track->GetConstrain() && track->GetNumberOfClusters()<6;
3272 if ((track->GetChi2MIP(0)+track->GetNUsed()<minchi2 && track->GetNumberOfClusters()>=minn) ||shortbest){
3273 if (!shortbest) accepted++;
3275 newarray->AddLast(array->RemoveAt(index[i]));
3276 for (Int_t j=0;j<6;j++){
3278 erry[j] = track->GetSigmaY(j); erry[j+6] = track->GetSigmaY(j+6);
3279 errz[j] = track->GetSigmaZ(j); errz[j] = track->GetSigmaZ(j+6);
3280 ny[j] = track->GetNy(j);
3281 nz[j] = track->GetNz(j);
3286 delete array->RemoveAt(index[i]);
3290 delete fTrackHypothesys.RemoveAt(esdindex);
3291 fTrackHypothesys.AddAt(newarray,esdindex);
3295 delete fTrackHypothesys.RemoveAt(esdindex);
3301 //------------------------------------------------------------------------
3302 AliITStrackMI * AliITStrackerMI::GetBestHypothesys(Int_t esdindex, AliITStrackMI * original, Int_t checkmax)
3304 //-------------------------------------------------------------
3305 // try to find best hypothesy
3306 // currently - minimal chi2 of track+backpropagated track+matching to the tpc track
3307 //-------------------------------------------------------------
3308 if (fTrackHypothesys.GetEntriesFast()<=esdindex) return 0;
3309 TObjArray * array = (TObjArray*) fTrackHypothesys.At(esdindex);
3310 if (!array) return 0;
3311 Int_t entries = array->GetEntriesFast();
3312 if (!entries) return 0;
3313 Float_t minchi2 = 100000;
3314 AliITStrackMI * besttrack=0;
3316 AliITStrackMI * backtrack = new AliITStrackMI(*original);
3317 AliITStrackMI * forwardtrack = new AliITStrackMI(*original);
3318 Double_t xyzVtx[]={GetX(),GetY(),GetZ()};
3319 Double_t ersVtx[]={GetSigmaX()/3.,GetSigmaY()/3.,GetSigmaZ()/3.};
3321 for (Int_t i=0;i<entries;i++){
3322 AliITStrackMI * track = (AliITStrackMI*)array->At(i);
3323 if (!track) continue;
3324 Float_t sigmarfi,sigmaz;
3325 GetDCASigma(track,sigmarfi,sigmaz);
3326 track->SetDnorm(0,sigmarfi);
3327 track->SetDnorm(1,sigmaz);
3329 track->SetChi2MIP(1,1000000);
3330 track->SetChi2MIP(2,1000000);
3331 track->SetChi2MIP(3,1000000);
3334 backtrack = new(backtrack) AliITStrackMI(*track);
3335 if (track->GetConstrain()) {
3336 if (!CorrectForPipeMaterial(backtrack,"inward")) continue;
3337 if (!backtrack->Improve(0,xyzVtx,ersVtx)) continue;
3338 backtrack->ResetCovariance(10.);
3340 backtrack->ResetCovariance(10.);
3342 backtrack->ResetClusters();
3344 Double_t x = original->GetX();
3345 if (!RefitAt(x,backtrack,track)) continue;
3347 track->SetChi2MIP(1,NormalizedChi2(backtrack,0));
3348 //for (Int_t i=2;i<6;i++){track->fDy[i]+=backtrack->fDy[i]; track->fDz[i]+=backtrack->fDz[i];}
3349 if (track->GetChi2MIP(1)>AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(1)*6.) continue;
3350 track->SetChi22(GetMatchingChi2(backtrack,original));
3352 if ((track->GetConstrain()) && track->GetChi22()>90.) continue;
3353 if ((!track->GetConstrain()) && track->GetChi22()>30.) continue;
3354 if ( track->GetChi22()/track->GetNumberOfClusters()>11.) continue;
3357 if (!(track->GetConstrain())&&track->GetChi2MIP(1)>AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(1)) continue;
3359 //forward track - without constraint
3360 forwardtrack = new(forwardtrack) AliITStrackMI(*original);
3361 forwardtrack->ResetClusters();
3363 RefitAt(x,forwardtrack,track);
3364 track->SetChi2MIP(2,NormalizedChi2(forwardtrack,0));
3365 if (track->GetChi2MIP(2)>AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(2)*6.0) continue;
3366 if (!(track->GetConstrain())&&track->GetChi2MIP(2)>AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(2)) continue;
3368 //track->fD[0] = forwardtrack->GetD(GetX(),GetY());
3369 //track->fD[1] = forwardtrack->GetZat(GetX())-GetZ();
3370 forwardtrack->GetDZ(GetX(),GetY(),GetZ(),track->GetDP()); //I.B.
3371 forwardtrack->SetD(0,track->GetD(0));
3372 forwardtrack->SetD(1,track->GetD(1));
3375 AliITSRecPoint* clist[6];
3376 track->SetChi2MIP(4,GetNumberOfSharedClusters(track,esdindex,list,clist));
3377 if ( (!track->GetConstrain()) && track->GetChi2MIP(4)>1.0) continue;
3380 track->SetChi2MIP(3,GetInterpolatedChi2(forwardtrack,backtrack));
3381 if ( (track->GetChi2MIP(3)>6.*AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(3))) continue;
3382 if ( (!track->GetConstrain()) && (track->GetChi2MIP(3)>2*AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(3))) {
3383 track->SetChi2MIP(3,1000);
3386 Double_t chi2 = track->GetChi2MIP(0)+track->GetNUsed();
3388 for (Int_t ichi=0;ichi<5;ichi++){
3389 forwardtrack->SetChi2MIP(ichi, track->GetChi2MIP(ichi));
3391 if (chi2 < minchi2){
3392 //besttrack = new AliITStrackMI(*forwardtrack);
3394 besttrack->SetLabel(track->GetLabel());
3395 besttrack->SetFakeRatio(track->GetFakeRatio());
3397 //original->fD[0] = forwardtrack->GetD(GetX(),GetY());
3398 //original->fD[1] = forwardtrack->GetZat(GetX())-GetZ();
3399 forwardtrack->GetDZ(GetX(),GetY(),GetZ(),original->GetDP()); //I.B.
3403 delete forwardtrack;
3405 for (Int_t i=0;i<entries;i++){
3406 AliITStrackMI * track = (AliITStrackMI*)array->At(i);
3408 if (!track) continue;
3410 if (accepted>checkmax || track->GetChi2MIP(3)>AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(3)*6. ||
3411 (track->GetNumberOfClusters()<besttrack->GetNumberOfClusters()-1.)||
3412 track->GetChi2MIP(0)>besttrack->GetChi2MIP(0)+2.*besttrack->GetNUsed()+3.){
3413 if (track->GetConstrain() || track->GetNumberOfClusters()>5){ //keep best short tracks - without vertex constrain
3414 delete array->RemoveAt(i);
3424 SortTrackHypothesys(esdindex,checkmax,1);
3426 array = (TObjArray*) fTrackHypothesys.At(esdindex);
3427 if (!array) return 0; // PH What can be the reason? Check SortTrackHypothesys
3428 besttrack = (AliITStrackMI*)array->At(0);
3429 if (!besttrack) return 0;
3430 besttrack->SetChi2MIP(8,0);
3431 fBestTrackIndex[esdindex]=0;
3432 entries = array->GetEntriesFast();
3433 AliITStrackMI *longtrack =0;
3435 Float_t minn=besttrack->GetNumberOfClusters()+besttrack->GetNDeadZone();
3436 for (Int_t itrack=entries-1;itrack>0;itrack--) {
3437 AliITStrackMI * track = (AliITStrackMI*)array->At(itrack);
3438 if (!track->GetConstrain()) continue;
3439 if (track->GetNumberOfClusters()+track->GetNDeadZone()<minn) continue;
3440 if (track->GetChi2MIP(0)-besttrack->GetChi2MIP(0)>0.0) continue;
3441 if (track->GetChi2MIP(0)>4.) continue;
3442 minn = track->GetNumberOfClusters()+track->GetNDeadZone();
3445 //if (longtrack) besttrack=longtrack;
3448 AliITSRecPoint * clist[6];
3449 Float_t shared = GetNumberOfSharedClusters(besttrack,esdindex,list,clist);
3450 if (besttrack->GetConstrain()&&besttrack->GetChi2MIP(0)<AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(0)&&besttrack->GetChi2MIP(1)<AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(1)
3451 &&besttrack->GetChi2MIP(2)<AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(2)&&besttrack->GetChi2MIP(3)<AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(3)){
3452 RegisterClusterTracks(besttrack,esdindex);
3459 Int_t sharedtrack = GetOverlapTrack(besttrack, esdindex, nshared, list, overlist);
3460 if (sharedtrack>=0){
3462 besttrack = GetBest2Tracks(esdindex,sharedtrack,10,5.5);
3464 shared = GetNumberOfSharedClusters(besttrack,esdindex,list,clist);
3470 if (shared>2.5) return 0;
3471 if (shared>1.0) return besttrack;
3473 // Don't sign clusters if not gold track
3475 if (!besttrack->IsGoldPrimary()) return besttrack;
3476 if (besttrack->GetESDtrack()->GetKinkIndex(0)!=0) return besttrack; //track belong to kink
3478 if (fConstraint[fPass]){
3482 Float_t *ny = GetNy(esdindex), *nz = GetNz(esdindex);
3483 for (Int_t i=0;i<6;i++){
3484 Int_t index = besttrack->GetClIndex(i);
3485 if (index<0) continue;
3486 Int_t ilayer = (index & 0xf0000000) >> 28;
3487 if (besttrack->GetSigmaY(ilayer)<0.00000000001) continue;
3488 AliITSRecPoint *c = (AliITSRecPoint*)GetCluster(index);
3490 if (ilayer>3&&c->GetNy()+c->GetNz()>6) continue;
3491 if ( (c->GetNy()+c->GetNz() )> ny[i]+nz[i]+0.7) continue; //shared track
3492 if ( c->GetNz()> nz[i]+0.7) continue; //shared track
3493 if ( ilayer>2&& AliITSReconstructor::GetRecoParam()->GetUseAmplitudeInfo(ilayer))
3494 if (besttrack->GetNormQ(ilayer)/besttrack->GetExpQ()>1.5) continue;
3495 //if ( c->GetNy()> ny[i]+0.7) continue; //shared track
3497 Bool_t cansign = kTRUE;
3498 for (Int_t itrack=0;itrack<entries; itrack++){
3499 AliITStrackMI * track = (AliITStrackMI*)array->At(i);
3500 if (!track) continue;
3501 if (track->GetChi2MIP(0)>besttrack->GetChi2MIP(0)+2.*shared+1.) break;
3502 if ( (track->GetClIndex(ilayer)>=0) && (track->GetClIndex(ilayer)!=besttrack->GetClIndex(ilayer))){
3508 if (TMath::Abs(besttrack->GetDy(ilayer)/besttrack->GetSigmaY(ilayer))>3.) continue;
3509 if (TMath::Abs(besttrack->GetDz(ilayer)/besttrack->GetSigmaZ(ilayer))>3.) continue;
3510 if (!c->IsUsed()) c->Use();
3516 //------------------------------------------------------------------------
3517 void AliITStrackerMI::GetBestHypothesysMIP(TObjArray &itsTracks)
3520 // get "best" hypothesys
3523 Int_t nentries = itsTracks.GetEntriesFast();
3524 for (Int_t i=0;i<nentries;i++){
3525 AliITStrackMI* track = (AliITStrackMI*)itsTracks.At(i);
3526 if (!track) continue;
3527 TObjArray * array = (TObjArray*) fTrackHypothesys.At(i);
3528 if (!array) continue;
3529 if (array->GetEntriesFast()<=0) continue;
3531 AliITStrackMI* longtrack=0;
3533 Float_t maxchi2=1000;
3534 for (Int_t j=0;j<array->GetEntriesFast();j++){
3535 AliITStrackMI* trackHyp = (AliITStrackMI*)array->At(j);
3536 if (!trackHyp) continue;
3537 if (trackHyp->GetGoldV0()) {
3538 longtrack = trackHyp; //gold V0 track taken
3541 if (trackHyp->GetNumberOfClusters()+trackHyp->GetNDeadZone()<minn) continue;
3542 Float_t chi2 = trackHyp->GetChi2MIP(0);
3544 if (!trackHyp->GetGoldV0()&&trackHyp->GetConstrain()==kFALSE) chi2+=5;
3546 if (trackHyp->GetNumberOfClusters()+trackHyp->GetNDeadZone()>minn) maxchi2 = trackHyp->GetChi2MIP(0);
3548 if (chi2 > maxchi2) continue;
3549 minn= trackHyp->GetNumberOfClusters()+trackHyp->GetNDeadZone();
3556 AliITStrackMI * besttrack = (AliITStrackMI*)array->At(0);
3557 if (!longtrack) {longtrack = besttrack;}
3558 else besttrack= longtrack;
3562 AliITSRecPoint * clist[6];
3563 Float_t shared = GetNumberOfSharedClusters(longtrack,i,list,clist);
3565 track->SetNUsed(shared);
3566 track->SetNSkipped(besttrack->GetNSkipped());
3567 track->SetChi2MIP(0,besttrack->GetChi2MIP(0));
3569 if(!AliITSReconstructor::GetRecoParam()->GetAllowSharedClusters()) continue;
3573 Int_t sharedtrack = GetOverlapTrack(longtrack, i, nshared, list, overlist);
3574 //if (sharedtrack==-1) sharedtrack=0;
3575 if (sharedtrack>=0) {
3576 besttrack = GetBest2Tracks(i,sharedtrack,10,5.5);
3579 if (besttrack&&fAfterV0) {
3580 UpdateESDtrack(besttrack,AliESDtrack::kITSin);
3582 if (besttrack&&fConstraint[fPass])
3583 UpdateESDtrack(besttrack,AliESDtrack::kITSin);
3584 if (besttrack->GetChi2MIP(0)+besttrack->GetNUsed()>1.5 && fConstraint[fPass]) {
3585 if ( TMath::Abs(besttrack->GetD(0))>0.1 ||
3586 TMath::Abs(besttrack->GetD(1))>0.1 ) track->SetReconstructed(kFALSE);
3592 //------------------------------------------------------------------------
3593 void AliITStrackerMI::CookLabel(AliITStrackMI *track,Float_t wrong) const {
3594 //--------------------------------------------------------------------
3595 //This function "cooks" a track label. If label<0, this track is fake.
3596 //--------------------------------------------------------------------
3599 if ( track->GetESDtrack()) tpcLabel = TMath::Abs(track->GetESDtrack()->GetTPCLabel());
3601 track->SetChi2MIP(9,0);
3603 for (Int_t i=0;i<track->GetNumberOfClusters();i++){
3604 Int_t cindex = track->GetClusterIndex(i);
3605 Int_t l=(cindex & 0xf0000000) >> 28;
3606 AliITSRecPoint *cl = (AliITSRecPoint*)GetCluster(cindex);
3608 for (Int_t ind=0;ind<3;ind++){
3610 if (cl->GetLabel(ind)==tpcLabel) isWrong=0;
3611 AliDebug(2,Form("icl %d ilab %d lab %d",i,ind,cl->GetLabel(ind)));
3613 track->SetChi2MIP(9,track->GetChi2MIP(9)+isWrong*(2<<l));
3616 Int_t nclusters = track->GetNumberOfClusters();
3617 if (nclusters > 0) //PH Some tracks don't have any cluster
3618 track->SetFakeRatio(double(nwrong)/double(nclusters));
3620 if (track->GetFakeRatio()>wrong) track->SetLabel(-tpcLabel);
3622 track->SetLabel(tpcLabel);
3624 AliDebug(2,Form(" nls %d wrong %d label %d tpcLabel %d\n",nclusters,nwrong,track->GetLabel(),tpcLabel));
3627 //------------------------------------------------------------------------
3628 void AliITStrackerMI::CookdEdx(AliITStrackMI* track)
3631 track->SetChi2MIP(9,0);
3632 for (Int_t i=0;i<track->GetNumberOfClusters();i++){
3633 Int_t cindex = track->GetClusterIndex(i);
3634 Int_t l=(cindex & 0xf0000000) >> 28;
3635 AliITSRecPoint *cl = (AliITSRecPoint*)GetCluster(cindex);
3636 Int_t lab = TMath::Abs(track->GetESDtrack()->GetTPCLabel());
3638 for (Int_t ind=0;ind<3;ind++){
3639 if (cl->GetLabel(ind)==lab) isWrong=0;
3641 track->SetChi2MIP(9,track->GetChi2MIP(9)+isWrong*(2<<l));
3645 track->CookdEdx(low,up);
3647 //------------------------------------------------------------------------
3648 void AliITStrackerMI::MakeCoefficients(Int_t ntracks){
3650 // Create some arrays
3652 if (fCoefficients) delete []fCoefficients;
3653 fCoefficients = new Float_t[ntracks*48];
3654 for (Int_t i=0;i<ntracks*48;i++) fCoefficients[i]=-1.;
3656 //------------------------------------------------------------------------
3657 Double_t AliITStrackerMI::GetPredictedChi2MI(AliITStrackMI* track, const AliITSRecPoint *cluster,Int_t layer)
3660 // Compute predicted chi2
3662 Float_t erry,errz,covyz;
3663 Float_t theta = track->GetTgl();
3664 Float_t phi = track->GetSnp();
3665 phi = TMath::Abs(phi)*TMath::Sqrt(1./((1.-phi)*(1.+phi)));
3666 AliITSClusterParam::GetError(layer,cluster,theta,phi,track->GetExpQ(),erry,errz,covyz);
3667 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()));
3668 // Take into account the mis-alignment (bring track to cluster plane)
3669 Double_t xTrOrig=track->GetX();
3670 if (!track->Propagate(xTrOrig+cluster->GetX())) return 1000.;
3671 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()));
3672 Double_t chi2 = track->GetPredictedChi2MI(cluster->GetY(),cluster->GetZ(),erry,errz,covyz);
3673 // Bring the track back to detector plane in ideal geometry
3674 // [mis-alignment will be accounted for in UpdateMI()]
3675 if (!track->Propagate(xTrOrig)) return 1000.;
3677 AliITSClusterParam::GetNTeor(layer,cluster,theta,phi,ny,nz);
3678 Double_t delta = cluster->GetNy()+cluster->GetNz()-nz-ny;
3680 chi2+=0.5*TMath::Min(delta/2,2.);
3681 chi2+=2.*cluster->GetDeltaProbability();
3684 track->SetNy(layer,ny);
3685 track->SetNz(layer,nz);
3686 track->SetSigmaY(layer,erry);
3687 track->SetSigmaZ(layer, errz);
3688 track->SetSigmaYZ(layer,covyz);
3689 //track->fNormQ[layer] = cluster->GetQ()/TMath::Sqrt(1+theta*theta+phi*phi);
3690 track->SetNormQ(layer,cluster->GetQ()/TMath::Sqrt((1.+ track->GetTgl()*track->GetTgl())/((1.-track->GetSnp())*(1.+track->GetSnp()))));
3694 //------------------------------------------------------------------------
3695 Int_t AliITStrackerMI::UpdateMI(AliITStrackMI* track, const AliITSRecPoint* cl,Double_t chi2,Int_t index) const
3700 Int_t layer = (index & 0xf0000000) >> 28;
3701 track->SetClIndex(layer, index);
3702 if (layer>1&&AliITSReconstructor::GetRecoParam()->GetUseAmplitudeInfo(layer)) {
3703 if (track->GetNormQ(layer)/track->GetExpQ()<0.5 ) {
3704 chi2+= (0.5-track->GetNormQ(layer)/track->GetExpQ())*10.;
3705 track->SetdEdxMismatch(track->GetdEdxMismatch()+(0.5-track->GetNormQ(layer)/track->GetExpQ())*10.);
3709 if (cl->GetQ()<=0) return 0; // ingore the "virtual" clusters
3712 // Take into account the mis-alignment (bring track to cluster plane)
3713 Double_t xTrOrig=track->GetX();
3714 Float_t clxyz[3]; cl->GetGlobalXYZ(clxyz);Double_t trxyz[3]; track->GetXYZ(trxyz);
3715 AliDebug(2,Form("gtr %f %f %f",trxyz[0],trxyz[1],trxyz[2]));
3716 AliDebug(2,Form("gcl %f %f %f",clxyz[0],clxyz[1],clxyz[2]));
3717 AliDebug(2,Form(" xtr %f xcl %f",track->GetX(),cl->GetX()));
3719 if (!track->Propagate(xTrOrig+cl->GetX())) return 0;
3722 c.SetSigmaY2(track->GetSigmaY(layer)*track->GetSigmaY(layer));
3723 c.SetSigmaZ2(track->GetSigmaZ(layer)*track->GetSigmaZ(layer));
3724 c.SetSigmaYZ(track->GetSigmaYZ(layer));
3727 Int_t updated = track->UpdateMI(&c,chi2,index);
3728 // Bring the track back to detector plane in ideal geometry
3729 if (!track->Propagate(xTrOrig)) return 0;
3731 if(!updated) AliDebug(2,"update failed");
3735 //------------------------------------------------------------------------
3736 void AliITStrackerMI::GetDCASigma(const AliITStrackMI* track, Float_t & sigmarfi, Float_t &sigmaz)
3739 //DCA sigmas parameterization
3740 //to be paramterized using external parameters in future
3743 sigmarfi = 0.0040+1.4 *TMath::Abs(track->GetC())+332.*track->GetC()*track->GetC();
3744 sigmaz = 0.0110+4.37*TMath::Abs(track->GetC());
3746 //------------------------------------------------------------------------
3747 void AliITStrackerMI::SignDeltas(const TObjArray *clusterArray, Float_t vz)
3750 // Clusters from delta electrons?
3752 Int_t entries = clusterArray->GetEntriesFast();
3753 if (entries<4) return;
3754 AliITSRecPoint* cluster = (AliITSRecPoint*)clusterArray->At(0);
3755 Int_t layer = cluster->GetLayer();
3756 if (layer>1) return;
3758 Int_t ncandidates=0;
3759 Float_t r = (layer>0)? 7:4;
3761 for (Int_t i=0;i<entries;i++){
3762 AliITSRecPoint* cl0 = (AliITSRecPoint*)clusterArray->At(i);
3763 Float_t nz = 1+TMath::Abs((cl0->GetZ()-vz)/r);
3764 if (cl0->GetNy()+cl0->GetNz()<=5+2*layer+nz) continue;
3765 index[ncandidates] = i; //candidate to belong to delta electron track
3767 if (cl0->GetNy()+cl0->GetNz()>9+2*layer+nz) {
3768 cl0->SetDeltaProbability(1);
3774 for (Int_t i=0;i<ncandidates;i++){
3775 AliITSRecPoint* cl0 = (AliITSRecPoint*)clusterArray->At(index[i]);
3776 if (cl0->GetDeltaProbability()>0.8) continue;
3779 Float_t y[100],z[100],sumy,sumz,sumy2, sumyz, sumw;
3780 sumy=sumz=sumy2=sumyz=sumw=0.0;
3781 for (Int_t j=0;j<ncandidates;j++){
3783 AliITSRecPoint* cl1 = (AliITSRecPoint*)clusterArray->At(index[j]);
3785 Float_t dz = cl0->GetZ()-cl1->GetZ();
3786 Float_t dy = cl0->GetY()-cl1->GetY();
3787 if (TMath::Sqrt(dz*dz+dy*dy)<0.2){
3788 Float_t weight = cl1->GetNy()+cl1->GetNz()-2;
3789 y[ncl] = cl1->GetY();
3790 z[ncl] = cl1->GetZ();
3791 sumy+= y[ncl]*weight;
3792 sumz+= z[ncl]*weight;
3793 sumy2+=y[ncl]*y[ncl]*weight;
3794 sumyz+=y[ncl]*z[ncl]*weight;
3799 if (ncl<4) continue;
3800 Float_t det = sumw*sumy2 - sumy*sumy;
3802 if (TMath::Abs(det)>0.01){
3803 Float_t z0 = (sumy2*sumz - sumy*sumyz)/det;
3804 Float_t k = (sumyz*sumw - sumy*sumz)/det;
3805 delta = TMath::Abs(cl0->GetZ()-(z0+k*cl0->GetY()));
3808 Float_t z0 = sumyz/sumy;
3809 delta = TMath::Abs(cl0->GetZ()-z0);
3812 cl0->SetDeltaProbability(1-20.*delta);
3816 //------------------------------------------------------------------------
3817 void AliITStrackerMI::UpdateESDtrack(AliITStrackMI* track, ULong_t flags) const
3822 track->UpdateESDtrack(flags);
3823 AliITStrackMI * oldtrack = (AliITStrackMI*)(track->GetESDtrack()->GetITStrack());
3824 if (oldtrack) delete oldtrack;
3825 track->GetESDtrack()->SetITStrack(new AliITStrackMI(*track));
3826 if (TMath::Abs(track->GetDnorm(1))<0.000000001){
3827 printf("Problem\n");
3830 //------------------------------------------------------------------------
3831 Int_t AliITStrackerMI::GetNearestLayer(const Double_t *xr) const{
3833 // Get nearest upper layer close to the point xr.
3834 // rough approximation
3836 const Float_t kRadiuses[6]={4,6.5,15.03,24.,38.5,43.7};
3837 Float_t radius = TMath::Sqrt(xr[0]*xr[0]+xr[1]*xr[1]);
3839 for (Int_t i=0;i<6;i++){
3840 if (radius<kRadiuses[i]){
3847 //------------------------------------------------------------------------
3848 void AliITStrackerMI::BuildMaterialLUT(TString material) {
3849 //--------------------------------------------------------------------
3850 // Fill a look-up table with mean material
3851 //--------------------------------------------------------------------
3855 Double_t point1[3],point2[3];
3856 Double_t phi,cosphi,sinphi,z;
3857 // 0-5 layers, 6 pipe, 7-8 shields
3858 Double_t rmin[9]={ 3.5, 5.5,13.0,22.0,35.0,41.0, 2.0, 8.0,25.0};
3859 Double_t rmax[9]={ 5.5, 8.0,17.0,26.0,41.0,47.0, 3.0,10.5,30.0};
3861 Int_t ifirst=0,ilast=0;
3862 if(material.Contains("Pipe")) {
3864 } else if(material.Contains("Shields")) {
3866 } else if(material.Contains("Layers")) {
3869 Error("BuildMaterialLUT","Wrong layer name\n");
3872 for(Int_t imat=ifirst; imat<=ilast; imat++) {
3873 Double_t param[5]={0.,0.,0.,0.,0.};
3874 for (Int_t i=0; i<n; i++) {
3875 phi = 2.*TMath::Pi()*gRandom->Rndm();
3876 cosphi = TMath::Cos(phi); sinphi = TMath::Sin(phi);
3877 z = 14.*(-1.+2.*gRandom->Rndm()); // SPD barrel
3878 point1[0] = rmin[imat]*cosphi;
3879 point1[1] = rmin[imat]*sinphi;
3881 point2[0] = rmax[imat]*cosphi;
3882 point2[1] = rmax[imat]*sinphi;
3884 AliTracker::MeanMaterialBudget(point1,point2,mparam);
3885 for(Int_t j=0;j<5;j++) param[j]+=mparam[j];
3887 for(Int_t j=0;j<5;j++) param[j]/=(Float_t)n;
3889 fxOverX0Layer[imat] = param[1];
3890 fxTimesRhoLayer[imat] = param[0]*param[4];
3891 } else if(imat==6) {
3892 fxOverX0Pipe = param[1];
3893 fxTimesRhoPipe = param[0]*param[4];
3894 } else if(imat==7) {
3895 fxOverX0Shield[0] = param[1];
3896 fxTimesRhoShield[0] = param[0]*param[4];
3897 } else if(imat==8) {
3898 fxOverX0Shield[1] = param[1];
3899 fxTimesRhoShield[1] = param[0]*param[4];
3903 printf("%s\n",material.Data());
3904 printf("%f %f\n",fxOverX0Pipe,fxTimesRhoPipe);
3905 printf("%f %f\n",fxOverX0Shield[0],fxTimesRhoShield[0]);
3906 printf("%f %f\n",fxOverX0Shield[1],fxTimesRhoShield[1]);
3907 printf("%f %f\n",fxOverX0Layer[0],fxTimesRhoLayer[0]);
3908 printf("%f %f\n",fxOverX0Layer[1],fxTimesRhoLayer[1]);
3909 printf("%f %f\n",fxOverX0Layer[2],fxTimesRhoLayer[2]);
3910 printf("%f %f\n",fxOverX0Layer[3],fxTimesRhoLayer[3]);
3911 printf("%f %f\n",fxOverX0Layer[4],fxTimesRhoLayer[4]);
3912 printf("%f %f\n",fxOverX0Layer[5],fxTimesRhoLayer[5]);
3916 //------------------------------------------------------------------------
3917 Int_t AliITStrackerMI::CorrectForPipeMaterial(AliITStrackMI *t,
3918 TString direction) {
3919 //-------------------------------------------------------------------
3920 // Propagate beyond beam pipe and correct for material
3921 // (material budget in different ways according to fUseTGeo value)
3922 // Add time if going outward (PropagateTo or PropagateToTGeo)
3923 //-------------------------------------------------------------------
3925 // Define budget mode:
3926 // 0: material from AliITSRecoParam (hard coded)
3927 // 1: material from TGeo in one step (on the fly)
3928 // 2: material from lut
3929 // 3: material from TGeo in one step (same for all hypotheses)
3942 if(fTrackingPhase.Contains("Clusters2Tracks"))
3943 { mode=3; } else { mode=1; }
3946 if(fTrackingPhase.Contains("Clusters2Tracks"))
3947 { mode=3; } else { mode=2; }
3953 if(fTrackingPhase.Contains("Default")) mode=0;
3955 Int_t index=fCurrentEsdTrack;
3957 Float_t dir = (direction.Contains("inward") ? 1. : -1.);
3958 Double_t rToGo=(dir>0 ? AliITSRecoParam::GetrInsidePipe() : AliITSRecoParam::GetrOutsidePipe());
3960 if (!t->GetLocalXat(rToGo,xToGo)) return 0;
3962 Double_t xOverX0,x0,lengthTimesMeanDensity;
3966 xOverX0 = AliITSRecoParam::GetdPipe();
3967 x0 = AliITSRecoParam::GetX0Be();
3968 lengthTimesMeanDensity = xOverX0*x0;
3969 lengthTimesMeanDensity *= dir;
3970 if (!t->PropagateTo(xToGo,xOverX0,lengthTimesMeanDensity/xOverX0)) return 0;
3973 if (!t->PropagateToTGeo(xToGo,1)) return 0;
3976 if(fxOverX0Pipe<0) BuildMaterialLUT("Pipe");
3977 xOverX0 = fxOverX0Pipe;
3978 lengthTimesMeanDensity = fxTimesRhoPipe;
3979 lengthTimesMeanDensity *= dir;
3980 if (!t->PropagateTo(xToGo,xOverX0,lengthTimesMeanDensity/xOverX0)) return 0;
3983 if(!fxOverX0PipeTrks || index<0 || index>=fNtracks) Error("CorrectForPipeMaterial","Incorrect usage of UseTGeo option!\n");
3984 if(fxOverX0PipeTrks[index]<0) {
3985 if (!t->PropagateToTGeo(xToGo,1,xOverX0,lengthTimesMeanDensity)) return 0;
3986 Double_t angle=TMath::Sqrt((1.+t->GetTgl()*t->GetTgl())/
3987 ((1.-t->GetSnp())*(1.+t->GetSnp())));
3988 fxOverX0PipeTrks[index] = TMath::Abs(xOverX0)/angle;
3989 fxTimesRhoPipeTrks[index] = TMath::Abs(lengthTimesMeanDensity)/angle;
3992 xOverX0 = fxOverX0PipeTrks[index];
3993 lengthTimesMeanDensity = fxTimesRhoPipeTrks[index];
3994 lengthTimesMeanDensity *= dir;
3995 if (!t->PropagateTo(xToGo,xOverX0,lengthTimesMeanDensity/xOverX0)) return 0;
4001 //------------------------------------------------------------------------
4002 Int_t AliITStrackerMI::CorrectForShieldMaterial(AliITStrackMI *t,
4004 TString direction) {
4005 //-------------------------------------------------------------------
4006 // Propagate beyond SPD or SDD shield and correct for material
4007 // (material budget in different ways according to fUseTGeo value)
4008 // Add time if going outward (PropagateTo or PropagateToTGeo)
4009 //-------------------------------------------------------------------
4011 // Define budget mode:
4012 // 0: material from AliITSRecoParam (hard coded)
4013 // 1: material from TGeo in steps of X cm (on the fly)
4014 // X = AliITSRecoParam::GetStepSizeTGeo()
4015 // 2: material from lut
4016 // 3: material from TGeo in one step (same for all hypotheses)
4029 if(fTrackingPhase.Contains("Clusters2Tracks"))
4030 { mode=3; } else { mode=1; }
4033 if(fTrackingPhase.Contains("Clusters2Tracks"))
4034 { mode=3; } else { mode=2; }
4040 if(fTrackingPhase.Contains("Default")) mode=0;
4042 Float_t dir = (direction.Contains("inward") ? 1. : -1.);
4044 Int_t shieldindex=0;
4045 if (shield.Contains("SDD")) { // SDDouter
4046 rToGo=(dir>0 ? AliITSRecoParam::GetrInsideShield(1) : AliITSRecoParam::GetrOutsideShield(1));
4048 } else if (shield.Contains("SPD")) { // SPDouter
4049 rToGo=(dir>0 ? AliITSRecoParam::GetrInsideShield(0) : AliITSRecoParam::GetrOutsideShield(0));
4052 Error("CorrectForShieldMaterial"," Wrong shield name\n");
4056 // do nothing if we are already beyond the shield
4057 Double_t rTrack = TMath::Sqrt(t->GetX()*t->GetX()+t->GetY()*t->GetY());
4058 if(dir<0 && rTrack > rToGo) return 1; // going outward
4059 if(dir>0 && rTrack < rToGo) return 1; // going inward
4063 if (!t->GetLocalXat(rToGo,xToGo)) return 0;
4065 Int_t index=2*fCurrentEsdTrack+shieldindex;
4067 Double_t xOverX0,x0,lengthTimesMeanDensity;
4072 xOverX0 = AliITSRecoParam::Getdshield(shieldindex);
4073 x0 = AliITSRecoParam::GetX0shield(shieldindex);
4074 lengthTimesMeanDensity = xOverX0*x0;
4075 lengthTimesMeanDensity *= dir;
4076 if (!t->PropagateTo(xToGo,xOverX0,lengthTimesMeanDensity/xOverX0)) return 0;
4079 nsteps= (Int_t)(TMath::Abs(t->GetX()-xToGo)/AliITSReconstructor::GetRecoParam()->GetStepSizeTGeo())+1;
4080 if (!t->PropagateToTGeo(xToGo,nsteps)) return 0; // cross the material and apply correction
4083 if(fxOverX0Shield[shieldindex]<0) BuildMaterialLUT("Shields");
4084 xOverX0 = fxOverX0Shield[shieldindex];
4085 lengthTimesMeanDensity = fxTimesRhoShield[shieldindex];
4086 lengthTimesMeanDensity *= dir;
4087 if (!t->PropagateTo(xToGo,xOverX0,lengthTimesMeanDensity/xOverX0)) return 0;
4090 if(!fxOverX0ShieldTrks || index<0 || index>=2*fNtracks) Error("CorrectForShieldMaterial","Incorrect usage of UseTGeo option!\n");
4091 if(fxOverX0ShieldTrks[index]<0) {
4092 if (!t->PropagateToTGeo(xToGo,1,xOverX0,lengthTimesMeanDensity)) return 0;
4093 Double_t angle=TMath::Sqrt((1.+t->GetTgl()*t->GetTgl())/
4094 ((1.-t->GetSnp())*(1.+t->GetSnp())));
4095 fxOverX0ShieldTrks[index] = TMath::Abs(xOverX0)/angle;
4096 fxTimesRhoShieldTrks[index] = TMath::Abs(lengthTimesMeanDensity)/angle;
4099 xOverX0 = fxOverX0ShieldTrks[index];
4100 lengthTimesMeanDensity = fxTimesRhoShieldTrks[index];
4101 lengthTimesMeanDensity *= dir;
4102 if (!t->PropagateTo(xToGo,xOverX0,lengthTimesMeanDensity/xOverX0)) return 0;
4108 //------------------------------------------------------------------------
4109 Int_t AliITStrackerMI::CorrectForLayerMaterial(AliITStrackMI *t,
4111 Double_t oldGlobXYZ[3],
4112 TString direction) {
4113 //-------------------------------------------------------------------
4114 // Propagate beyond layer and correct for material
4115 // (material budget in different ways according to fUseTGeo value)
4116 // Add time if going outward (PropagateTo or PropagateToTGeo)
4117 //-------------------------------------------------------------------
4119 // Define budget mode:
4120 // 0: material from AliITSRecoParam (hard coded)
4121 // 1: material from TGeo in stepsof X cm (on the fly)
4122 // X = AliITSRecoParam::GetStepSizeTGeo()
4123 // 2: material from lut
4124 // 3: material from TGeo in one step (same for all hypotheses)
4137 if(fTrackingPhase.Contains("Clusters2Tracks"))
4138 { mode=3; } else { mode=1; }
4141 if(fTrackingPhase.Contains("Clusters2Tracks"))
4142 { mode=3; } else { mode=2; }
4148 if(fTrackingPhase.Contains("Default")) mode=0;
4150 Float_t dir = (direction.Contains("inward") ? 1. : -1.);
4152 Double_t r=fgLayers[layerindex].GetR();
4153 Double_t deltar=(layerindex<2 ? 0.10*r : 0.05*r);
4155 Double_t rToGo=TMath::Sqrt(t->GetX()*t->GetX()+t->GetY()*t->GetY())-deltar*dir;
4157 if (!t->GetLocalXat(rToGo,xToGo)) return 0;
4159 Int_t index=6*fCurrentEsdTrack+layerindex;
4162 Double_t xOverX0=0.0,x0=0.0,lengthTimesMeanDensity=0.0;
4165 // back before material (no correction)
4167 rOld=TMath::Sqrt(oldGlobXYZ[0]*oldGlobXYZ[0]+oldGlobXYZ[1]*oldGlobXYZ[1]);
4168 if (!t->GetLocalXat(rOld,xOld)) return 0;
4169 if (!t->Propagate(xOld)) return 0;
4173 xOverX0 = fgLayers[layerindex].GetThickness(t->GetY(),t->GetZ(),x0);
4174 lengthTimesMeanDensity = xOverX0*x0;
4175 lengthTimesMeanDensity *= dir;
4176 // Bring the track beyond the material
4177 if (!t->PropagateTo(xToGo,xOverX0,lengthTimesMeanDensity/xOverX0)) return 0;
4180 nsteps = (Int_t)(TMath::Abs(xOld-xToGo)/AliITSReconstructor::GetRecoParam()->GetStepSizeTGeo())+1;
4181 if (!t->PropagateToTGeo(xToGo,nsteps)) return 0; // cross the material and apply correction
4184 if(fxOverX0Layer[layerindex]<0) BuildMaterialLUT("Layers");
4185 xOverX0 = fxOverX0Layer[layerindex];
4186 lengthTimesMeanDensity = fxTimesRhoLayer[layerindex];
4187 lengthTimesMeanDensity *= dir;
4188 // Bring the track beyond the material
4189 if (!t->PropagateTo(xToGo,xOverX0,lengthTimesMeanDensity/xOverX0)) return 0;
4192 if(!fxOverX0LayerTrks || index<0 || index>=6*fNtracks) Error("CorrectForLayerMaterial","Incorrect usage of UseTGeo option!\n");
4193 if(fxOverX0LayerTrks[index]<0) {
4194 nsteps = (Int_t)(TMath::Abs(xOld-xToGo)/AliITSReconstructor::GetRecoParam()->GetStepSizeTGeo())+1;
4195 if (!t->PropagateToTGeo(xToGo,nsteps,xOverX0,lengthTimesMeanDensity)) return 0;
4196 Double_t angle=TMath::Sqrt((1.+t->GetTgl()*t->GetTgl())/
4197 ((1.-t->GetSnp())*(1.+t->GetSnp())));
4198 fxOverX0LayerTrks[index] = TMath::Abs(xOverX0)/angle;
4199 fxTimesRhoLayerTrks[index] = TMath::Abs(lengthTimesMeanDensity)/angle;
4202 xOverX0 = fxOverX0LayerTrks[index];
4203 lengthTimesMeanDensity = fxTimesRhoLayerTrks[index];
4204 lengthTimesMeanDensity *= dir;
4205 if (!t->PropagateTo(xToGo,xOverX0,lengthTimesMeanDensity/xOverX0)) return 0;
4212 //------------------------------------------------------------------------
4213 void AliITStrackerMI::MakeTrksMaterialLUT(Int_t ntracks) {
4214 //-----------------------------------------------------------------
4215 // Initialize LUT for storing material for each prolonged track
4216 //-----------------------------------------------------------------
4217 fxOverX0PipeTrks = new Float_t[ntracks];
4218 fxTimesRhoPipeTrks = new Float_t[ntracks];
4219 fxOverX0ShieldTrks = new Float_t[ntracks*2];
4220 fxTimesRhoShieldTrks = new Float_t[ntracks*2];
4221 fxOverX0LayerTrks = new Float_t[ntracks*6];
4222 fxTimesRhoLayerTrks = new Float_t[ntracks*6];
4224 for(Int_t i=0; i<ntracks; i++) {
4225 fxOverX0PipeTrks[i] = -1.;
4226 fxTimesRhoPipeTrks[i] = -1.;
4228 for(Int_t j=0; j<ntracks*2; j++) {
4229 fxOverX0ShieldTrks[j] = -1.;
4230 fxTimesRhoShieldTrks[j] = -1.;
4232 for(Int_t k=0; k<ntracks*6; k++) {
4233 fxOverX0LayerTrks[k] = -1.;
4234 fxTimesRhoLayerTrks[k] = -1.;
4241 //------------------------------------------------------------------------
4242 void AliITStrackerMI::DeleteTrksMaterialLUT() {
4243 //-----------------------------------------------------------------
4244 // Delete LUT for storing material for each prolonged track
4245 //-----------------------------------------------------------------
4246 if(fxOverX0PipeTrks) {
4247 delete [] fxOverX0PipeTrks; fxOverX0PipeTrks = 0;
4249 if(fxOverX0ShieldTrks) {
4250 delete [] fxOverX0ShieldTrks; fxOverX0ShieldTrks = 0;
4253 if(fxOverX0LayerTrks) {
4254 delete [] fxOverX0LayerTrks; fxOverX0LayerTrks = 0;
4256 if(fxTimesRhoPipeTrks) {
4257 delete [] fxTimesRhoPipeTrks; fxTimesRhoPipeTrks = 0;
4259 if(fxTimesRhoShieldTrks) {
4260 delete [] fxTimesRhoShieldTrks; fxTimesRhoShieldTrks = 0;
4262 if(fxTimesRhoLayerTrks) {
4263 delete [] fxTimesRhoLayerTrks; fxTimesRhoLayerTrks = 0;
4267 //------------------------------------------------------------------------
4268 void AliITStrackerMI::SetForceSkippingOfLayer() {
4269 //-----------------------------------------------------------------
4270 // Check if we are forced to skip layers
4271 // either we set to skip them in RecoParam
4272 // or they were off during data-taking
4273 //-----------------------------------------------------------------
4275 const AliEventInfo *eventInfo = GetEventInfo();
4277 for(Int_t l=0; l<AliITSgeomTGeo::kNLayers; l++) {
4278 fForceSkippingOfLayer[l] = 0;
4280 if(AliITSReconstructor::GetRecoParam()->GetLayersToSkip(l)) fForceSkippingOfLayer[l] = 1;
4284 AliDebug(2,Form("GetEventInfo->GetTriggerCluster: %s",eventInfo->GetTriggerCluster()));
4286 if(!strstr(eventInfo->GetTriggerCluster(),"ITSSPD")) fForceSkippingOfLayer[l] = 1;
4287 } else if(l==2 || l==3) {
4288 if(!strstr(eventInfo->GetTriggerCluster(),"ITSSDD")) fForceSkippingOfLayer[l] = 1;
4290 if(!strstr(eventInfo->GetTriggerCluster(),"ITSSSD")) fForceSkippingOfLayer[l] = 1;
4296 //------------------------------------------------------------------------
4297 Int_t AliITStrackerMI::CheckSkipLayer(const AliITStrackMI *track,
4298 Int_t ilayer,Int_t idet) const {
4299 //-----------------------------------------------------------------
4300 // This method is used to decide whether to allow a prolongation
4301 // without clusters, because we want to skip the layer.
4302 // In this case the return value is > 0:
4303 // return 1: the user requested to skip a layer
4304 // return 2: track outside z acceptance
4305 //-----------------------------------------------------------------
4307 if (ForceSkippingOfLayer(ilayer)) return 1;
4309 Int_t innerLayCanSkip=0; // was 2, changed on 05.11.2009
4311 if (idet<0 && // out in z
4312 ilayer>innerLayCanSkip &&
4313 AliITSReconstructor::GetRecoParam()->GetExtendedEtaAcceptance()) {
4314 // check if track will cross SPD outer layer
4315 Double_t phiAtSPD2,zAtSPD2;
4316 if (track->GetPhiZat(fgLayers[1].GetR(),phiAtSPD2,zAtSPD2)) {
4317 if (TMath::Abs(zAtSPD2)<2.*AliITSRecoParam::GetSPDdetzlength()) return 2;
4319 return 2; // always allow skipping, changed on 05.11.2009
4324 //------------------------------------------------------------------------
4325 Int_t AliITStrackerMI::CheckDeadZone(AliITStrackMI *track,
4326 Int_t ilayer,Int_t idet,
4327 Double_t dz,Double_t dy,
4328 Bool_t noClusters) const {
4329 //-----------------------------------------------------------------
4330 // This method is used to decide whether to allow a prolongation
4331 // without clusters, because there is a dead zone in the road.
4332 // In this case the return value is > 0:
4333 // return 1: dead zone at z=0,+-7cm in SPD
4334 // return 2: all road is "bad" (dead or noisy) from the OCDB
4335 // return 3: at least a chip is "bad" (dead or noisy) from the OCDB
4336 // return 4: at least a single channel is "bad" (dead or noisy) from the OCDB
4337 //-----------------------------------------------------------------
4339 // check dead zones at z=0,+-7cm in the SPD
4340 if (ilayer<2 && !AliITSReconstructor::GetRecoParam()->GetAddVirtualClustersInDeadZone()) {
4341 Double_t zmindead[3]={fSPDdetzcentre[0] + 0.5*AliITSRecoParam::GetSPDdetzlength(),
4342 fSPDdetzcentre[1] + 0.5*AliITSRecoParam::GetSPDdetzlength(),
4343 fSPDdetzcentre[2] + 0.5*AliITSRecoParam::GetSPDdetzlength()};
4344 Double_t zmaxdead[3]={fSPDdetzcentre[1] - 0.5*AliITSRecoParam::GetSPDdetzlength(),
4345 fSPDdetzcentre[2] - 0.5*AliITSRecoParam::GetSPDdetzlength(),
4346 fSPDdetzcentre[3] - 0.5*AliITSRecoParam::GetSPDdetzlength()};
4347 for (Int_t i=0; i<3; i++)
4348 if (track->GetZ()-dz<zmaxdead[i] && track->GetZ()+dz>zmindead[i]) {
4349 AliDebug(2,Form("crack SPD %d",ilayer));
4354 // check bad zones from OCDB
4355 if (!AliITSReconstructor::GetRecoParam()->GetUseBadZonesFromOCDB()) return 0;
4357 if (idet<0) return 0;
4359 AliITSdetector &det=fgLayers[ilayer].GetDetector(idet);
4362 Float_t detSizeFactorX=0.0001,detSizeFactorZ=0.0001;
4363 if (ilayer==0 || ilayer==1) { // ---------- SPD
4365 } else if (ilayer==2 || ilayer==3) { // ---------- SDD
4367 detSizeFactorX *= 2.;
4368 } else if (ilayer==4 || ilayer==5) { // ---------- SSD
4371 AliITSsegmentation *segm = (AliITSsegmentation*)fkDetTypeRec->GetSegmentationModel(detType);
4372 if (detType==2) segm->SetLayer(ilayer+1);
4373 Float_t detSizeX = detSizeFactorX*segm->Dx();
4374 Float_t detSizeZ = detSizeFactorZ*segm->Dz();
4376 // check if the road overlaps with bad chips
4378 LocalModuleCoord(ilayer,idet,track,xloc,zloc);
4379 Float_t zlocmin = zloc-dz;
4380 Float_t zlocmax = zloc+dz;
4381 Float_t xlocmin = xloc-dy;
4382 Float_t xlocmax = xloc+dy;
4383 Int_t chipsInRoad[100];
4385 // check if road goes out of detector
4386 Bool_t touchNeighbourDet=kFALSE;
4387 if (TMath::Abs(xlocmin)>0.5*detSizeX) {xlocmin=-0.4999*detSizeX; touchNeighbourDet=kTRUE;}
4388 if (TMath::Abs(xlocmax)>0.5*detSizeX) {xlocmax=+0.4999*detSizeX; touchNeighbourDet=kTRUE;}
4389 if (TMath::Abs(zlocmin)>0.5*detSizeZ) {zlocmin=-0.4999*detSizeZ; touchNeighbourDet=kTRUE;}
4390 if (TMath::Abs(zlocmax)>0.5*detSizeZ) {zlocmax=+0.4999*detSizeZ; touchNeighbourDet=kTRUE;}
4391 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));
4393 // check if this detector is bad
4395 AliDebug(2,Form("lay %d bad detector %d",ilayer,idet));
4396 if(!touchNeighbourDet) {
4397 return 2; // all detectors in road are bad
4399 return 3; // at least one is bad
4403 Int_t nChipsInRoad = segm->GetChipsInLocalWindow(chipsInRoad,zlocmin,zlocmax,xlocmin,xlocmax);
4404 AliDebug(2,Form("lay %d nChipsInRoad %d",ilayer,nChipsInRoad));
4405 if (!nChipsInRoad) return 0;
4407 Bool_t anyBad=kFALSE,anyGood=kFALSE;
4408 for (Int_t iCh=0; iCh<nChipsInRoad; iCh++) {
4409 if (chipsInRoad[iCh]<0 || chipsInRoad[iCh]>det.GetNChips()-1) continue;
4410 AliDebug(2,Form(" chip %d bad %d",chipsInRoad[iCh],(Int_t)det.IsChipBad(chipsInRoad[iCh])));
4411 if (det.IsChipBad(chipsInRoad[iCh])) {
4419 if(!touchNeighbourDet) {
4420 AliDebug(2,"all bad in road");
4421 return 2; // all chips in road are bad
4423 return 3; // at least a bad chip in road
4428 AliDebug(2,"at least a bad in road");
4429 return 3; // at least a bad chip in road
4433 if (!AliITSReconstructor::GetRecoParam()->GetUseSingleBadChannelsFromOCDB()
4434 || !noClusters) return 0;
4436 // There are no clusters in road: check if there is at least
4437 // a bad SPD pixel or SDD anode or SSD strips on both sides
4439 Int_t idetInITS=idet;
4440 for(Int_t l=0;l<ilayer;l++) idetInITS+=AliITSgeomTGeo::GetNLadders(l+1)*AliITSgeomTGeo::GetNDetectors(l+1);
4442 if (fITSChannelStatus->AnyBadInRoad(idetInITS,zlocmin,zlocmax,xlocmin,xlocmax)) {
4443 AliDebug(2,Form("Bad channel in det %d of layer %d\n",idet,ilayer));
4446 //if (fITSChannelStatus->FractionOfBadInRoad(idet,zlocmin,zlocmax,xlocmin,xlocmax) > AliITSReconstructor::GetRecoParam()->GetMinFractionOfBadInRoad()) return 3;
4450 //------------------------------------------------------------------------
4451 Bool_t AliITStrackerMI::LocalModuleCoord(Int_t ilayer,Int_t idet,
4452 const AliITStrackMI *track,
4453 Float_t &xloc,Float_t &zloc) const {
4454 //-----------------------------------------------------------------
4455 // Gives position of track in local module ref. frame
4456 //-----------------------------------------------------------------
4461 if(idet<0) return kTRUE; // track out of z acceptance of layer
4463 Int_t ndet=AliITSgeomTGeo::GetNDetectors(ilayer+1); // layers from 1 to 6
4465 Int_t lad = Int_t(idet/ndet) + 1;
4467 Int_t det = idet - (lad-1)*ndet + 1;
4469 Double_t xyzGlob[3],xyzLoc[3];
4471 AliITSdetector &detector = fgLayers[ilayer].GetDetector(idet);
4472 // take into account the misalignment: xyz at real detector plane
4473 if(!track->GetXYZAt(detector.GetRmisal(),GetBz(),xyzGlob)) return kFALSE;
4475 if(!AliITSgeomTGeo::GlobalToLocal(ilayer+1,lad,det,xyzGlob,xyzLoc)) return kFALSE;
4477 xloc = (Float_t)xyzLoc[0];
4478 zloc = (Float_t)xyzLoc[2];
4482 //------------------------------------------------------------------------
4483 Bool_t AliITStrackerMI::IsOKForPlaneEff(const AliITStrackMI* track, const Int_t *clusters, Int_t ilayer) const {
4485 // Method to be optimized further:
4486 // Aim: decide whether a track can be used for PlaneEff evaluation
4487 // the decision is taken based on the track quality at the layer under study
4488 // no information on the clusters on this layer has to be used
4489 // The criterium is to reject tracks at boundaries between basic block (e.g. SPD chip)
4490 // the cut is done on number of sigmas from the boundaries
4492 // Input: Actual track, layer [0,5] under study
4494 // Return: kTRUE if this is a good track
4496 // it will apply a pre-selection to obtain good quality tracks.
4497 // Here also you will have the possibility to put a control on the
4498 // impact point of the track on the basic block, in order to exclude border regions
4499 // this will be done by calling a proper method of the AliITSPlaneEff class.
4501 // input: AliITStrackMI* track, ilayer= layer number [0,5]
4502 // return: Bool_t -> kTRUE if usable track, kFALSE if not usable.
4504 Int_t index[AliITSgeomTGeo::kNLayers];
4506 for (k=0; k<AliITSgeomTGeo::GetNLayers(); k++) index[k]=-1;
4508 for (k=0; k<AliITSgeomTGeo::GetNLayers(); k++) {
4509 index[k]=clusters[k];
4513 {AliWarning("IsOKForPlaneEff: null pointer to AliITSPlaneEff"); return kFALSE;}
4514 AliITSlayer &layer=fgLayers[ilayer];
4515 Double_t r=layer.GetR();
4516 AliITStrackMI tmp(*track);
4518 // require a minimal number of cluster in other layers and eventually clusters in closest layers
4520 for(Int_t lay=AliITSgeomTGeo::kNLayers-1;lay>ilayer;lay--) {
4521 AliDebug(2,Form("trak=%d lay=%d ; index=%d ESD label= %d",tmp.GetLabel(),lay,
4522 tmp.GetClIndex(lay),((AliESDtrack*)tmp.GetESDtrack())->GetLabel())) ;
4523 if (tmp.GetClIndex(lay)>=0) ncl++;
4525 Bool_t nextout = kFALSE;
4526 if(ilayer==AliITSgeomTGeo::kNLayers-1) nextout=kTRUE; // you are already on the outermost layer
4527 else nextout = ((tmp.GetClIndex(ilayer+1)>=0)? kTRUE : kFALSE );
4528 Bool_t nextin = kFALSE;
4529 if(ilayer==0) nextin=kTRUE; // you are already on the innermost layer
4530 else nextin = ((index[ilayer-1]>=0)? kTRUE : kFALSE );
4531 if(ncl<AliITSgeomTGeo::kNLayers-(ilayer+1)-AliITSReconstructor::GetRecoParam()->GetMaxMissingClustersPlaneEff())
4533 if(AliITSReconstructor::GetRecoParam()->GetRequireClusterInOuterLayerPlaneEff() && !nextout) return kFALSE;
4534 if(AliITSReconstructor::GetRecoParam()->GetRequireClusterInInnerLayerPlaneEff() && !nextin) return kFALSE;
4535 if(tmp.Pt() < AliITSReconstructor::GetRecoParam()->GetMinPtPlaneEff()) return kFALSE;
4536 // if(AliITSReconstructor::GetRecoParam()->GetOnlyConstraintPlaneEff() && !tmp.GetConstrain()) return kFALSE;
4540 if (!tmp.GetPhiZat(r,phi,z)) return kFALSE;
4541 Int_t idet=layer.FindDetectorIndex(phi,z);
4542 if(idet<0) { AliInfo(Form("cannot find detector"));
4545 // here check if it has good Chi Square.
4547 //propagate to the intersection with the detector plane
4548 const AliITSdetector &det=layer.GetDetector(idet);
4549 if (!tmp.Propagate(det.GetPhi(),det.GetR())) return kFALSE;
4553 if(!LocalModuleCoord(ilayer,idet,&tmp,locx,locz)) return kFALSE;
4554 UInt_t key=fPlaneEff->GetKeyFromDetLocCoord(ilayer,idet,locx,locz);
4555 if(key>fPlaneEff->Nblock()) return kFALSE;
4556 Float_t blockXmn,blockXmx,blockZmn,blockZmx;
4557 if (!fPlaneEff->GetBlockBoundaries(key,blockXmn,blockXmx,blockZmn,blockZmx)) return kFALSE;
4559 // DEFINITION OF SEARCH ROAD FOR accepting a track
4561 //For the time being they are hard-wired, later on from AliITSRecoParam
4562 // Double_t nsigx=AliITSRecoParam::GetNSigXFarFromBoundary();
4563 // Double_t nsigz=AliITSRecoParam::GetNSigZFarFromBoundary();
4566 Double_t dx=nsigx*TMath::Sqrt(tmp.GetSigmaY2()); // those are precisions in the tracking reference system
4567 Double_t dz=nsigz*TMath::Sqrt(tmp.GetSigmaZ2()); // Use it also for the module reference system, as it is
4568 // done for RecPoints
4570 // exclude tracks at boundary between detectors
4571 //Double_t boundaryWidth=AliITSRecoParam::GetBoundaryWidthPlaneEff();
4572 Double_t boundaryWidth=0; // for the time being hard-wired, later on from AliITSRecoParam
4573 AliDebug(2,Form("Tracking: track impact x=%f, y=%f, z=%f",tmp.GetX(), tmp.GetY(), tmp.GetZ()));
4574 AliDebug(2,Form("Local: track impact x=%f, z=%f",locx,locz));
4575 AliDebug(2,Form("Search Road. Tracking: dy=%f , dz=%f",dx,dz));
4577 if ( (locx-dx < blockXmn+boundaryWidth) ||
4578 (locx+dx > blockXmx-boundaryWidth) ||
4579 (locz-dz < blockZmn+boundaryWidth) ||
4580 (locz+dz > blockZmx-boundaryWidth) ) return kFALSE;
4583 //------------------------------------------------------------------------
4584 void AliITStrackerMI::UseTrackForPlaneEff(const AliITStrackMI* track, Int_t ilayer) {
4586 // This Method has to be optimized! For the time-being it uses the same criteria
4587 // as those used in the search of extra clusters for overlapping modules.
4589 // Method Purpose: estabilish whether a track has produced a recpoint or not
4590 // in the layer under study (For Plane efficiency)
4592 // inputs: AliITStrackMI* track (pointer to a usable track)
4594 // side effects: update (by 1 count) the Plane Efficiency statistics of the basic block
4595 // traversed by this very track. In details:
4596 // - if a cluster can be associated to the track then call
4597 // AliITSPlaneEff::UpDatePlaneEff(key,kTRUE);
4598 // - if not, the AliITSPlaneEff::UpDatePlaneEff(key,kFALSE) is called
4601 {AliWarning("UseTrackForPlaneEff: null pointer to AliITSPlaneEff"); return;}
4602 AliITSlayer &layer=fgLayers[ilayer];
4603 Double_t r=layer.GetR();
4604 AliITStrackMI tmp(*track);
4608 if (!tmp.GetPhiZat(r,phi,z)) return;
4609 Int_t idet=layer.FindDetectorIndex(phi,z);
4611 if(idet<0) { AliInfo(Form("cannot find detector"));
4615 //propagate to the intersection with the detector plane
4616 const AliITSdetector &det=layer.GetDetector(idet);
4617 if (!tmp.Propagate(det.GetPhi(),det.GetR())) return;
4621 // DEFINITION OF SEARCH ROAD FOR CLUSTERS SELECTION
4623 Double_t dz=AliITSReconstructor::GetRecoParam()->GetNSigmaRoadZ()*
4624 TMath::Sqrt(tmp.GetSigmaZ2() +
4625 AliITSReconstructor::GetRecoParam()->GetNSigmaZLayerForRoadZ()*
4626 AliITSReconstructor::GetRecoParam()->GetNSigmaZLayerForRoadZ()*
4627 AliITSReconstructor::GetRecoParam()->GetSigmaZ2(ilayer));
4628 Double_t dy=AliITSReconstructor::GetRecoParam()->GetNSigmaRoadY()*
4629 TMath::Sqrt(tmp.GetSigmaY2() +
4630 AliITSReconstructor::GetRecoParam()->GetNSigmaYLayerForRoadY()*
4631 AliITSReconstructor::GetRecoParam()->GetNSigmaYLayerForRoadY()*
4632 AliITSReconstructor::GetRecoParam()->GetSigmaY2(ilayer));
4634 // road in global (rphi,z) [i.e. in tracking ref. system]
4635 Double_t zmin = tmp.GetZ() - dz;
4636 Double_t zmax = tmp.GetZ() + dz;
4637 Double_t ymin = tmp.GetY() + r*det.GetPhi() - dy;
4638 Double_t ymax = tmp.GetY() + r*det.GetPhi() + dy;
4640 // select clusters in road
4641 layer.SelectClusters(zmin,zmax,ymin,ymax);
4643 // Define criteria for track-cluster association
4644 Double_t msz = tmp.GetSigmaZ2() +
4645 AliITSReconstructor::GetRecoParam()->GetNSigmaZLayerForRoadZ()*
4646 AliITSReconstructor::GetRecoParam()->GetNSigmaZLayerForRoadZ()*
4647 AliITSReconstructor::GetRecoParam()->GetSigmaZ2(ilayer);
4648 Double_t msy = tmp.GetSigmaY2() +
4649 AliITSReconstructor::GetRecoParam()->GetNSigmaYLayerForRoadY()*
4650 AliITSReconstructor::GetRecoParam()->GetNSigmaYLayerForRoadY()*
4651 AliITSReconstructor::GetRecoParam()->GetSigmaY2(ilayer);
4652 if (tmp.GetConstrain()) {
4653 msz *= AliITSReconstructor::GetRecoParam()->GetNSigma2RoadZC();
4654 msy *= AliITSReconstructor::GetRecoParam()->GetNSigma2RoadYC();
4656 msz *= AliITSReconstructor::GetRecoParam()->GetNSigma2RoadZNonC();
4657 msy *= AliITSReconstructor::GetRecoParam()->GetNSigma2RoadYNonC();
4659 msz = 1./msz; // 1/RoadZ^2
4660 msy = 1./msy; // 1/RoadY^2
4663 const AliITSRecPoint *cl=0; Int_t clidx=-1, ci=-1;
4665 Double_t chi2trkcl=1000.*AliITSReconstructor::GetRecoParam()->GetMaxChi2();
4666 //Double_t tolerance=0.2;
4667 /*while ((cl=layer.GetNextCluster(clidx))!=0) {
4668 idetc = cl->GetDetectorIndex();
4669 if(idet!=idetc) continue;
4670 //Int_t ilay = cl->GetLayer();
4672 if (TMath::Abs(tmp.GetZ() - cl->GetZ()) > tolerance) continue;
4673 if (TMath::Abs(tmp.GetY() - cl->GetY()) > tolerance) continue;
4675 Double_t chi2=tmp.GetPredictedChi2(cl);
4676 if (chi2<chi2trkcl) { chi2trkcl=chi2; ci=clidx; }
4680 if(!LocalModuleCoord(ilayer,idet,&tmp,locx,locz)) return;
4682 AliDebug(2,Form("ilayer= %d, idet=%d, x= %f, z=%f",ilayer,idet,locx,locz));
4683 UInt_t key=fPlaneEff->GetKeyFromDetLocCoord(ilayer,idet,locx,locz);
4684 if(key>fPlaneEff->Nblock()) return;
4685 Bool_t found=kFALSE;
4688 while ((cl=layer.GetNextCluster(clidx))!=0) {
4689 idetc = cl->GetDetectorIndex();
4690 if(idet!=idetc) continue;
4691 // here real control to see whether the cluster can be associated to the track.
4692 // cluster not associated to track
4693 if ( (tmp.GetZ()-cl->GetZ())*(tmp.GetZ()-cl->GetZ())*msz +
4694 (tmp.GetY()-cl->GetY())*(tmp.GetY()-cl->GetY())*msy > 1. ) continue;
4695 // calculate track-clusters chi2
4696 chi2 = GetPredictedChi2MI(&tmp,cl,ilayer); // note that this method change track tmp
4697 // in particular, the error associated to the cluster
4698 //Double_t chi2 = tmp.GetPredictedChi(cl); // this method does not change track tmp
4700 if (chi2 > AliITSReconstructor::GetRecoParam()->GetMaxChi2s(ilayer)) continue;
4702 if (chi2<chi2trkcl) { chi2trkcl=chi2; ci=clidx; } // this just to trace which cluster is selected
4703 // track->SetExtraCluster(ilayer,(ilayer<<28)+ci);
4704 // track->SetExtraModule(ilayer,idetExtra);
4706 if(!fPlaneEff->UpDatePlaneEff(found,key))
4707 AliWarning(Form("UseTrackForPlaneEff: cannot UpDate PlaneEff for key=%d",key));
4708 if(fPlaneEff->GetCreateHistos()&& AliITSReconstructor::GetRecoParam()->GetHistoPlaneEff()) {
4709 Float_t tr[4]={99999.,99999.,9999.,9999.}; // initialize to high values
4710 Float_t clu[4]={-99999.,-99999.,9999.,9999.}; // (in some cases GetCov fails)
4711 Int_t cltype[2]={-999,-999};
4715 tr[2]=TMath::Sqrt(tmp.GetSigmaY2()); // those are precisions in the tracking reference system
4716 tr[3]=TMath::Sqrt(tmp.GetSigmaZ2()); // Use it also for the module reference system, as it is
4719 clu[0]=layer.GetCluster(ci)->GetDetLocalX();
4720 clu[1]=layer.GetCluster(ci)->GetDetLocalZ();
4721 cltype[0]=layer.GetCluster(ci)->GetNy();
4722 cltype[1]=layer.GetCluster(ci)->GetNz();
4724 // Without the following 6 lines you would retrieve the nominal error of a cluster (e.g. for the SPD:
4725 // X->50/sqrt(12)=14 micron Z->450/sqrt(12)= 120 micron)
4726 // Within AliTrackerMI/AliTrackMI the error on the cluster is associated to the AliITStrackMI (fSigmaY,Z)
4727 // It is computed properly by calling the method
4728 // AliITStrackerMI::GetPredictedChi2MI(AliITStrackMI* track, const AliITSRecPoint *cluster,Int_t layer)
4730 //Double_t x=0.5*(tmp.GetX()+layer.GetCluster(ci)->GetX()); // Take into account the mis-alignment
4731 //if (tmp.PropagateTo(x,0.,0.)) {
4732 chi2=GetPredictedChi2MI(&tmp,layer.GetCluster(ci),ilayer);
4733 AliCluster c(*layer.GetCluster(ci));
4734 c.SetSigmaY2(tmp.GetSigmaY(ilayer)*tmp.GetSigmaY(ilayer));
4735 c.SetSigmaZ2(tmp.GetSigmaZ(ilayer)*tmp.GetSigmaZ(ilayer));
4736 //if (layer.GetCluster(ci)->GetGlobalCov(cov)) // by using this, instead, you got nominal cluster errors
4737 clu[2]=TMath::Sqrt(c.GetSigmaY2());
4738 clu[3]=TMath::Sqrt(c.GetSigmaZ2());
4741 fPlaneEff->FillHistos(key,found,tr,clu,cltype);