LCOV - code coverage report
Current view: top level - ITS/ITSbase - AliITStrackerMI.cxx (source / functions) Hit Total Coverage
Test: coverage.info Lines: 2256 3118 72.4 %
Date: 2016-06-14 17:26:59 Functions: 69 88 78.4 %

          Line data    Source code
       1             : /**************************************************************************
       2             :  * Copyright(c) 2007-2009, ALICE Experiment at CERN, All rights reserved. *
       3             :  *                                                                        *
       4             :  * Author: The ALICE Off-line Project.                                    *
       5             :  * Contributors are mentioned in the code where appropriate.              *
       6             :  *                                                                        *
       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             :  **************************************************************************/
      15             : /* $Id$ */
      16             : 
      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             : //-------------------------------------------------------------------------
      28             : 
      29             : #include <TMatrixD.h>
      30             : #include <TTree.h>
      31             : #include <TDatabasePDG.h>
      32             : #include <TString.h>
      33             : #include <TRandom.h>
      34             : #include <TTreeStream.h>
      35             : #include <TVector3.h>
      36             : #include <TBits.h>
      37             : 
      38             : #include "AliLog.h"
      39             : #include "AliGeomManager.h"
      40             : #include "AliITSPlaneEff.h"
      41             : #include "AliTrackPointArray.h"
      42             : #include "AliESDEvent.h"
      43             : #include "AliESDV0Params.h"
      44             : #include "AliESDtrack.h"
      45             : #include "AliV0.h"
      46             : #include "AliITSChannelStatus.h"
      47             : #include "AliITSDetTypeRec.h"
      48             : #include "AliITSRecPoint.h"
      49             : #include "AliITSRecPointContainer.h"
      50             : #include "AliITSgeomTGeo.h"
      51             : #include "AliITSReconstructor.h"
      52             : #include "AliITSClusterParam.h"
      53             : #include "AliITSsegmentation.h"
      54             : #include "AliITSCalibration.h"
      55             : #include "AliITSPlaneEffSPD.h"
      56             : #include "AliITSPlaneEffSDD.h"
      57             : #include "AliITSPlaneEffSSD.h"
      58             : #include "AliITSV0Finder.h"
      59             : #include "AliITStrackerMI.h"
      60             : #include "AliMathBase.h"
      61             : #include "AliPID.h"
      62             : 
      63             : 
      64         118 : ClassImp(AliITStrackerMI)
      65             : 
      66        1062 : AliITStrackerMI::AliITSlayer AliITStrackerMI::fgLayers[AliITSgeomTGeo::kNLayers]; // ITS layers
      67             : 
      68           0 : AliITStrackerMI::AliITStrackerMI():AliTracker(),
      69           0 : fI(0),
      70           0 : fBestTrack(),
      71           0 : fTrackToFollow(),
      72           0 : fTrackHypothesys(),
      73           0 : fBestHypothesys(),
      74           0 : fOriginal(),
      75           0 : fCurrentEsdTrack(),
      76           0 : fPass(0),
      77           0 : fAfterV0(kFALSE),
      78           0 : fLastLayerToTrackTo(0),
      79           0 : fCoefficients(0),
      80           0 : fEsd(0),
      81           0 : fTrackingPhase("Default"),
      82           0 : fUseTGeo(3),
      83           0 : fNtracks(0),
      84           0 : fFlagFakes(kFALSE),
      85           0 : fSelectBestMIP03(kFALSE),
      86           0 : fUseImproveKalman(kFALSE),
      87           0 : fxOverX0Pipe(-1.),
      88           0 : fxTimesRhoPipe(-1.),
      89           0 : fxOverX0PipeTrks(0),
      90           0 : fxTimesRhoPipeTrks(0),
      91           0 : fxOverX0ShieldTrks(0),
      92           0 : fxTimesRhoShieldTrks(0),
      93           0 : fxOverX0LayerTrks(0),
      94           0 : fxTimesRhoLayerTrks(0),
      95           0 : fDebugStreamer(0),
      96           0 : fITSChannelStatus(0),
      97           0 : fkDetTypeRec(0),
      98           0 : fPlaneEff(0),
      99           0 : fSPDChipIntPlaneEff(0),
     100           0 : fITSPid(0)
     101             : 
     102           0 :  {
     103             :   //Default constructor
     104             :   Int_t i;
     105           0 :   for(i=0;i<4;i++) fSPDdetzcentre[i]=0.;
     106           0 :   for(i=0;i<2;i++) {
     107           0 :     fxOverX0Shield[i]=-1.;
     108           0 :     fxTimesRhoShield[i]=-1.;
     109           0 :     fConstraint[i]=0;
     110             :   }
     111           0 :   for(i=0;i<6;i++) {fxOverX0Layer[i]=-1.;fxTimesRhoLayer[i]=-1.;}
     112           0 :   fOriginal.SetOwner();
     113           0 :   for(i=0;i<AliITSgeomTGeo::kNLayers;i++)fForceSkippingOfLayer[i]=0;
     114           0 :   for(i=0;i<100000;i++)fBestTrackIndex[i]=0;
     115           0 :   fITSPid=new AliITSPIDResponse();
     116             : 
     117           0 : }
     118             : //------------------------------------------------------------------------
     119          28 : AliITStrackerMI::AliITStrackerMI(const Char_t *geom) : AliTracker(),
     120           2 : fI(AliITSgeomTGeo::GetNLayers()),
     121           2 : fBestTrack(),
     122           2 : fTrackToFollow(),
     123           2 : fTrackHypothesys(),
     124           2 : fBestHypothesys(),
     125           2 : fOriginal(),
     126           2 : fCurrentEsdTrack(),
     127           2 : fPass(0),
     128           2 : fAfterV0(kFALSE),
     129           2 : fLastLayerToTrackTo(AliITSRecoParam::GetLastLayerToTrackTo()),
     130           2 : fCoefficients(0),
     131           2 : fEsd(0),
     132           2 : fTrackingPhase("Default"),
     133           2 : fUseTGeo(3),
     134           2 : fNtracks(0),
     135           2 : fFlagFakes(kFALSE),
     136           2 : fSelectBestMIP03(kFALSE),
     137           2 : fUseImproveKalman(kFALSE),
     138           2 : fxOverX0Pipe(-1.),
     139           2 : fxTimesRhoPipe(-1.),
     140           2 : fxOverX0PipeTrks(0),
     141           2 : fxTimesRhoPipeTrks(0),
     142           2 : fxOverX0ShieldTrks(0),
     143           2 : fxTimesRhoShieldTrks(0),
     144           2 : fxOverX0LayerTrks(0),
     145           2 : fxTimesRhoLayerTrks(0),
     146           2 : fDebugStreamer(0),
     147           2 : fITSChannelStatus(0),
     148           2 : fkDetTypeRec(0),
     149           2 : fPlaneEff(0),
     150           2 : fSPDChipIntPlaneEff(0),
     151           8 : fITSPid(0) {
     152             :   //--------------------------------------------------------------------
     153             :   //This is the AliITStrackerMI constructor
     154             :   //--------------------------------------------------------------------
     155           2 :   if (geom) {
     156           0 :     AliWarning("\"geom\" is actually a dummy argument !");
     157             :   }
     158             : 
     159           2 :   fOriginal.SetOwner();
     160           2 :   fCoefficients = 0;
     161           2 :   fAfterV0     = kFALSE;
     162             : 
     163          28 :   for (Int_t i=1; i<AliITSgeomTGeo::GetNLayers()+1; i++) {
     164          12 :     Int_t nlad=AliITSgeomTGeo::GetNLadders(i);
     165          12 :     Int_t ndet=AliITSgeomTGeo::GetNDetectors(i);
     166             : 
     167          12 :     Double_t xyz[3]={0}, &x=xyz[0], &y=xyz[1], &z=xyz[2];
     168          12 :     AliITSgeomTGeo::GetTranslation(i,1,1,xyz); 
     169          12 :     Double_t poff=TMath::ATan2(y,x);
     170          12 :     Double_t zoff=z;
     171             : 
     172          12 :     AliITSgeomTGeo::GetOrigTranslation(i,1,1,xyz);
     173          12 :     Double_t r=TMath::Sqrt(x*x + y*y);
     174             : 
     175          12 :     AliITSgeomTGeo::GetOrigTranslation(i,1,2,xyz);
     176          12 :     r += TMath::Sqrt(x*x + y*y);
     177          12 :     AliITSgeomTGeo::GetOrigTranslation(i,2,1,xyz);
     178          12 :     r += TMath::Sqrt(x*x + y*y);
     179          12 :     AliITSgeomTGeo::GetOrigTranslation(i,2,2,xyz);
     180          12 :     r += TMath::Sqrt(x*x + y*y);
     181          12 :     r*=0.25;
     182             : 
     183          12 :     new (fgLayers+i-1) AliITSlayer(r,poff,zoff,nlad,ndet);
     184             : 
     185         696 :     for (Int_t j=1; j<nlad+1; j++) {
     186        9464 :       for (Int_t k=1; k<ndet+1; k++) { //Fill this layer with detectors
     187        8792 :         TGeoHMatrix m; AliITSgeomTGeo::GetOrigMatrix(i,j,k,m);
     188        4396 :         const TGeoHMatrix *tm=AliITSgeomTGeo::GetTracking2LocalMatrix(i,j,k);
     189        4396 :         m.Multiply(tm);
     190        4396 :         Double_t txyz[3]={0.};
     191        4396 :         xyz[0]=0.;xyz[1]=0.;xyz[2]=0.;
     192        4396 :         m.LocalToMaster(txyz,xyz);
     193        4396 :         r=TMath::Sqrt(xyz[0]*xyz[0] + xyz[1]*xyz[1]);
     194        4396 :         Double_t phi=TMath::ATan2(xyz[1],xyz[0]);
     195             : 
     196        8792 :         if (phi<0) phi+=TMath::TwoPi();
     197        4396 :         else if (phi>=TMath::TwoPi()) phi-=TMath::TwoPi();
     198             : 
     199        4396 :         AliITSdetector &det=fgLayers[i-1].GetDetector((j-1)*ndet + k-1); 
     200        4396 :         new(&det) AliITSdetector(r,phi); 
     201             :         // compute the real radius (with misalignment)
     202        8792 :         TGeoHMatrix mmisal(*(AliITSgeomTGeo::GetMatrix(i,j,k)));
     203        4396 :         mmisal.Multiply(tm);
     204        4396 :         xyz[0]=0.;xyz[1]=0.;xyz[2]=0.;
     205        4396 :         mmisal.LocalToMaster(txyz,xyz);
     206        4396 :         Double_t rmisal=TMath::Sqrt(xyz[0]*xyz[0] + xyz[1]*xyz[1]);
     207        4396 :         det.SetRmisal(rmisal);
     208             :         
     209        4396 :       } // end loop on detectors
     210             :     } // end loop on ladders
     211          12 :     fForceSkippingOfLayer[i-1] = 0;
     212          12 :   } // end loop on layers
     213             : 
     214             : 
     215           2 :   fI=AliITSgeomTGeo::GetNLayers();
     216             : 
     217           2 :   fPass=0;
     218           2 :   fConstraint[0]=1; fConstraint[1]=0;
     219             : 
     220           8 :   Double_t xyzVtx[]={AliITSReconstructor::GetRecoParam()->GetXVdef(),
     221           4 :                      AliITSReconstructor::GetRecoParam()->GetYVdef(),
     222           4 :                      AliITSReconstructor::GetRecoParam()->GetZVdef()}; 
     223           8 :   Double_t ersVtx[]={AliITSReconstructor::GetRecoParam()->GetSigmaXVdef(),
     224           4 :                      AliITSReconstructor::GetRecoParam()->GetSigmaYVdef(),
     225           4 :                      AliITSReconstructor::GetRecoParam()->GetSigmaZVdef()}; 
     226           2 :   SetVertex(xyzVtx,ersVtx);
     227             : 
     228           2 :   fLastLayerToTrackTo=AliITSRecoParam::GetLastLayerToTrackTo();
     229      400004 :   for (Int_t i=0;i<100000;i++){
     230      200000 :     fBestTrackIndex[i]=0;
     231             :   }
     232             : 
     233             :   // store positions of centre of SPD modules (in z)
     234             :   //  The convetion is that fSPDdetzcentre is ordered from -z to +z
     235           2 :   Double_t tr[3]={0};
     236           2 :   AliITSgeomTGeo::GetTranslation(1,1,1,tr);
     237           2 :   if (tr[2]<0) { // old geom (up to v5asymmPPR)
     238           0 :     AliITSgeomTGeo::GetTranslation(1,1,1,tr);
     239           0 :     fSPDdetzcentre[0] = tr[2];
     240           0 :     AliITSgeomTGeo::GetTranslation(1,1,2,tr);
     241           0 :     fSPDdetzcentre[1] = tr[2];
     242           0 :     AliITSgeomTGeo::GetTranslation(1,1,3,tr);
     243           0 :     fSPDdetzcentre[2] = tr[2];
     244           0 :     AliITSgeomTGeo::GetTranslation(1,1,4,tr);
     245           0 :     fSPDdetzcentre[3] = tr[2];
     246           0 :   } else { // new geom (from v11Hybrid)
     247           2 :     AliITSgeomTGeo::GetTranslation(1,1,4,tr);
     248           2 :     fSPDdetzcentre[0] = tr[2];
     249           2 :     AliITSgeomTGeo::GetTranslation(1,1,3,tr);
     250           2 :     fSPDdetzcentre[1] = tr[2];
     251           2 :     AliITSgeomTGeo::GetTranslation(1,1,2,tr);
     252           2 :     fSPDdetzcentre[2] = tr[2];
     253           2 :     AliITSgeomTGeo::GetTranslation(1,1,1,tr);
     254           2 :     fSPDdetzcentre[3] = tr[2];
     255             :   }
     256             : 
     257           4 :   fUseTGeo = AliITSReconstructor::GetRecoParam()->GetUseTGeoInTracker();
     258           8 :   if(AliITSReconstructor::GetRecoParam()->GetExtendedEtaAcceptance() && fUseTGeo!=1 && fUseTGeo!=3) {
     259           0 :     AliWarning("fUseTGeo changed to 3 because fExtendedEtaAcceptance is kTRUE");
     260           0 :     fUseTGeo = 3;
     261           0 :   }
     262             : 
     263          12 :   for(Int_t i=0;i<2;i++) {fxOverX0Shield[i]=-1.;fxTimesRhoShield[i]=-1.;}
     264          28 :   for(Int_t i=0;i<6;i++) {fxOverX0Layer[i]=-1.;fxTimesRhoLayer[i]=-1.;}
     265             :   
     266           4 :   if (AliITSReconstructor::GetRecoParam()->GetESDV0Params()->StreamLevel()>0)
     267           0 :     fDebugStreamer = new TTreeSRedirector("ITSdebug.root");
     268             : 
     269             :   // only for plane efficiency evaluation
     270           4 :   if (AliITSReconstructor::GetRecoParam()->GetComputePlaneEff() &&
     271           0 :       AliITSReconstructor::GetRecoParam()->GetIPlanePlaneEff()>=0) {
     272           0 :     Int_t iplane=AliITSReconstructor::GetRecoParam()->GetIPlanePlaneEff();
     273           0 :     if(AliITSReconstructor::GetRecoParam()->GetLayersToSkip(iplane)!=1)
     274           0 :       AliWarning(Form("Evaluation of Plane Eff for layer %d will be attempted without removing it from tracker",iplane));
     275           0 :     if (iplane<2) {
     276           0 :       fPlaneEff = new AliITSPlaneEffSPD();
     277           0 :       fSPDChipIntPlaneEff = new Bool_t[AliITSPlaneEffSPD::kNModule*AliITSPlaneEffSPD::kNChip];
     278           0 :       for (UInt_t i=0; i<AliITSPlaneEffSPD::kNModule*AliITSPlaneEffSPD::kNChip; i++) fSPDChipIntPlaneEff[i]=kFALSE;
     279           0 :     }
     280           0 :     else if (iplane<4) fPlaneEff = new AliITSPlaneEffSDD();
     281           0 :     else fPlaneEff = new AliITSPlaneEffSSD();
     282           0 :     if(AliITSReconstructor::GetRecoParam()->GetReadPlaneEffFromOCDB())
     283           0 :        if(!fPlaneEff->ReadFromCDB()) {AliWarning("AliITStrackerMI reading of AliITSPlaneEff from OCDB failed") ;}
     284           0 :     if(AliITSReconstructor::GetRecoParam()->GetHistoPlaneEff()) fPlaneEff->SetCreateHistos(kTRUE);
     285           0 :   }
     286             :   //
     287             :   // RS
     288           2 :   fSelectBestMIP03  = kFALSE;//AliITSReconstructor::GetRecoParam()->GetSelectBestMIP03();
     289           4 :   fFlagFakes        = AliITSReconstructor::GetRecoParam()->GetFlagFakes();
     290           4 :   fUseImproveKalman = AliITSReconstructor::GetRecoParam()->GetUseImproveKalman();
     291             :   //
     292           6 :   fITSPid=new AliITSPIDResponse();
     293           2 : }
     294             : /*
     295             : //------------------------------------------------------------------------
     296             : AliITStrackerMI::AliITStrackerMI(const AliITStrackerMI &tracker):AliTracker(tracker),
     297             : fI(tracker.fI),
     298             : fBestTrack(tracker.fBestTrack),
     299             : fTrackToFollow(tracker.fTrackToFollow),
     300             : fTrackHypothesys(tracker.fTrackHypothesys),
     301             : fBestHypothesys(tracker.fBestHypothesys),
     302             : fOriginal(tracker.fOriginal),
     303             : fCurrentEsdTrack(tracker.fCurrentEsdTrack),
     304             : fPass(tracker.fPass),
     305             : fAfterV0(tracker.fAfterV0),
     306             : fLastLayerToTrackTo(tracker.fLastLayerToTrackTo),
     307             : fCoefficients(tracker.fCoefficients),
     308             : fEsd(tracker.fEsd),
     309             : fTrackingPhase(tracker.fTrackingPhase),
     310             : fUseTGeo(tracker.fUseTGeo),
     311             : fNtracks(tracker.fNtracks),
     312             : fFlagFakes(tracker.fFlagFakes),
     313             : fSelectBestMIP03(tracker.fSelectBestMIP03),
     314             : fxOverX0Pipe(tracker.fxOverX0Pipe),
     315             : fxTimesRhoPipe(tracker.fxTimesRhoPipe),
     316             : fxOverX0PipeTrks(0),
     317             : fxTimesRhoPipeTrks(0),
     318             : fxOverX0ShieldTrks(0),
     319             : fxTimesRhoShieldTrks(0),
     320             : fxOverX0LayerTrks(0),
     321             : fxTimesRhoLayerTrks(0),
     322             : fDebugStreamer(tracker.fDebugStreamer),
     323             : fITSChannelStatus(tracker.fITSChannelStatus),
     324             : fkDetTypeRec(tracker.fkDetTypeRec),
     325             : fPlaneEff(tracker.fPlaneEff) {
     326             :   //Copy constructor
     327             :   fOriginal.SetOwner();
     328             :   Int_t i;
     329             :   for(i=0;i<4;i++) {
     330             :     fSPDdetzcentre[i]=tracker.fSPDdetzcentre[i];
     331             :   }
     332             :   for(i=0;i<6;i++) {
     333             :     fxOverX0Layer[i]=tracker.fxOverX0Layer[i];
     334             :     fxTimesRhoLayer[i]=tracker.fxTimesRhoLayer[i];
     335             :   }
     336             :   for(i=0;i<2;i++) {
     337             :     fxOverX0Shield[i]=tracker.fxOverX0Shield[i];
     338             :     fxTimesRhoShield[i]=tracker.fxTimesRhoShield[i];
     339             :   }
     340             : }
     341             : 
     342             : //------------------------------------------------------------------------
     343             : AliITStrackerMI & AliITStrackerMI::operator=(const AliITStrackerMI &tracker){
     344             :   //Assignment operator
     345             :   this->~AliITStrackerMI();
     346             :   new(this) AliITStrackerMI(tracker);
     347             :   return *this;
     348             : }
     349             : */
     350             : //------------------------------------------------------------------------
     351             : AliITStrackerMI::~AliITStrackerMI()
     352           4 : {
     353             :   //
     354             :   //destructor
     355             :   //
     356           2 :   if (fCoefficients) delete [] fCoefficients;
     357           2 :   DeleteTrksMaterialLUT();
     358           2 :   if (fDebugStreamer) {
     359             :     //fDebugStreamer->Close();
     360           0 :     delete fDebugStreamer;
     361             :   }
     362           6 :   if(fITSChannelStatus) delete fITSChannelStatus;
     363           2 :   if(fPlaneEff) delete fPlaneEff;
     364           6 :   if(fITSPid) delete fITSPid;
     365           2 :   if (fSPDChipIntPlaneEff) delete [] fSPDChipIntPlaneEff;
     366             : 
     367          16 : }
     368             : //------------------------------------------------------------------------
     369             : void AliITStrackerMI::ReadBadFromDetTypeRec() {
     370             :   //--------------------------------------------------------------------
     371             :   //This function read ITS bad detectors, chips, channels from AliITSDetTypeRec
     372             :   //i.e. from OCDB
     373             :   //--------------------------------------------------------------------
     374             : 
     375           4 :   if(!AliITSReconstructor::GetRecoParam()->GetUseBadZonesFromOCDB()) return;
     376             : 
     377           2 :   Info("ReadBadFromDetTypeRec","Reading info about bad ITS detectors and channels");
     378             : 
     379           2 :   if(!fkDetTypeRec) Error("ReadBadFromDetTypeRec","AliITSDetTypeRec nof found!\n");
     380             : 
     381             :   // ITS channels map
     382           2 :   if(fITSChannelStatus) delete fITSChannelStatus;
     383           4 :   fITSChannelStatus = new AliITSChannelStatus(fkDetTypeRec);
     384             : 
     385             :   // ITS detectors and chips
     386             :   Int_t i=0,j=0,k=0,ndet=0;
     387          28 :   for (i=1; i<AliITSgeomTGeo::GetNLayers()+1; i++) {
     388             :     Int_t nBadDetsPerLayer=0;
     389          12 :     ndet=AliITSgeomTGeo::GetNDetectors(i);    
     390         696 :     for (j=1; j<AliITSgeomTGeo::GetNLadders(i)+1; j++) {
     391        9464 :       for (k=1; k<ndet+1; k++) {
     392        4396 :         AliITSdetector &det=fgLayers[i-1].GetDetector((j-1)*ndet + k-1);  
     393        4396 :         det.ReadBadDetectorAndChips(i-1,(j-1)*ndet + k-1,fkDetTypeRec);
     394        4576 :         if(det.IsBad()) {nBadDetsPerLayer++;}
     395             :       } // end loop on detectors
     396             :     } // end loop on ladders
     397          12 :     AliInfo(Form("Layer %d: %d bad out of %d",i-1,nBadDetsPerLayer,ndet*AliITSgeomTGeo::GetNLadders(i)));
     398             :   } // end loop on layers
     399             :   
     400             :   return;
     401           2 : }
     402             : //------------------------------------------------------------------------
     403             : Int_t AliITStrackerMI::LoadClusters(TTree *cTree) {
     404             :   //--------------------------------------------------------------------
     405             :   //This function loads ITS clusters
     406             :   //--------------------------------------------------------------------
     407             :  
     408             :   TClonesArray *clusters = NULL;
     409          16 :   AliITSRecPointContainer* rpcont=AliITSRecPointContainer::Instance();
     410           8 :   clusters=rpcont->FetchClusters(0,cTree);
     411           8 :   if(!clusters) return 1;
     412             : 
     413           8 :   if(!(rpcont->IsSPDActive() || rpcont->IsSDDActive() || rpcont->IsSSDActive())){
     414           0 :       AliError("ITS is not in a known running configuration: SPD, SDD and SSD are not active");
     415           0 :       return 1;
     416             :   }
     417             :   Int_t i=0,j=0,ndet=0;
     418             :   Int_t detector=0;
     419         112 :   for (i=0; i<AliITSgeomTGeo::GetNLayers(); i++) {
     420          48 :     ndet=fgLayers[i].GetNdetectors();
     421          48 :     Int_t jmax = j + fgLayers[i].GetNladders()*ndet;
     422       35264 :     for (; j<jmax; j++) {           
     423             :       //      if (!cTree->GetEvent(j)) continue;
     424       17584 :       clusters = rpcont->UncheckedGetClusters(j);
     425       17584 :       if(!clusters)continue;
     426       17584 :       Int_t ncl=clusters->GetEntriesFast();
     427       17584 :       SignDeltas(clusters,GetZ());
     428             :  
     429       35834 :       while (ncl--) {
     430         666 :         AliITSRecPoint *c=(AliITSRecPoint*)clusters->UncheckedAt(ncl);
     431         666 :         detector=c->GetDetectorIndex();
     432             : 
     433         666 :         if (!c->Misalign()) AliWarning("Can't misalign this cluster !");
     434             :         
     435        1332 :         Int_t retval = fgLayers[i].InsertCluster(new AliITSRecPoint(*c));
     436         666 :         if(retval) {
     437           0 :           AliWarning(Form("Too many clusters on layer %d!",i));
     438           0 :           break;  
     439             :         } 
     440         666 :       }
     441             : 
     442             :       // add dead zone "virtual" cluster in SPD, if there is a cluster within 
     443             :       // zwindow cm from the dead zone      
     444             :       //  This method assumes that fSPDdetzcentre is ordered from -z to +z
     445       19504 :       if (i<2 && AliITSReconstructor::GetRecoParam()->GetAddVirtualClustersInDeadZone()) {
     446           0 :         for (Float_t xdead = 0; xdead < AliITSRecoParam::GetSPDdetxlength(); xdead += (i+1.)*AliITSReconstructor::GetRecoParam()->GetXPassDeadZoneHits()) {
     447           0 :           Int_t lab[4]   = {0,0,0,detector};
     448           0 :           Int_t info[3]  = {0,0,i};
     449             :           Float_t q      = 0.; // this identifies virtual clusters
     450           0 :           Float_t hit[6] = {xdead,
     451             :                             0.,
     452           0 :                             static_cast<Float_t>(AliITSReconstructor::GetRecoParam()->GetSigmaXDeadZoneHit2()),
     453           0 :                             static_cast<Float_t>(AliITSReconstructor::GetRecoParam()->GetSigmaZDeadZoneHit2()),
     454             :                             q,
     455             :                             0.};
     456             :           Bool_t local   = kTRUE;
     457           0 :           Double_t zwindow = AliITSReconstructor::GetRecoParam()->GetZWindowDeadZone();
     458           0 :           hit[1] = fSPDdetzcentre[0]+0.5*AliITSRecoParam::GetSPDdetzlength();
     459           0 :           if (TMath::Abs(fgLayers[i].GetDetector(detector).GetZmax()-hit[1])<zwindow) 
     460           0 :             fgLayers[i].InsertCluster(new AliITSRecPoint(lab,hit,info,local));
     461           0 :           hit[1] = fSPDdetzcentre[1]-0.5*AliITSRecoParam::GetSPDdetzlength();
     462           0 :           if (TMath::Abs(fgLayers[i].GetDetector(detector).GetZmax()-hit[1])<zwindow) 
     463           0 :             fgLayers[i].InsertCluster(new AliITSRecPoint(lab,hit,info,local));
     464           0 :           hit[1] = fSPDdetzcentre[1]+0.5*AliITSRecoParam::GetSPDdetzlength();
     465           0 :           if (TMath::Abs(fgLayers[i].GetDetector(detector).GetZmax()-hit[1])<zwindow) 
     466           0 :             fgLayers[i].InsertCluster(new AliITSRecPoint(lab,hit,info,local));
     467           0 :           hit[1] = fSPDdetzcentre[2]-0.5*AliITSRecoParam::GetSPDdetzlength();
     468           0 :           if (TMath::Abs(fgLayers[i].GetDetector(detector).GetZmax()-hit[1])<zwindow) 
     469           0 :             fgLayers[i].InsertCluster(new AliITSRecPoint(lab,hit,info,local));
     470           0 :           hit[1] = fSPDdetzcentre[2]+0.5*AliITSRecoParam::GetSPDdetzlength();
     471           0 :           if (TMath::Abs(fgLayers[i].GetDetector(detector).GetZmax()-hit[1])<zwindow) 
     472           0 :             fgLayers[i].InsertCluster(new AliITSRecPoint(lab,hit,info,local));
     473           0 :           hit[1] = fSPDdetzcentre[3]-0.5*AliITSRecoParam::GetSPDdetzlength();
     474           0 :           if (TMath::Abs(fgLayers[i].GetDetector(detector).GetZmax()-hit[1])<zwindow) 
     475           0 :             fgLayers[i].InsertCluster(new AliITSRecPoint(lab,hit,info,local));
     476           0 :         }
     477           0 :       } // "virtual" clusters in SPD
     478             :       
     479       17584 :     }
     480             :     //
     481          48 :     fgLayers[i].ResetRoad(); //road defined by the cluster density
     482          48 :     fgLayers[i].SortClusters();
     483             :   }
     484             : 
     485             :   // check whether we have to skip some layers
     486           8 :   SetForceSkippingOfLayer();
     487             : 
     488             :   return 0;
     489           8 : }
     490             : //------------------------------------------------------------------------
     491             : void AliITStrackerMI::UnloadClusters() {
     492             :   //--------------------------------------------------------------------
     493             :   //This function unloads ITS clusters
     494             :   //--------------------------------------------------------------------
     495         120 :   for (Int_t i=0; i<AliITSgeomTGeo::GetNLayers(); i++) fgLayers[i].ResetClusters();
     496           8 : }
     497             : //------------------------------------------------------------------------
     498             : void AliITStrackerMI::FillClusterArray(TObjArray* array) const {
     499             :   //--------------------------------------------------------------------
     500             :   // Publishes all pointers to clusters known to the tracker into the
     501             :   // passed object array.
     502             :   // The ownership is not transfered - the caller is not expected to delete
     503             :   // the clusters.
     504             :   //--------------------------------------------------------------------
     505             : 
     506           0 :   for(Int_t i=0; i<AliITSgeomTGeo::GetNLayers(); i++) {
     507           0 :     for(Int_t icl=0; icl<fgLayers[i].GetNumberOfClusters(); icl++) {
     508           0 :       AliCluster *cl = (AliCluster*)fgLayers[i].GetCluster(icl);
     509           0 :       array->AddLast(cl);
     510             :     }
     511             :   }
     512             : 
     513           0 :   return;
     514             : }
     515             : //------------------------------------------------------------------------
     516             : Int_t AliITStrackerMI::CorrectForTPCtoITSDeadZoneMaterial(AliITStrackMI *t) {
     517             :   //--------------------------------------------------------------------
     518             :   // Correction for the material between the TPC and the ITS
     519             :   //--------------------------------------------------------------------
     520         684 :   if (t->GetX() > AliITSRecoParam::Getriw()) {   // inward direction 
     521         246 :       if (!t->PropagateToTGeo(AliITSRecoParam::Getriw(),1)) return 0;// TPC inner wall
     522         242 :       if (!t->PropagateToTGeo(AliITSRecoParam::Getrcd(),1)) return 0;// TPC central drum
     523         242 :       if (!t->PropagateToTGeo(AliITSRecoParam::Getrs(),1))  return 0;// ITS screen
     524          98 :   } else if (t->GetX() < AliITSRecoParam::Getrs()) {  // outward direction
     525          98 :       if (!t->PropagateToTGeo(AliITSRecoParam::Getrs(),1))        return 0;// ITS screen
     526          98 :       if (!t->PropagateToTGeo(AliITSRecoParam::Getrcd(),1))       return 0;// TPC central drum
     527          98 :       if (!t->PropagateToTGeo(AliITSRecoParam::Getriw()+0.001,1)) return 0;// TPC inner wall
     528             :   } else {
     529           0 :     printf("CorrectForTPCtoITSDeadZoneMaterial: Track is already in the dead zone !\n");
     530           0 :     return 0;
     531             :   }
     532             :   
     533         340 :   return 1;
     534         342 : }
     535             : //------------------------------------------------------------------------
     536             : Int_t AliITStrackerMI::Clusters2Tracks(AliESDEvent *event) {
     537             :   //--------------------------------------------------------------------
     538             :   // This functions reconstructs ITS tracks
     539             :   // The clusters must be already loaded !
     540             :   //--------------------------------------------------------------------
     541             : 
     542          32 :   AliDebug(2,Form("SKIPPING %d %d %d %d %d %d",ForceSkippingOfLayer(0),ForceSkippingOfLayer(1),ForceSkippingOfLayer(2),ForceSkippingOfLayer(3),ForceSkippingOfLayer(4),ForceSkippingOfLayer(5)));
     543             : 
     544           8 :   fTrackingPhase="Clusters2Tracks";
     545             :   //
     546             :   // RS
     547           8 :   fSelectBestMIP03  = kFALSE;//AliITSReconstructor::GetRecoParam()->GetSelectBestMIP03();
     548           8 :   fFlagFakes        = AliITSReconstructor::GetRecoParam()->GetFlagFakes();
     549           8 :   fUseImproveKalman = AliITSReconstructor::GetRecoParam()->GetUseImproveKalman();
     550             :   //
     551           8 :   double minPtCut = AliITSReconstructor::GetRecoParam()->GetMinPtForProlongation();
     552             :   // the pt cutoff is tuned for nominal 5kG field, scale it with real field
     553             :   const double kNomField = 5.00668e+00;
     554           8 :   minPtCut *= TMath::Abs(GetBz()/kNomField);
     555             :   //
     556           8 :   TObjArray itsTracks(15000);
     557           8 :   fOriginal.Clear();
     558           8 :   fEsd = event;         // store pointer to the esd 
     559           8 :   Bool_t checkInv = AliITSReconstructor::GetCheckInvariant(); // off in the special reco mode w/o invariant check
     560             :   // temporary (for cosmics)
     561          16 :   if(event->GetVertex()) {
     562          24 :     TString title = event->GetVertex()->GetTitle();
     563          16 :     if(title.Contains("cosmics")) {
     564           0 :       Double_t xyz[3]={GetX(),GetY(),GetZ()};
     565           0 :       Double_t exyz[3]={0.1,0.1,0.1};
     566           0 :       SetVertex(xyz,exyz);
     567           0 :     }
     568           8 :   }
     569             :   // temporary
     570             :   Int_t noesd = 0;
     571             :   {/* Read ESD tracks */
     572           8 :     Int_t nentr=event->GetNumberOfTracks();
     573             :     noesd=nentr;
     574             :     //    Info("Clusters2Tracks", "Number of ESD tracks: %d\n", nentr);
     575         152 :     while (nentr--) {
     576         136 :       AliESDtrack *esd=event->GetTrack(nentr);
     577             :       //  ---- for debugging:
     578             :       //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); }
     579             : 
     580         272 :       if ((esd->GetStatus()&AliESDtrack::kTPCin)==0) continue;
     581         272 :       if (esd->GetStatus()&AliESDtrack::kTPCout) continue;
     582         272 :       if (esd->GetStatus()&AliESDtrack::kITSin) continue;
     583         276 :       if (esd->GetKinkIndex(0)>0) continue;   //kink daughter
     584         264 :       AliITStrackMI *t = new AliITStrackMI(*esd);
     585         132 :       t->SetCheckInvariant(checkInv);
     586         132 :       t->GetDZ(GetX(),GetY(),GetZ(),t->GetDP());              //I.B.
     587         132 :       Double_t vdist = TMath::Sqrt(t->GetD(0)*t->GetD(0)+t->GetD(1)*t->GetD(1));
     588             : 
     589             :       // write expected q
     590         264 :       t->SetExpQ(TMath::Max(0.8*t->GetESDtrack()->GetTPCsignal(),30.));
     591             : 
     592         132 :       if (esd->GetV0Index(0)>0 && t->GetD(0)<AliITSReconstructor::GetRecoParam()->GetMaxDforV0dghtrForProlongation()){
     593             :         //track - can be  V0 according to TPC
     594             :       } else {  
     595         264 :         if (TMath::Abs(t->GetD(0))>AliITSReconstructor::GetRecoParam()->GetMaxDForProlongation()) {
     596          12 :           delete t;
     597           6 :           continue;
     598             :         }       
     599         252 :         if (TMath::Abs(vdist)>AliITSReconstructor::GetRecoParam()->GetMaxDZForProlongation()) {
     600           8 :           delete t;
     601           4 :           continue;
     602             :         }
     603         244 :         if (t->Pt()<minPtCut) {
     604          24 :           delete t;
     605          12 :           continue;
     606             :         }
     607         220 :         if (!CorrectForTPCtoITSDeadZoneMaterial(t)) {
     608           0 :           delete t;
     609           0 :           continue;
     610             :         }
     611             :       }
     612         110 :       t->SetReconstructed(kFALSE);
     613         110 :       itsTracks.AddLast(t);
     614         110 :       fOriginal.AddLast(t);
     615         110 :     }
     616             :   } /* End Read ESD tracks */
     617             : 
     618           8 :   itsTracks.Sort();
     619           8 :   fOriginal.Sort();
     620           8 :   Int_t nentr=itsTracks.GetEntriesFast();
     621           8 :   fTrackHypothesys.Expand(nentr);
     622           8 :   fBestHypothesys.Expand(nentr);
     623           8 :   MakeCoefficients(nentr);
     624          24 :   if(fUseTGeo==3 || fUseTGeo==4) MakeTrksMaterialLUT(event->GetNumberOfTracks());
     625             :   Int_t ntrk=0;
     626             :   // THE TWO TRACKING PASSES
     627          48 :   for (fPass=0; fPass<2; fPass++) {
     628          16 :      Int_t &constraint=fConstraint[fPass]; if (constraint<0) continue;
     629         472 :      for (fCurrentEsdTrack=0; fCurrentEsdTrack<nentr; fCurrentEsdTrack++) {
     630         220 :        AliITStrackMI *t=(AliITStrackMI*)itsTracks.UncheckedAt(fCurrentEsdTrack);
     631         220 :        if (t==0) continue;              //this track has been already tracked
     632             :        //cout<<"========== "<<fPass<<"    "<<fCurrentEsdTrack<<" =========\n";
     633         220 :        if (t->GetReconstructed()&&(t->GetNUsed()<1.5)) continue;  //this track was  already  "succesfully" reconstructed
     634         220 :        Float_t dz[2]={0}; t->GetDZ(GetX(),GetY(),GetZ(),dz);              //I.B.
     635         220 :        if (fConstraint[fPass]) { 
     636         316 :          if (TMath::Abs(dz[0])>AliITSReconstructor::GetRecoParam()->GetMaxDZToUseConstraint() ||
     637         206 :              TMath::Abs(dz[1])>AliITSReconstructor::GetRecoParam()->GetMaxDZToUseConstraint()) continue;
     638             :        }
     639             : 
     640         206 :        Int_t tpcLabel=t->GetLabel(); //save the TPC track label       
     641        1030 :        AliDebug(2,Form("LABEL %d pass %d",tpcLabel,fPass));
     642         206 :        fI = 6;
     643         206 :        ResetTrackToFollow(*t);
     644         206 :        ResetBestTrack();
     645             : 
     646         206 :        FollowProlongationTree(t,fCurrentEsdTrack,fConstraint[fPass]);
     647             :  
     648             : 
     649         206 :        SortTrackHypothesys(fCurrentEsdTrack,20,0);  //MI change
     650             :        //
     651         206 :        AliITStrackMI *besttrack = GetBestHypothesys(fCurrentEsdTrack,t,15);
     652         254 :        if (!besttrack) continue;
     653         158 :        besttrack->SetLabel(tpcLabel);
     654             :        //       besttrack->CookdEdx();
     655         158 :        CookdEdx(besttrack);
     656         158 :        besttrack->SetFakeRatio(1.);
     657         158 :        CookLabel(besttrack,0.); //For comparison only
     658         158 :        UpdateESDtrack(besttrack,AliESDtrack::kITSin);
     659         158 :        t->SetWinner(besttrack);
     660             : 
     661         386 :        if (fConstraint[fPass]&&(!besttrack->IsGoldPrimary())) continue;  //to be tracked also without vertex constrain 
     662             : 
     663          82 :        t->SetReconstructed(kTRUE);
     664          82 :        ntrk++;  
     665         410 :        AliDebug(2,Form("TRACK! (label %d) ncls %d",besttrack->GetLabel(),besttrack->GetNumberOfClusters()));
     666         302 :      }
     667          16 :      GetBestHypothesysMIP(itsTracks); 
     668          16 :   } // end loop on the two tracking passes
     669             :   //
     670           8 :   if (fFlagFakes) FlagFakes(itsTracks);
     671             :   //
     672          16 :   if(event->GetNumberOfV0s()>0) AliITSV0Finder::UpdateTPCV0(event,this);
     673          24 :   if(AliITSReconstructor::GetRecoParam()->GetFindV0s()) AliITSV0Finder::FindV02(event,this);
     674           8 :   fAfterV0 = kTRUE;
     675             :   //
     676           8 :   itsTracks.Clear();
     677             :   //
     678           8 :   Int_t entries = fTrackHypothesys.GetEntriesFast();
     679         228 :   for (Int_t ientry=0; ientry<entries; ientry++) {
     680         212 :     TObjArray * array =(TObjArray*)fTrackHypothesys.At(ientry);
     681         188 :     if (array) array->Delete();
     682         294 :     delete fTrackHypothesys.RemoveAt(ientry); 
     683             :   }
     684             : 
     685           8 :   fTrackHypothesys.Delete();
     686           8 :   entries = fBestHypothesys.GetEntriesFast();
     687         236 :   for (Int_t ientry=0; ientry<entries; ientry++) {
     688         220 :     TObjArray * array =(TObjArray*)fBestHypothesys.At(ientry);
     689         220 :     if (array) array->Delete();
     690         330 :     delete fBestHypothesys.RemoveAt(ientry);
     691             :   }
     692           8 :   fBestHypothesys.Delete();
     693           8 :   fOriginal.Clear();
     694          16 :   delete [] fCoefficients;
     695           8 :   fCoefficients=0;
     696           8 :   DeleteTrksMaterialLUT();
     697             : 
     698          24 :   AliInfo(Form("Number of prolonged tracks: %d out of %d ESD tracks",ntrk,noesd));
     699             : 
     700           8 :   fTrackingPhase="Default";
     701             :   
     702             :   return 0;
     703           8 : }
     704             : //------------------------------------------------------------------------
     705             : Int_t AliITStrackerMI::PropagateBack(AliESDEvent *event) {
     706             :   //--------------------------------------------------------------------
     707             :   // This functions propagates reconstructed ITS tracks back
     708             :   // The clusters must be loaded !
     709             :   //--------------------------------------------------------------------
     710          16 :   fTrackingPhase="PropagateBack";
     711           8 :   Int_t nentr=event->GetNumberOfTracks();
     712             :   //  Info("PropagateBack", "Number of ESD tracks: %d\n", nentr);
     713           8 :   double bz0 = GetBz();
     714             :   const double kWatchStep=10.; // for larger steps watch arc vs segment difference
     715             :   //
     716           8 :   Bool_t checkInv = AliITSReconstructor::GetCheckInvariant(); // off in the special reco mode w/o invariant check
     717             :   Int_t ntrk=0;
     718         320 :   for (Int_t i=0; i<nentr; i++) {
     719         152 :      AliESDtrack *esd=event->GetTrack(i);
     720             : 
     721             :      // Start time integral and add distance from current position to vertex 
     722         152 :      if (esd->GetStatus()&AliESDtrack::kITSout) continue;
     723         152 :      AliITStrackMI t(*esd);
     724         152 :      t.SetCheckInvariant(checkInv);
     725         152 :      Double_t xyzTrk[3]={0},xyzVtx[3]={GetX(),GetY(),GetZ()};
     726         152 :      t.GetXYZ(xyzTrk); 
     727             :      Double_t dst2 = 0.;
     728             :      {
     729         152 :        double dxs = xyzTrk[0] - xyzVtx[0];
     730         152 :        double dys = xyzTrk[1] - xyzVtx[1];
     731         152 :        double dzs = xyzTrk[2] - xyzVtx[2];
     732             :        // RS: for large segment steps d use approximation of cicrular arc s by
     733             :        // s = 2R*asin(d/2R) = d/p asin(p) \approx d/p (p + 1/6 p^3) = d (1+1/6 p^2)
     734             :        // where R is the track radius, p = d/2R = 2C*d (C is the abs curvature)
     735             :        // Hence s^2/d^2 = (1+1/6 p^2)^2
     736         152 :        dst2 = dxs*dxs + dys*dys;
     737         152 :        if (dst2 > kWatchStep*kWatchStep) { // correct circular part for arc/segment factor
     738         120 :          double crv = TMath::Abs(esd->GetC(bz0));
     739          60 :          double fcarc = 1.+crv*crv*dst2/6.;
     740          60 :          dst2 *= fcarc*fcarc;
     741          60 :        }
     742         152 :        dst2 += dzs*dzs;
     743             :      }
     744         152 :      t.StartTimeIntegral();
     745         152 :      t.AddTimeStep(TMath::Sqrt(dst2));
     746             :      //
     747             :      // transfer the time integral to ESD track
     748         152 :      esd->SetStatus(AliESDtrack::kTIME);
     749         152 :      Double_t times[AliPID::kSPECIESC]={0};
     750         152 :      t.GetIntegratedTimes(times,AliPID::kSPECIESC); 
     751         152 :      esd->SetIntegratedTimes(times);
     752         304 :      esd->SetIntegratedLength(t.GetIntegratedLength());
     753             :      //
     754         358 :      if ((esd->GetStatus()&AliESDtrack::kITSin)==0) continue;
     755             : 
     756         196 :      t.SetExpQ(TMath::Max(0.8*t.GetESDtrack()->GetTPCsignal(),30.));
     757          98 :      ResetTrackToFollow(t);
     758             :      //
     759          98 :      fTrackToFollow.ResetCovariance(10.); fTrackToFollow.ResetClusters();
     760         196 :      if (RefitAt(AliITSRecoParam::GetrInsideITSscreen(),&fTrackToFollow,&t)) {
     761         196 :        if (!CorrectForTPCtoITSDeadZoneMaterial(&fTrackToFollow)) continue;
     762             :        //       fTrackToFollow.SetLabel(t.GetLabel());              // why do we neet this
     763             :        //fTrackToFollow.CookdEdx();
     764          98 :        CookLabel(&fTrackToFollow,0.); //For comparison only // why do we need this?
     765          98 :        fTrackToFollow.UpdateESDtrack(AliESDtrack::kITSout);
     766             :        //UseClusters(&fTrackToFollow);
     767          98 :        ntrk++;
     768          98 :      }
     769         250 :   }
     770             : 
     771           8 :   AliInfo(Form("Number of back propagated ITS tracks: %d out of %d ESD tracks",ntrk,nentr));
     772             : 
     773           8 :   fTrackingPhase="Default";
     774             : 
     775           8 :   return 0;
     776           0 : }
     777             : //------------------------------------------------------------------------
     778             : Int_t AliITStrackerMI::RefitInward(AliESDEvent *event) {
     779             :   //--------------------------------------------------------------------
     780             :   // This functions refits ITS tracks using the 
     781             :   // "inward propagated" TPC tracks
     782             :   // The clusters must be loaded !
     783             :   //--------------------------------------------------------------------
     784          16 :   fTrackingPhase="RefitInward";
     785             : 
     786          16 :   if(AliITSReconstructor::GetRecoParam()->GetFindV0s()) AliITSV0Finder::RefitV02(event,this);
     787             : 
     788           8 :   Bool_t doExtra=AliITSReconstructor::GetRecoParam()->GetSearchForExtraClusters();
     789           8 :   if(!doExtra) AliDebug(2,"Do not search for extra clusters");
     790             : 
     791           8 :   Int_t nentr=event->GetNumberOfTracks();
     792             :   //  Info("RefitInward", "Number of ESD tracks: %d\n", nentr);
     793             : 
     794             :   // only for PlaneEff and in case of SPD (for FO studies)
     795           8 :   if( AliITSReconstructor::GetRecoParam()->GetComputePlaneEff() &&
     796           0 :       AliITSReconstructor::GetRecoParam()->GetIPlanePlaneEff()>=0 && 
     797           0 :       AliITSReconstructor::GetRecoParam()->GetIPlanePlaneEff()<2) {
     798           0 :       for (UInt_t i=0; i<AliITSPlaneEffSPD::kNModule*AliITSPlaneEffSPD::kNChip; i++) fSPDChipIntPlaneEff[i]=kFALSE;     
     799           0 :   }
     800             : 
     801           8 :   Bool_t checkInv = AliITSReconstructor::GetCheckInvariant(); // off in the special reco mode w/o invariant check
     802             : 
     803             :   Int_t ntrk=0;
     804         320 :   for (Int_t i=0; i<nentr; i++) {
     805         152 :     AliESDtrack *esd=event->GetTrack(i);
     806             : 
     807         206 :     if ((esd->GetStatus()&AliESDtrack::kITSout) == 0) continue;
     808          98 :     if (esd->GetStatus()&AliESDtrack::kITSrefit) continue;
     809          98 :     if (esd->GetStatus()&AliESDtrack::kTPCout)
     810          82 :       if ((esd->GetStatus()&AliESDtrack::kTPCrefit)==0) continue;
     811             : 
     812          98 :     AliITStrackMI *t = new AliITStrackMI(*esd);
     813          98 :     t->SetCheckInvariant(checkInv);
     814             : 
     815          98 :     t->SetExpQ(TMath::Max(0.8*t->GetESDtrack()->GetTPCsignal(),30.));
     816          98 :     if (!CorrectForTPCtoITSDeadZoneMaterial(t)) {
     817           0 :        delete t;
     818           0 :        continue;
     819             :     }
     820             : 
     821          98 :     ResetTrackToFollow(*t);
     822          98 :     fTrackToFollow.ResetClusters();
     823             : 
     824             :     // ITS standalone tracks
     825          98 :     if ((esd->GetStatus()&AliESDtrack::kTPCin)==0) {
     826          16 :       fTrackToFollow.ResetCovariance(10.);
     827             :       // protection for loopers that can have parameters screwed up
     828          32 :       if(TMath::Abs(fTrackToFollow.GetY())>1000. ||
     829          16 :          TMath::Abs(fTrackToFollow.GetZ())>1000.) {
     830           0 :         delete t;
     831           0 :         continue;
     832             :       }
     833             :     }
     834             : 
     835             :     //Refitting...
     836         196 :     Bool_t pe=(AliITSReconstructor::GetRecoParam()->GetComputePlaneEff() &&
     837           0 :                AliITSReconstructor::GetRecoParam()->GetIPlanePlaneEff()>=0);
     838             : 
     839         294 :     AliDebug(2,Form("Refit LABEL %d  %d",t->GetLabel(),t->GetNumberOfClusters()));
     840          98 :     if (RefitAt(AliITSRecoParam::GetrInsideSPD1(),&fTrackToFollow,t,doExtra,pe)) {
     841         288 :        AliDebug(2,"  refit OK");
     842          96 :        fTrackToFollow.SetLabel(t->GetLabel());
     843             :        //       fTrackToFollow.CookdEdx();
     844          96 :        CookdEdx(&fTrackToFollow);
     845             : 
     846          96 :        CookLabel(&fTrackToFollow,0.0); //For comparison only // RS why do we need this?
     847             : 
     848             :        //The beam pipe
     849         192 :        if (CorrectForPipeMaterial(&fTrackToFollow,"inward")) {
     850          92 :          fTrackToFollow.UpdateESDtrack(AliESDtrack::kITSrefit);
     851          92 :          AliESDtrack  *esdTrack =fTrackToFollow.GetESDtrack();
     852             :          //printf("                                       %d\n",esdTrack->GetITSModuleIndex(0));
     853             :          //esdTrack->UpdateTrackParams(&fTrackToFollow,AliESDtrack::kITSrefit); //original line
     854          92 :          Double_t r[3]={0.,0.,0.};
     855             :          Double_t maxD=3.;
     856          92 :          esdTrack->RelateToVertex(event->GetVertex(),GetBz(r),maxD);
     857          92 :          ntrk++;
     858          92 :        }
     859             :     }
     860         196 :     delete t;
     861          98 :   }
     862             : 
     863           8 :   AliInfo(Form("Number of refitted tracks: %d out of %d ESD tracks",ntrk,nentr));
     864             : 
     865           8 :   fTrackingPhase="Default";
     866             : 
     867           8 :   return 0;
     868           0 : }
     869             : //------------------------------------------------------------------------
     870             : AliCluster *AliITStrackerMI::GetCluster(Int_t index) const {
     871             :   //--------------------------------------------------------------------
     872             :   //       Return pointer to a given cluster
     873             :   //--------------------------------------------------------------------
     874      106276 :   Int_t l=(index & 0xf0000000) >> 28;
     875       53138 :   Int_t c=(index & 0x0fffffff) >> 00;
     876       53138 :   return fgLayers[l].GetCluster(c);
     877             : }
     878             : //------------------------------------------------------------------------
     879             : Bool_t AliITStrackerMI::GetTrackPoint(Int_t index, AliTrackPoint& p) const {
     880             :   //--------------------------------------------------------------------
     881             :   // Get track space point with index i
     882             :   //--------------------------------------------------------------------
     883             : 
     884         534 :   Int_t l=(index & 0xf0000000) >> 28;
     885         267 :   Int_t c=(index & 0x0fffffff) >> 00;
     886         267 :   AliITSRecPoint *cl = fgLayers[l].GetCluster(c);
     887         267 :   Int_t idet = cl->GetDetectorIndex();
     888             : 
     889         267 :   Float_t xyz[3]={0};
     890         267 :   Float_t cov[6]={0};
     891         267 :   cl->GetGlobalXYZ(xyz);
     892         267 :   cl->GetGlobalCov(cov);
     893         267 :   p.SetXYZ(xyz, cov);
     894         267 :   p.SetCharge(cl->GetQ());
     895         267 :   p.SetDriftTime(cl->GetDriftTime());
     896         267 :   p.SetChargeRatio(cl->GetChargeRatio());
     897         267 :   p.SetClusterType(cl->GetClusterType());
     898             :   AliGeomManager::ELayerID iLayer = AliGeomManager::kInvalidLayer; 
     899         267 :   switch (l) {
     900             :   case 0:
     901             :     iLayer = AliGeomManager::kSPD1;
     902          38 :     break;
     903             :   case 1:
     904             :     iLayer = AliGeomManager::kSPD2;
     905          29 :     break;
     906             :   case 2:
     907             :     iLayer = AliGeomManager::kSDD1;
     908          47 :     break;
     909             :   case 3:
     910             :     iLayer = AliGeomManager::kSDD2;
     911          52 :     break;
     912             :   case 4:
     913             :     iLayer = AliGeomManager::kSSD1;
     914          51 :     break;
     915             :   case 5:
     916             :     iLayer = AliGeomManager::kSSD2;
     917          50 :     break;
     918             :   default:
     919           0 :     AliWarning(Form("Wrong layer index in ITS (%d) !",l));
     920           0 :     break;
     921             :   };
     922         267 :   UShort_t volid = AliGeomManager::LayerToVolUID(iLayer,idet);
     923         267 :   p.SetVolumeID((UShort_t)volid);
     924         267 :   return kTRUE;
     925         267 : }
     926             : //------------------------------------------------------------------------
     927             : Bool_t AliITStrackerMI::GetTrackPointTrackingError(Int_t index, 
     928             :                         AliTrackPoint& p, const AliESDtrack *t) {
     929             :   //--------------------------------------------------------------------
     930             :   // Get track space point with index i
     931             :   // (assign error estimated during the tracking)
     932             :   //--------------------------------------------------------------------
     933             : 
     934           0 :   Int_t l=(index & 0xf0000000) >> 28;
     935           0 :   Int_t c=(index & 0x0fffffff) >> 00;
     936           0 :   const AliITSRecPoint *cl = fgLayers[l].GetCluster(c);
     937           0 :   Int_t idet = cl->GetDetectorIndex();
     938             : 
     939           0 :   const AliITSdetector &det=fgLayers[l].GetDetector(idet);
     940             : 
     941             :   // tgphi and tglambda of the track in tracking frame with alpha=det.GetPhi
     942             :   Float_t detxy[2]={0};
     943           0 :   detxy[0] = det.GetR()*TMath::Cos(det.GetPhi());
     944           0 :   detxy[1] = det.GetR()*TMath::Sin(det.GetPhi());
     945           0 :   Double_t alpha = t->GetAlpha();
     946           0 :   Double_t xdetintrackframe = detxy[0]*TMath::Cos(alpha)+detxy[1]*TMath::Sin(alpha);
     947           0 :   Float_t phi = TMath::ASin(t->GetSnpAt(xdetintrackframe+cl->GetX(),GetBz()));
     948           0 :   phi += alpha-det.GetPhi();
     949           0 :   Float_t tgphi = TMath::Tan(phi);
     950             : 
     951           0 :   Float_t tgl = t->GetTgl(); // tgl about const along track
     952           0 :   Float_t expQ = TMath::Max(0.8*t->GetTPCsignal(),30.);
     953             : 
     954           0 :   Float_t errtrky,errtrkz,covyz;
     955             :   Bool_t addMisalErr=kFALSE;
     956           0 :   AliITSClusterParam::GetError(l,cl,tgl,tgphi,expQ,errtrky,errtrkz,covyz,addMisalErr);
     957             : 
     958           0 :   Float_t xyz[3]={0};
     959           0 :   Float_t cov[6]={0};
     960           0 :   cl->GetGlobalXYZ(xyz);
     961             :   //  cl->GetGlobalCov(cov);
     962             :   Float_t pos[3] = {0.,0.,0.};
     963           0 :   AliCluster tmpcl((UShort_t)cl->GetVolumeId(),pos[0],pos[1],pos[2],errtrky*errtrky,errtrkz*errtrkz,covyz);
     964           0 :   tmpcl.GetGlobalCov(cov);
     965             : 
     966           0 :   p.SetXYZ(xyz, cov);
     967           0 :   p.SetCharge(cl->GetQ());
     968           0 :   p.SetDriftTime(cl->GetDriftTime());
     969           0 :   p.SetChargeRatio(cl->GetChargeRatio());
     970           0 :   p.SetClusterType(cl->GetClusterType());
     971             : 
     972             :   AliGeomManager::ELayerID iLayer = AliGeomManager::kInvalidLayer; 
     973           0 :   switch (l) {
     974             :   case 0:
     975             :     iLayer = AliGeomManager::kSPD1;
     976           0 :     break;
     977             :   case 1:
     978             :     iLayer = AliGeomManager::kSPD2;
     979           0 :     break;
     980             :   case 2:
     981             :     iLayer = AliGeomManager::kSDD1;
     982           0 :     break;
     983             :   case 3:
     984             :     iLayer = AliGeomManager::kSDD2;
     985           0 :     break;
     986             :   case 4:
     987             :     iLayer = AliGeomManager::kSSD1;
     988           0 :     break;
     989             :   case 5:
     990             :     iLayer = AliGeomManager::kSSD2;
     991           0 :     break;
     992             :   default:
     993           0 :     AliWarning(Form("Wrong layer index in ITS (%d) !",l));
     994             :     break;
     995             :   };
     996           0 :   UShort_t volid = AliGeomManager::LayerToVolUID(iLayer,idet);
     997             : 
     998           0 :   p.SetVolumeID((UShort_t)volid);
     999             :   return kTRUE;
    1000           0 : }
    1001             : //------------------------------------------------------------------------
    1002             : void AliITStrackerMI::FollowProlongationTree(AliITStrackMI * otrack, Int_t esdindex, Bool_t constrain) 
    1003             : {
    1004             :   //--------------------------------------------------------------------
    1005             :   // Follow prolongation tree
    1006             :   //--------------------------------------------------------------------
    1007             :   //
    1008         206 :   Double_t xyzVtx[]={GetX(),GetY(),GetZ()};
    1009         206 :   Double_t ersVtx[]={GetSigmaX(),GetSigmaY(),GetSigmaZ()};
    1010             : 
    1011             : 
    1012         206 :   AliESDtrack * esd = otrack->GetESDtrack();
    1013         206 :   if (esd->GetV0Index(0)>0) {
    1014             :     // TEMPORARY SOLLUTION: map V0 indexes to point to proper track
    1015             :     //                      mapping of ESD track is different as ITS track in Containers
    1016             :     //                      Need something more stable
    1017             :     //                      Indexes are set back again to the ESD track indexes in UpdateTPCV0
    1018           0 :     for (Int_t i=0;i<3;i++){
    1019           0 :       Int_t  index = esd->GetV0Index(i);
    1020           0 :       if (index==0) break;
    1021           0 :       AliESDv0 * vertex = fEsd->GetV0(index);
    1022           0 :       if (vertex->GetStatus()<0) continue;     // rejected V0
    1023             :       //
    1024           0 :       if (esd->GetSign()>0) {
    1025           0 :         vertex->SetIndex(0,esdindex);
    1026           0 :       } else {
    1027           0 :         vertex->SetIndex(1,esdindex);
    1028             :       }
    1029           0 :     }
    1030           0 :   }
    1031         206 :   TObjArray *bestarray = (TObjArray*)fBestHypothesys.At(esdindex);
    1032         206 :   if (!bestarray){
    1033         110 :     bestarray = new TObjArray(5);
    1034         110 :     bestarray->SetOwner();
    1035         110 :     fBestHypothesys.AddAt(bestarray,esdindex);
    1036         110 :   }
    1037             : 
    1038             :   //
    1039             :   //setup tree of the prolongations
    1040             :   //
    1041             :   const int kMaxTr = 100; //RS
    1042        3010 :   static AliITStrackMI tracks[7][kMaxTr];
    1043             :   AliITStrackMI *currenttrack;
    1044         212 :   static AliITStrackMI currenttrack1;
    1045         212 :   static AliITStrackMI currenttrack2;  
    1046         212 :   static AliITStrackMI backuptrack;
    1047         206 :   Int_t ntracks[7]={0};
    1048         206 :   Int_t nindexes[7][kMaxTr];
    1049         206 :   Float_t normalizedchi2[kMaxTr]={0};
    1050        2884 :   for (Int_t ilayer=0;ilayer<6;ilayer++) ntracks[ilayer]=0;
    1051         206 :   otrack->SetNSkipped(0);
    1052         206 :   new (&(tracks[6][0])) AliITStrackMI(*otrack);
    1053         206 :   ntracks[6]=1;
    1054        3296 :   for (Int_t i=0;i<7;i++) nindexes[i][0]=0;
    1055             :   Int_t modstatus = 1; // found 
    1056         206 :   Float_t xloc,zloc;
    1057             :   // 
    1058             :   //
    1059             :   // follow prolongations
    1060        2884 :   for (Int_t ilayer=5; ilayer>=0; ilayer--) {
    1061        3708 :     AliDebug(2,Form("FollowProlongationTree: layer %d",ilayer));
    1062        1236 :     fI = ilayer;
    1063             :     //
    1064        1236 :     AliITSlayer &layer=fgLayers[ilayer];
    1065        1236 :     Double_t r = layer.GetR(); 
    1066        1236 :     ntracks[ilayer]=0;
    1067             :     //
    1068             :     //
    1069             :     Int_t nskipped=0;
    1070             :     Float_t nused =0;
    1071        9184 :     for (Int_t itrack =0; itrack<ntracks[ilayer+1]; itrack++) {
    1072             :       //      printf("LR %d Tr:%d NSeeds: %d\n",ilayer,itrack,ntracks[ilayer+1]);
    1073             :       //set current track
    1074        2738 :       if (ntracks[ilayer]>=kMaxTr) break;  
    1075        4068 :       if (tracks[ilayer+1][nindexes[ilayer+1][itrack]].GetNSkipped()>0) nskipped++;
    1076        2738 :       if (tracks[ilayer+1][nindexes[ilayer+1][itrack]].GetNUsed()>2.) nused++;
    1077        2738 :       if (ntracks[ilayer]>15+ilayer){
    1078           0 :         if (itrack>1&&tracks[ilayer+1][nindexes[ilayer+1][itrack]].GetNSkipped()>0 && nskipped>4+ilayer) continue;
    1079           0 :         if (itrack>1&&tracks[ilayer+1][nindexes[ilayer+1][itrack]].GetNUsed()>2. && nused>3) continue;
    1080             :       }
    1081             : 
    1082        2738 :       new(&currenttrack1)  AliITStrackMI(tracks[ilayer+1][nindexes[ilayer+1][itrack]]);
    1083             :   
    1084             :       // material between SSD and SDD, SDD and SPD
    1085        2738 :       if (ilayer==3) 
    1086        1314 :         if(!CorrectForShieldMaterial(&currenttrack1,"SDD","inward")) continue;
    1087        2738 :       if (ilayer==1) 
    1088        1764 :         if(!CorrectForShieldMaterial(&currenttrack1,"SPD","inward")) continue;
    1089             : 
    1090             :       // detector number
    1091        2732 :       Double_t phi,z;
    1092        2734 :       if (!currenttrack1.GetPhiZat(r,phi,z)) continue;
    1093        2730 :       Int_t idet=layer.FindDetectorIndex(phi,z);
    1094             : 
    1095        2730 :       Double_t trackGlobXYZ1[3]={0};
    1096        2730 :       if (!currenttrack1.GetXYZ(trackGlobXYZ1)) continue;
    1097             : 
    1098             :       // Get the budget to the primary vertex for the current track being prolonged
    1099             :       Double_t budgetToPrimVertex = 0;
    1100        2730 :       double xMSLrs[9]={0},x2X0MSLrs[9]={0}; // needed for ImproveKalman
    1101             :       int nMSLrs = 0;
    1102             :       //
    1103        2730 :       if (fUseImproveKalman) nMSLrs = GetEffectiveThicknessLbyL(xMSLrs,x2X0MSLrs);
    1104        2730 :       else budgetToPrimVertex = GetEffectiveThickness();
    1105             :       //
    1106             :       // check if we allow a prolongation without point
    1107        2730 :       Int_t skip = CheckSkipLayer(&currenttrack1,ilayer,idet);
    1108        2730 :       if (skip) {
    1109           4 :         AliITStrackMI* vtrack = new (&tracks[ilayer][ntracks[ilayer]]) AliITStrackMI(currenttrack1);
    1110             :         // propagate to the layer radius
    1111           4 :         Double_t xToGo; if (!vtrack->GetLocalXat(r,xToGo)) continue;
    1112           4 :         if(!vtrack->Propagate(xToGo)) continue;
    1113             :         // apply correction for material of the current layer
    1114           8 :         CorrectForLayerMaterial(vtrack,ilayer,trackGlobXYZ1,"inward");
    1115           4 :         vtrack->SetNDeadZone(vtrack->GetNDeadZone()+1);
    1116           4 :         vtrack->SetDeadZoneProbability(ilayer,1.); // no penalty for missing cluster
    1117           4 :         vtrack->SetClIndex(ilayer,-1);
    1118           4 :         modstatus = (skip==1 ? 3 : 4); // skipped : out in z
    1119           4 :         if(LocalModuleCoord(ilayer,idet,vtrack,xloc,zloc)) { // local module coords
    1120           4 :           vtrack->SetModuleIndexInfo(ilayer,idet,modstatus,xloc,zloc);
    1121           4 :         }
    1122           4 :         if(constrain && AliITSReconstructor::GetRecoParam()->GetImproveWithVertex()) {
    1123           0 :           fUseImproveKalman ? 
    1124           0 :             vtrack->ImproveKalman(xyzVtx,ersVtx,xMSLrs,x2X0MSLrs,nMSLrs) : 
    1125           0 :             vtrack->Improve(budgetToPrimVertex,xyzVtx,ersVtx);
    1126             :         }
    1127           4 :         ntracks[ilayer]++;
    1128           4 :         continue;
    1129           4 :       }
    1130             : 
    1131             :       // track outside layer acceptance in z
    1132        2726 :       if (idet<0) continue;
    1133             :       
    1134             :       //propagate to the intersection with the detector plane
    1135        2726 :       const AliITSdetector &det=layer.GetDetector(idet);
    1136        2726 :       new(&currenttrack2)  AliITStrackMI(currenttrack1);
    1137        2726 :       if (!currenttrack1.Propagate(det.GetPhi(),det.GetR())) continue;
    1138        2726 :       if (!currenttrack2.Propagate(det.GetPhi(),det.GetR())) continue;
    1139        2726 :       currenttrack1.SetDetectorIndex(idet);
    1140        2726 :       currenttrack2.SetDetectorIndex(idet);
    1141        2726 :       if(!LocalModuleCoord(ilayer,idet,&currenttrack1,xloc,zloc)) continue; // local module coords
    1142             : 
    1143             :       //***************
    1144             :       // DEFINITION OF SEARCH ROAD AND CLUSTERS SELECTION
    1145             :       //
    1146             :       // road in global (rphi,z) [i.e. in tracking ref. system]
    1147        2726 :       Double_t zmin,zmax,ymin,ymax;
    1148        2726 :       if (!ComputeRoad(&currenttrack1,ilayer,idet,zmin,zmax,ymin,ymax)) continue;
    1149             : 
    1150             :       // select clusters in road
    1151        2726 :       layer.SelectClusters(zmin,zmax,ymin,ymax); 
    1152             :       //********************
    1153             : 
    1154             :       // Define criteria for track-cluster association
    1155        5452 :       Double_t msz = currenttrack1.GetSigmaZ2() + 
    1156        5452 :         AliITSReconstructor::GetRecoParam()->GetNSigmaZLayerForRoadZ()*
    1157        5452 :         AliITSReconstructor::GetRecoParam()->GetNSigmaZLayerForRoadZ()*
    1158        2726 :         AliITSReconstructor::GetRecoParam()->GetSigmaZ2(ilayer);
    1159        5452 :       Double_t msy = currenttrack1.GetSigmaY2() + 
    1160        5452 :         AliITSReconstructor::GetRecoParam()->GetNSigmaYLayerForRoadY()*
    1161        5452 :         AliITSReconstructor::GetRecoParam()->GetNSigmaYLayerForRoadY()*
    1162        2726 :         AliITSReconstructor::GetRecoParam()->GetSigmaY2(ilayer);
    1163        5452 :       if (constrain) {
    1164        4726 :         msz *= AliITSReconstructor::GetRecoParam()->GetNSigma2RoadZC();
    1165        2000 :         msy *= AliITSReconstructor::GetRecoParam()->GetNSigma2RoadYC(); 
    1166        2000 :       }  else {
    1167         726 :         msz *= AliITSReconstructor::GetRecoParam()->GetNSigma2RoadZNonC();
    1168         726 :         msy *= AliITSReconstructor::GetRecoParam()->GetNSigma2RoadYNonC(); 
    1169             :       }
    1170        2726 :       msz = 1./msz; // 1/RoadZ^2
    1171        2726 :       msy = 1./msy; // 1/RoadY^2
    1172             : 
    1173             :       //
    1174             :       //
    1175             :       // LOOP OVER ALL POSSIBLE TRACK PROLONGATIONS ON THIS LAYER
    1176             :       //
    1177             :       const AliITSRecPoint *cl=0; 
    1178        2726 :       Int_t clidx=-1;
    1179        2726 :       Double_t chi2trkcl=AliITSReconstructor::GetRecoParam()->GetMaxChi2(); // init with big value
    1180             :       Bool_t deadzoneSPD=kFALSE;
    1181             :       currenttrack = &currenttrack1;
    1182             : 
    1183             :       // check if the road contains a dead zone 
    1184             :       Bool_t noClusters = kFALSE;
    1185        2880 :       if (!layer.GetNextCluster(clidx,kTRUE)) noClusters=kTRUE;
    1186        3188 :       if (noClusters) AliDebug(2,"no clusters in road");
    1187        2726 :       Double_t dz=0.5*(zmax-zmin);
    1188        2726 :       Double_t dy=0.5*(ymax-ymin);
    1189        2726 :       Int_t dead = CheckDeadZone(&currenttrack1,ilayer,idet,dz,dy,noClusters); 
    1190        3860 :       if(dead) AliDebug(2,Form("DEAD (%d)\n",dead));
    1191             :       // create a prolongation without clusters (check also if there are no clusters in the road)
    1192        2784 :       if (dead || 
    1193        2348 :           (noClusters && 
    1194          58 :            AliITSReconstructor::GetRecoParam()->GetAllowProlongationWithEmptyRoad())) {
    1195         436 :         AliITStrackMI * updatetrack = new (&tracks[ilayer][ntracks[ilayer]]) AliITStrackMI(*currenttrack);
    1196         436 :         updatetrack->SetClIndex(ilayer,-1);
    1197         436 :         if (dead==0) {
    1198             :           modstatus = 5; // no cls in road
    1199         436 :         } else if (dead==1) {
    1200             :           modstatus = 7; // holes in z in SPD
    1201         378 :         } else if (dead==2 || dead==3 || dead==4) {
    1202             :           modstatus = 2; // dead from OCDB
    1203          96 :         }
    1204         436 :         updatetrack->SetModuleIndexInfo(ilayer,idet,modstatus,xloc,zloc);
    1205             :         // apply correction for material of the current layer
    1206         872 :         CorrectForLayerMaterial(updatetrack,ilayer,trackGlobXYZ1,"inward");
    1207         436 :         if (constrain) { // apply vertex constrain
    1208         326 :           updatetrack->SetConstrain(constrain);
    1209             :           Bool_t isPrim = kTRUE;
    1210         326 :           if (ilayer<4) { // check that it's close to the vertex
    1211         306 :             updatetrack->GetDZ(GetX(),GetY(),GetZ(),updatetrack->GetDP()); //I.B.
    1212         914 :             if (TMath::Abs(updatetrack->GetD(0)/(1.+ilayer)) > // y
    1213         612 :                 AliITSReconstructor::GetRecoParam()->GetMaxDZforPrimTrk() || 
    1214         604 :                 TMath::Abs(updatetrack->GetD(1)/(1.+ilayer)) > // z
    1215         306 :                 AliITSReconstructor::GetRecoParam()->GetMaxDZforPrimTrk()) isPrim=kFALSE;
    1216             :           }
    1217         648 :           if (isPrim && AliITSReconstructor::GetRecoParam()->GetImproveWithVertex()) {
    1218           0 :             fUseImproveKalman ? 
    1219           0 :               updatetrack->ImproveKalman(xyzVtx,ersVtx,xMSLrs,x2X0MSLrs,nMSLrs) : 
    1220           0 :               updatetrack->Improve(budgetToPrimVertex,xyzVtx,ersVtx);
    1221             :           }
    1222         326 :         }
    1223         436 :         updatetrack->SetNDeadZone(updatetrack->GetNDeadZone()+1);
    1224         436 :         if (dead) {
    1225         378 :           if (dead==1) { // dead zone at z=0,+-7cm in SPD
    1226         282 :             updatetrack->SetDeadZoneProbability(ilayer,GetSPDDeadZoneProbability(updatetrack->GetZ(),TMath::Sqrt(updatetrack->GetSigmaZ2())));
    1227             :             deadzoneSPD=kTRUE;
    1228         378 :           } else if (dead==2 || dead==3) { // dead module or chip from OCDB  
    1229          64 :             updatetrack->SetDeadZoneProbability(ilayer,1.); 
    1230          96 :           } else if (dead==4) { // at least a single dead channel from OCDB  
    1231          32 :             updatetrack->SetDeadZoneProbability(ilayer,0.); 
    1232          32 :           } 
    1233             :         }
    1234         436 :         ntracks[ilayer]++;
    1235         436 :       }
    1236             : 
    1237        2726 :       clidx=-1;
    1238             :       // loop over clusters in the road
    1239        8654 :       while ((cl=layer.GetNextCluster(clidx))!=0) { 
    1240        3202 :         if (ntracks[ilayer]>int(0.95*kMaxTr)) break; //space for skipped clusters  
    1241             :         Bool_t changedet =kFALSE;  
    1242        3202 :         if (TMath::Abs(cl->GetQ())<1.e-13 && deadzoneSPD==kTRUE) continue;
    1243        3202 :         Int_t idetc=cl->GetDetectorIndex();
    1244             : 
    1245        3202 :         if (currenttrack->GetDetectorIndex()==idetc) { // track already on the cluster's detector
    1246             :           // take into account misalignment (bring track to real detector plane)
    1247        2466 :           Double_t xTrOrig = currenttrack->GetX();
    1248        2466 :           if (!currenttrack->Propagate(xTrOrig+cl->GetX())) continue;
    1249             :           // a first cut on track-cluster distance
    1250        7398 :           if ( (currenttrack->GetZ()-cl->GetZ())*(currenttrack->GetZ()-cl->GetZ())*msz + 
    1251        4932 :                (currenttrack->GetY()-cl->GetY())*(currenttrack->GetY()-cl->GetY())*msy > 1. ) 
    1252             :             {  // cluster not associated to track
    1253        1224 :               AliDebug(2,"not associated");
    1254             :               // MvL: added here as well
    1255             :               // bring track back to ideal detector plane
    1256         408 :               currenttrack->Propagate(xTrOrig);
    1257         408 :               continue;
    1258             :             }
    1259             :           // bring track back to ideal detector plane
    1260        2058 :           if (!currenttrack->Propagate(xTrOrig)) continue;
    1261        2058 :         } else {                                      // have to move track to cluster's detector
    1262         736 :           const AliITSdetector &detc=layer.GetDetector(idetc);
    1263             :           // a first cut on track-cluster distance
    1264         736 :           Double_t y;
    1265         736 :           if (!currenttrack2.GetProlongationFast(detc.GetPhi(),detc.GetR()+cl->GetX(),y,z)) continue;
    1266        2208 :           if ( (z-cl->GetZ())*(z-cl->GetZ())*msz + 
    1267        1472 :                (y-cl->GetY())*(y-cl->GetY())*msy > 1. ) 
    1268         316 :             continue; // cluster not associated to track
    1269             :           //
    1270         420 :           new (&backuptrack) AliITStrackMI(currenttrack2);
    1271             :           changedet = kTRUE;
    1272             :           currenttrack =&currenttrack2;
    1273         420 :           if (!currenttrack->Propagate(detc.GetPhi(),detc.GetR())) {
    1274           0 :             new (currenttrack) AliITStrackMI(backuptrack);
    1275             :             changedet = kFALSE;
    1276           0 :             continue;
    1277             :           }
    1278         420 :           currenttrack->SetDetectorIndex(idetc);
    1279             :           // Get again the budget to the primary vertex 
    1280             :           // for the current track being prolonged, if had to change detector 
    1281             :           //budgetToPrimVertex = GetEffectiveThickness();// not needed at the moment because anyway we take a mean material for this correction
    1282        1156 :         }
    1283             : 
    1284             :         // calculate track-clusters chi2
    1285        2478 :         chi2trkcl = GetPredictedChi2MI(currenttrack,cl,ilayer); 
    1286             :         // chi2 cut
    1287        7434 :         AliDebug(2,Form("chi2 %f max %f",chi2trkcl,AliITSReconstructor::GetRecoParam()->GetMaxChi2s(ilayer)));
    1288        2478 :         if (chi2trkcl < AliITSReconstructor::GetRecoParam()->GetMaxChi2s(ilayer)) {
    1289        2378 :           if (TMath::Abs(cl->GetQ())<1.e-13) deadzoneSPD=kTRUE; // only 1 prolongation with virtual cluster         
    1290        2378 :           if (ntracks[ilayer]>=kMaxTr) continue;
    1291        2378 :           AliITStrackMI * updatetrack = new (&tracks[ilayer][ntracks[ilayer]]) AliITStrackMI(*currenttrack);
    1292        2378 :           updatetrack->SetClIndex(ilayer,-1);
    1293        2772 :           if (changedet) new (&currenttrack2) AliITStrackMI(backuptrack);
    1294             : 
    1295        2378 :           if (TMath::Abs(cl->GetQ())>1.e-13) { // real cluster
    1296        2378 :             if (!UpdateMI(updatetrack,cl,chi2trkcl,(ilayer<<28)+clidx)) {
    1297           0 :               AliDebug(2,"update failed");
    1298           0 :               continue;
    1299             :             } 
    1300        2378 :             updatetrack->SetSampledEdx(cl->GetQ(),ilayer-2); 
    1301             :             modstatus = 1; // found
    1302        2378 :           } else {             // virtual cluster in dead zone
    1303           0 :             updatetrack->SetNDeadZone(updatetrack->GetNDeadZone()+1);
    1304           0 :             updatetrack->SetDeadZoneProbability(ilayer,GetSPDDeadZoneProbability(updatetrack->GetZ(),TMath::Sqrt(updatetrack->GetSigmaZ2())));
    1305             :             modstatus = 7; // holes in z in SPD
    1306             :           }
    1307             : 
    1308        2378 :           if (changedet) {
    1309         394 :             Float_t xlocnewdet,zlocnewdet;
    1310         394 :             if(LocalModuleCoord(ilayer,idet,updatetrack,xlocnewdet,zlocnewdet)) { // local module coords
    1311         394 :               updatetrack->SetModuleIndexInfo(ilayer,idet,modstatus,xlocnewdet,zlocnewdet);
    1312         394 :             }
    1313         394 :           } else {
    1314        1984 :             updatetrack->SetModuleIndexInfo(ilayer,idet,modstatus,xloc,zloc);
    1315             :           }
    1316        2378 :           if (cl->IsUsed()) updatetrack->IncrementNUsed();
    1317             : 
    1318             :           // apply correction for material of the current layer
    1319        4756 :           CorrectForLayerMaterial(updatetrack,ilayer,trackGlobXYZ1,"inward");
    1320             : 
    1321        2378 :           if (constrain) { // apply vertex constrain
    1322        1726 :             updatetrack->SetConstrain(constrain);
    1323             :             Bool_t isPrim = kTRUE;
    1324        1726 :             if (ilayer<4) { // check that it's close to the vertex
    1325        1370 :               updatetrack->GetDZ(GetX(),GetY(),GetZ(),updatetrack->GetDP()); //I.B.
    1326        4110 :               if (TMath::Abs(updatetrack->GetD(0)/(1.+ilayer)) > // y
    1327        2740 :                   AliITSReconstructor::GetRecoParam()->GetMaxDZforPrimTrk() || 
    1328        2740 :                   TMath::Abs(updatetrack->GetD(1)/(1.+ilayer)) > // z
    1329        1370 :                   AliITSReconstructor::GetRecoParam()->GetMaxDZforPrimTrk()) isPrim=kFALSE;
    1330             :             }
    1331        3452 :             if (isPrim && AliITSReconstructor::GetRecoParam()->GetImproveWithVertex()) {
    1332           0 :               fUseImproveKalman ? 
    1333           0 :                 updatetrack->ImproveKalman(xyzVtx,ersVtx,xMSLrs,x2X0MSLrs,nMSLrs) : 
    1334           0 :                 updatetrack->Improve(budgetToPrimVertex,xyzVtx,ersVtx);
    1335             :             }
    1336        1726 :           } //apply vertex constrain              
    1337        2378 :           ntracks[ilayer]++;
    1338        2378 :         }  // create new hypothesis
    1339             :         else {
    1340         300 :           AliDebug(2,"chi2 too large");
    1341             :         }
    1342             : 
    1343        2478 :       } // loop over possible prolongations 
    1344             :      
    1345             :       // allow one prolongation without clusters
    1346        4814 :       if (constrain && itrack<=1 && TMath::Abs(currenttrack1.GetNSkipped())<1.e-13 && deadzoneSPD==kFALSE && ntracks[ilayer]<kMaxTr) {
    1347         554 :         AliITStrackMI* vtrack = new (&tracks[ilayer][ntracks[ilayer]]) AliITStrackMI(currenttrack1);
    1348             :         // apply correction for material of the current layer
    1349        1108 :         CorrectForLayerMaterial(vtrack,ilayer,trackGlobXYZ1,"inward");
    1350         554 :         vtrack->SetClIndex(ilayer,-1);
    1351             :         modstatus = 3; // skipped 
    1352         554 :         vtrack->SetModuleIndexInfo(ilayer,idet,modstatus,xloc,zloc);
    1353         554 :         if(AliITSReconstructor::GetRecoParam()->GetImproveWithVertex()) {
    1354           0 :           fUseImproveKalman ? 
    1355           0 :             vtrack->ImproveKalman(xyzVtx,ersVtx,xMSLrs,x2X0MSLrs,nMSLrs) : 
    1356           0 :             vtrack->Improve(budgetToPrimVertex,xyzVtx,ersVtx);
    1357             :         }
    1358         554 :         vtrack->IncrementNSkipped();
    1359         554 :         ntracks[ilayer]++;
    1360         554 :       }
    1361             :       
    1362             : 
    1363       13644 :     } // loop over tracks in layer ilayer+1
    1364             : 
    1365             :     //loop over track candidates for the current layer
    1366             :     //
    1367             :     //
    1368             :     Int_t accepted=0;
    1369             :     
    1370             :     Int_t golden=0;
    1371        9216 :     for (Int_t itrack=0;itrack<ntracks[ilayer];itrack++){
    1372        3372 :       normalizedchi2[itrack] = NormalizedChi2(&tracks[ilayer][itrack],ilayer); 
    1373        6744 :       if (normalizedchi2[itrack] < 
    1374        5125 :           AliITSReconstructor::GetRecoParam()->GetMaxNormChi2ForGolden(ilayer)) golden++;
    1375        3372 :       if (ilayer>4) {
    1376         378 :         accepted++;
    1377         378 :       } else {
    1378        5988 :         if (constrain) { // constrain
    1379        5374 :           if (normalizedchi2[itrack]<AliITSReconstructor::GetRecoParam()->GetMaxNormChi2C(ilayer)+1) 
    1380        2312 :             accepted++;
    1381             :         } else {        // !constrain
    1382         614 :           if (normalizedchi2[itrack]<AliITSReconstructor::GetRecoParam()->GetMaxNormChi2NonC(ilayer)+1) 
    1383         580 :             accepted++;
    1384             :         }
    1385             :       }
    1386             :     }
    1387             :     // sort tracks by increasing normalized chi2
    1388        1236 :     TMath::Sort(ntracks[ilayer],normalizedchi2,nindexes[ilayer],kFALSE); 
    1389        1236 :     ntracks[ilayer] = TMath::Min(accepted,7+2*ilayer);
    1390        2302 :     if (ntracks[ilayer]<golden+2+ilayer) ntracks[ilayer]=TMath::Min(golden+2+ilayer,accepted);
    1391             :     //    if (ntracks[ilayer]>90) ntracks[ilayer]=90; 
    1392        1236 :     if (ntracks[ilayer]>int(kMaxTr*0.9)) ntracks[ilayer]=int(kMaxTr*0.9); 
    1393             :   } // end loop over layers
    1394             : 
    1395             : 
    1396             :   //
    1397             :   // Now select tracks to be kept
    1398             :   //
    1399         206 :   Int_t max = constrain ? 20 : 5;
    1400             : 
    1401             :   // tracks that reach layer 0 (SPD inner)
    1402        1648 :   for (Int_t i=0; i<TMath::Min(max,ntracks[0]); i++) {
    1403         618 :     AliITStrackMI & track= tracks[0][nindexes[0][i]];
    1404         624 :     if (track.GetNumberOfClusters()<2) continue;
    1405         816 :     if (!constrain && track.GetNormChi2(0) >
    1406         102 :         AliITSReconstructor::GetRecoParam()->GetMaxNormChi2NonCForHypothesis()) {
    1407           0 :       continue;
    1408             :     }
    1409        1224 :     AddTrackHypothesys(new AliITStrackMI(track), esdindex);
    1410         612 :   }
    1411             : 
    1412             :   // tracks that reach layer 1 (SPD outer)
    1413         920 :   for (Int_t i=0;i<TMath::Min(2,ntracks[1]);i++) {
    1414         254 :     AliITStrackMI & track= tracks[1][nindexes[1][i]];
    1415         276 :     if (track.GetNumberOfClusters()<4) continue;
    1416         424 :     if (!constrain && track.GetNormChi2(1) >
    1417          96 :         AliITSReconstructor::GetRecoParam()->GetMaxNormChi2NonCForHypothesis()) continue;
    1418         368 :     if (constrain) track.IncrementNSkipped();
    1419         232 :     if (!constrain) {
    1420          96 :       track.SetD(0,track.GetD(GetX(),GetY()));   
    1421          96 :       track.SetNSkipped(track.GetNSkipped()+4./(4.+8.*TMath::Abs(track.GetD(0))));
    1422          96 :       if (track.GetNumberOfClusters()+track.GetNDeadZone()+track.GetNSkipped()>6) {
    1423           0 :         track.SetNSkipped(6-track.GetNumberOfClusters()+track.GetNDeadZone());
    1424           0 :       }
    1425             :     }
    1426         464 :     AddTrackHypothesys(new AliITStrackMI(track), esdindex);
    1427         232 :   }
    1428             : 
    1429             :   // tracks that reach layer 2 (SDD inner), only during non-constrained pass
    1430         206 :   if (!constrain){  
    1431         444 :     for (Int_t i=0;i<TMath::Min(2,ntracks[2]);i++) {
    1432         112 :       AliITStrackMI & track= tracks[2][nindexes[2][i]];
    1433         118 :       if (track.GetNumberOfClusters()<3) continue;
    1434         212 :       if (track.GetNormChi2(2) >
    1435         106 :           AliITSReconstructor::GetRecoParam()->GetMaxNormChi2NonCForHypothesis()) continue;
    1436         106 :       track.SetD(0,track.GetD(GetX(),GetY()));
    1437         106 :       track.SetNSkipped(track.GetNSkipped()+7./(7.+8.*TMath::Abs(track.GetD(0))));
    1438         106 :       if (track.GetNumberOfClusters()+track.GetNDeadZone()+track.GetNSkipped()>6) {
    1439           0 :         track.SetNSkipped(6-track.GetNumberOfClusters()+track.GetNDeadZone());
    1440           0 :       }
    1441         212 :       AddTrackHypothesys(new AliITStrackMI(track), esdindex);
    1442         106 :     }
    1443         110 :   }
    1444             :   
    1445         206 :   if (!constrain) {
    1446             :     //
    1447             :     // register best track of each layer - important for V0 finder
    1448             :     //
    1449        1320 :     for (Int_t ilayer=0;ilayer<5;ilayer++){
    1450         550 :       if (ntracks[ilayer]==0) continue;
    1451         420 :       AliITStrackMI & track= tracks[ilayer][nindexes[ilayer][0]];
    1452         426 :       if (track.GetNumberOfClusters()<1) continue;
    1453         414 :       CookLabel(&track,0);
    1454         828 :       bestarray->AddAt(new AliITStrackMI(track),ilayer);
    1455         414 :     }
    1456         110 :   }
    1457             :   //
    1458             :   // update TPC V0 information
    1459             :   //
    1460         206 :   if (otrack->GetESDtrack()->GetV0Index(0)>0){    
    1461           0 :     Float_t fprimvertex[3]={static_cast<Float_t>(GetX()),static_cast<Float_t>(GetY()),static_cast<Float_t>(GetZ())};
    1462           0 :     for (Int_t i=0;i<3;i++){
    1463           0 :       Int_t  index = otrack->GetESDtrack()->GetV0Index(i); 
    1464           0 :       if (index==0) break;
    1465           0 :       AliV0 *vertex = (AliV0*)fEsd->GetV0(index);
    1466           0 :       if (vertex->GetStatus()<0) continue;     // rejected V0
    1467             :       //
    1468           0 :       if (otrack->GetSign()>0) {
    1469           0 :         vertex->SetIndex(0,esdindex);
    1470           0 :       }
    1471             :       else{
    1472           0 :         vertex->SetIndex(1,esdindex);
    1473             :       }
    1474             :       //find nearest layer with track info
    1475           0 :       Double_t xrp[3]={0}; vertex->GetXYZ(xrp[0],xrp[1],xrp[2]);  //I.B.
    1476           0 :       Int_t nearestold  = GetNearestLayer(xrp);               //I.B.
    1477             :       Int_t nearest     = nearestold; 
    1478           0 :       for (Int_t ilayer =nearest;ilayer<7;ilayer++){
    1479           0 :         if (ntracks[nearest]==0){
    1480             :           nearest = ilayer;
    1481           0 :         }
    1482             :       }
    1483             :       //
    1484           0 :       AliITStrackMI & track= tracks[nearest][nindexes[nearest][0]];
    1485           0 :       if (nearestold<5&&nearest<5){
    1486           0 :         Bool_t accept = track.GetNormChi2(nearest)<10; 
    1487           0 :         if (accept){
    1488           0 :           if (track.GetSign()>0) {
    1489           0 :             vertex->SetParamP(track);
    1490           0 :             vertex->Update(fprimvertex);
    1491             :             //vertex->SetIndex(0,track.fESDtrack->GetID()); 
    1492           0 :             if (track.GetNumberOfClusters()>2) AddTrackHypothesys(new AliITStrackMI(track), esdindex);
    1493             :           }else{
    1494           0 :             vertex->SetParamN(track);
    1495           0 :             vertex->Update(fprimvertex);
    1496             :             //vertex->SetIndex(1,track.fESDtrack->GetID());
    1497           0 :             if (track.GetNumberOfClusters()>2) AddTrackHypothesys(new AliITStrackMI(track), esdindex);
    1498             :           }
    1499           0 :           vertex->SetStatus(vertex->GetStatus()+1);
    1500           0 :         }else{
    1501             :           //vertex->SetStatus(-2);  // reject V0  - not enough clusters
    1502             :         }
    1503           0 :       }
    1504           0 :     }
    1505           0 :   } 
    1506             :   
    1507        1612 : }
    1508             : //------------------------------------------------------------------------
    1509             : AliITStrackerMI::AliITSlayer & AliITStrackerMI::GetLayer(Int_t layer) const
    1510             : {
    1511             :   //--------------------------------------------------------------------
    1512             :   //
    1513             :   //
    1514         100 :   return fgLayers[layer];
    1515             : }
    1516             : //------------------------------------------------------------------------
    1517             : AliITStrackerMI::AliITSlayer::AliITSlayer():
    1518         708 : fR(0),
    1519         354 : fPhiOffset(0),
    1520         354 : fNladders(0),
    1521         354 : fZOffset(0),
    1522         354 : fNdetectors(0),
    1523         354 : fDetectors(0),
    1524         354 : fN(0),
    1525         354 : fDy5(0),
    1526         354 : fDy10(0),
    1527         354 : fDy20(0),
    1528         354 : fClustersCs(0),
    1529         354 : fClusterIndexCs(0),
    1530         354 : fYcs(0),
    1531         354 : fZcs(0),
    1532         354 : fNcs(0),
    1533         354 : fCurrentSlice(-1),
    1534         354 : fZmin(0),
    1535         354 : fZmax(0),
    1536         354 : fYmin(0),
    1537         354 : fYmax(0),
    1538         354 : fI(0),
    1539         354 : fImax(0),
    1540         354 : fSkip(0),
    1541         354 : fAccepted(0),
    1542         354 : fRoad(0),
    1543         354 : fMaxSigmaClY(0),
    1544         354 : fMaxSigmaClZ(0),
    1545         354 : fNMaxSigmaCl(3)
    1546         708 : {
    1547             :   //--------------------------------------------------------------------
    1548             :   //default AliITSlayer constructor
    1549             :   //--------------------------------------------------------------------
    1550             :   //
    1551             :   // RS speedup reseting
    1552             :   //  memset(fClusterWeight,0,sizeof(Float_t)*AliITSRecoParam::kMaxClusterPerLayer);
    1553         354 :   memset(fClusterTracks,0,sizeof(UShort_t)*AliITSRecoParam::kMaxClusterPerLayer*4);
    1554         354 :   memset(fY,0,sizeof(Float_t)*AliITSRecoParam::kMaxClusterPerLayer);
    1555         354 :   memset(fZ,0,sizeof(Float_t)*AliITSRecoParam::kMaxClusterPerLayer);
    1556             :   /*
    1557             :   for (Int_t i=0; i<AliITSRecoParam::GetMaxClusterPerLayer(); i++) {
    1558             :     fClusterWeight[i]=0;
    1559             :     fClusterTracks[0][i]=-1;
    1560             :     fClusterTracks[1][i]=-1;
    1561             :     fClusterTracks[2][i]=-1;    
    1562             :     fClusterTracks[3][i]=-1;
    1563             :     fY[i]=0;    
    1564             :     fZ[i]=0;    
    1565             :   }
    1566             :   */
    1567         354 :   fYB[0]=0;
    1568         354 :   fYB[1]=0;
    1569             : 
    1570     9063108 :   for (Int_t j=0; j<AliITSRecoParam::kMaxClusterPerLayer5; j++) {
    1571    63436800 :     for (Int_t j1=0; j1<6; j1++) {
    1572    27187200 :       fClusters5[j1][j]=0;
    1573    27187200 :       fClusterIndex5[j1][j]=0;//RS -1;
    1574    27187200 :       fY5[j1][j]=0;
    1575    27187200 :       fZ5[j1][j]=0;
    1576    27187200 :       fN5[j1]=0;
    1577    27187200 :       fBy5[j1][0]=0;
    1578    27187200 :       fBy5[j1][1]=0;
    1579             :     }
    1580             :   }
    1581             : 
    1582     4531908 :   for (Int_t j=0; j<AliITSRecoParam::kMaxClusterPerLayer10; j++) {
    1583    54374400 :     for (Int_t j1=0; j1<11; j1++) {
    1584    24921600 :       fClusters10[j1][j]=0;
    1585    24921600 :       fClusterIndex10[j1][j]=0;//RS-1;
    1586    24921600 :       fY10[j1][j]=0;
    1587    24921600 :       fZ10[j1][j]=0;
    1588    24921600 :       fN10[j1]=0;
    1589    24921600 :       fBy10[j1][0]=0;
    1590    24921600 :       fBy10[j1][1]=0;
    1591             :     }
    1592             :   }
    1593             : 
    1594     2266308 :   for (Int_t j=0; j<AliITSRecoParam::kMaxClusterPerLayer20; j++) {
    1595    49843200 :     for (Int_t j1=0; j1<21; j1++) {
    1596    23788800 :       fClusters20[j1][j]=0;
    1597    23788800 :       fClusterIndex20[j1][j]=0;//RS-1;
    1598    23788800 :       fY20[j1][j]=0;
    1599    23788800 :       fZ20[j1][j]=0;
    1600    23788800 :       fN20[j1]=0;
    1601    23788800 :       fBy20[j1][0]=0;
    1602    23788800 :       fBy20[j1][1]=0;
    1603             :     }
    1604             :   }
    1605    22656708 :   for(Int_t i=0;i<AliITSRecoParam::kMaxClusterPerLayer;i++){
    1606    11328000 :     fClusters[i]=NULL;
    1607    11328000 :     fClusterIndex[i]=0;
    1608             :   }
    1609         708 : }
    1610             : //------------------------------------------------------------------------
    1611             : AliITStrackerMI::AliITSlayer::
    1612             : AliITSlayer(Double_t r,Double_t p,Double_t z,Int_t nl,Int_t nd):
    1613          24 : fR(r),
    1614          12 : fPhiOffset(p),
    1615          12 : fNladders(nl),
    1616          12 : fZOffset(z),
    1617          12 : fNdetectors(nd),
    1618          12 : fDetectors(0),
    1619          12 : fN(0),
    1620          12 : fDy5(0),
    1621          12 : fDy10(0),
    1622          12 : fDy20(0),
    1623          12 : fClustersCs(0),
    1624          12 : fClusterIndexCs(0),
    1625          12 : fYcs(0),
    1626          12 : fZcs(0),
    1627          12 : fNcs(0),
    1628          12 : fCurrentSlice(-1),
    1629          12 : fZmin(0),
    1630          12 : fZmax(0),
    1631          12 : fYmin(0),
    1632          12 : fYmax(0),
    1633          12 : fI(0),
    1634          12 : fImax(0),
    1635          12 : fSkip(0),
    1636          12 : fAccepted(0),
    1637          12 : fRoad(0),
    1638          12 : fMaxSigmaClY(0),
    1639          12 : fMaxSigmaClZ(0),
    1640          36 : fNMaxSigmaCl(3) {
    1641             :   //--------------------------------------------------------------------
    1642             :   //main AliITSlayer constructor
    1643             :   //--------------------------------------------------------------------
    1644        8828 :   fDetectors=new AliITSdetector[fNladders*fNdetectors];
    1645          12 :   fRoad=2*fR*TMath::Sqrt(TMath::Pi()/1.);//assuming that there's only one cluster
    1646             :   //
    1647             :   // RS speedup reseting
    1648             :   //  memset(fClusterWeight,0,sizeof(Float_t)*AliITSRecoParam::kMaxClusterPerLayer);
    1649          12 :   memset(fClusterTracks,0,sizeof(UShort_t)*AliITSRecoParam::kMaxClusterPerLayer*4);
    1650          12 :   memset(fY,0,sizeof(Float_t)*AliITSRecoParam::kMaxClusterPerLayer);
    1651          12 :   memset(fZ,0,sizeof(Float_t)*AliITSRecoParam::kMaxClusterPerLayer);
    1652             :   /*
    1653             :   for (Int_t i=0; i<AliITSRecoParam::GetMaxClusterPerLayer(); i++) {
    1654             :     fClusterWeight[i]=0;
    1655             :     fClusterTracks[0][i]=-1;
    1656             :     fClusterTracks[1][i]=-1;
    1657             :     fClusterTracks[2][i]=-1;    
    1658             :     fClusterTracks[3][i]=-1;
    1659             :     fY[i]=0;    
    1660             :     fZ[i]=0;    
    1661             :   }
    1662             :   */
    1663          12 :   fYB[0]=0;
    1664          12 :   fYB[1]=0;
    1665             : 
    1666      307224 :  for (Int_t j=0; j<AliITSRecoParam::kMaxClusterPerLayer5; j++) {
    1667     2150400 :     for (Int_t j1=0; j1<6; j1++) {
    1668      921600 :       fClusters5[j1][j]=0;
    1669      921600 :       fClusterIndex5[j1][j]=0;//RS-1;
    1670      921600 :       fY5[j1][j]=0;
    1671      921600 :       fZ5[j1][j]=0;
    1672      921600 :       fN5[j1]=0;
    1673      921600 :       fBy5[j1][0]=0;
    1674      921600 :       fBy5[j1][1]=0;
    1675             :     }
    1676             :   }
    1677             : 
    1678      153624 :   for (Int_t j=0; j<AliITSRecoParam::kMaxClusterPerLayer10; j++) {
    1679     1843200 :     for (Int_t j1=0; j1<11; j1++) {
    1680      844800 :       fClusters10[j1][j]=0;
    1681      844800 :       fClusterIndex10[j1][j]=0;//RS-1;
    1682      844800 :       fY10[j1][j]=0;
    1683      844800 :       fZ10[j1][j]=0;
    1684      844800 :       fN10[j1]=0;
    1685      844800 :       fBy10[j1][0]=0;
    1686      844800 :       fBy10[j1][1]=0;
    1687             :     }
    1688             :   }
    1689             : 
    1690       76824 :   for (Int_t j=0; j<AliITSRecoParam::kMaxClusterPerLayer20; j++) {
    1691     1689600 :     for (Int_t j1=0; j1<21; j1++) {
    1692      806400 :       fClusters20[j1][j]=0;
    1693      806400 :       fClusterIndex20[j1][j]=0;//RS-1;
    1694      806400 :       fY20[j1][j]=0;
    1695      806400 :       fZ20[j1][j]=0;
    1696      806400 :       fN20[j1]=0;
    1697      806400 :       fBy20[j1][0]=0;
    1698      806400 :       fBy20[j1][1]=0;
    1699             :     }
    1700             :   }
    1701      768024 :   for(Int_t i=0;i<AliITSRecoParam::kMaxClusterPerLayer;i++){
    1702      384000 :     fClusters[i]=NULL;
    1703      384000 :     fClusterIndex[i]=0;
    1704             :   }
    1705          24 : }
    1706             : /*
    1707             : //------------------------------------------------------------------------
    1708             : AliITStrackerMI::AliITSlayer::AliITSlayer(const AliITSlayer& layer):
    1709             : fR(layer.fR),
    1710             : fPhiOffset(layer.fPhiOffset),
    1711             : fNladders(layer.fNladders),
    1712             : fZOffset(layer.fZOffset),
    1713             : fNdetectors(layer.fNdetectors),
    1714             : fDetectors(layer.fDetectors),
    1715             : fN(layer.fN),
    1716             : fDy5(layer.fDy5),
    1717             : fDy10(layer.fDy10),
    1718             : fDy20(layer.fDy20),
    1719             : fClustersCs(layer.fClustersCs),
    1720             : fClusterIndexCs(layer.fClusterIndexCs),
    1721             : fYcs(layer.fYcs),
    1722             : fZcs(layer.fZcs),
    1723             : fNcs(layer.fNcs),
    1724             : fCurrentSlice(layer.fCurrentSlice),
    1725             : fZmin(layer.fZmin),
    1726             : fZmax(layer.fZmax),
    1727             : fYmin(layer.fYmin),
    1728             : fYmax(layer.fYmax),
    1729             : fI(layer.fI),
    1730             : fImax(layer.fImax),
    1731             : fSkip(layer.fSkip),
    1732             : fAccepted(layer.fAccepted),
    1733             : fRoad(layer.fRoad),
    1734             : fMaxSigmaClY(layer.fMaxSigmaClY),
    1735             : fMaxSigmaClZ(layer.fMaxSigmaClZ),
    1736             : fNMaxSigmaCl(layer.fNMaxSigmaCl)
    1737             : {
    1738             :   //Copy constructor
    1739             : }
    1740             : */
    1741             : //------------------------------------------------------------------------
    1742         708 : AliITStrackerMI::AliITSlayer::~AliITSlayer() {
    1743             :   //--------------------------------------------------------------------
    1744             :   // AliITSlayer destructor
    1745             :   //--------------------------------------------------------------------
    1746        5128 :   delete [] fDetectors;
    1747         708 :   for (Int_t i=0; i<fN; i++) delete fClusters[i];
    1748             :   /* RS: Why?
    1749             :   for (Int_t i=0; i<AliITSRecoParam::GetMaxClusterPerLayer(); i++) {
    1750             :     fClusterWeight[i]=0;
    1751             :     fClusterTracks[0][i]=-1;
    1752             :     fClusterTracks[1][i]=-1;
    1753             :     fClusterTracks[2][i]=-1;    
    1754             :     fClusterTracks[3][i]=-1;    
    1755             :   }
    1756             :   */
    1757         708 : }
    1758             : //------------------------------------------------------------------------
    1759             : void AliITStrackerMI::AliITSlayer::ResetClusters() {
    1760             :   //--------------------------------------------------------------------
    1761             :   // This function removes loaded clusters
    1762             :   //--------------------------------------------------------------------
    1763        2142 :   for (Int_t i=fN; i--;) delete fClusters[i];
    1764             :   // RS speedup reseting
    1765             :   //  memset(fClusterWeight,0,sizeof(Float_t)*AliITSRecoParam::kMaxClusterPerLayer);
    1766          48 :   memset(fClusterTracks,0,sizeof(UShort_t)*AliITSRecoParam::kMaxClusterPerLayer*4);
    1767             :   /*  
    1768             :   for (Int_t i=0; i<AliITSRecoParam::GetMaxClusterPerLayer(); i++){
    1769             :     fClusterWeight[i]=0;
    1770             :     fClusterTracks[0][i]=-1;
    1771             :     fClusterTracks[1][i]=-1;
    1772             :     fClusterTracks[2][i]=-1;    
    1773             :     fClusterTracks[3][i]=-1;  
    1774             :   }
    1775             :   */  
    1776          48 :   fN=0;
    1777          48 :   fI=0;
    1778          48 : }
    1779             : //------------------------------------------------------------------------
    1780             : void AliITStrackerMI::AliITSlayer::ResetWeights() {
    1781             :   //--------------------------------------------------------------------
    1782             :   // This function reset weights of the clusters
    1783             :   //--------------------------------------------------------------------
    1784             :   // RS speedup reseting
    1785             :   //  memset(fClusterWeight,0,sizeof(Float_t)*AliITSRecoParam::kMaxClusterPerLayer);
    1786           0 :   memset(fClusterTracks,0,sizeof(UShort_t)*AliITSRecoParam::kMaxClusterPerLayer*4);
    1787             :   /*
    1788             :   for (Int_t i=0; i<AliITSRecoParam::GetMaxClusterPerLayer(); i++) {
    1789             :     fClusterWeight[i]=0;
    1790             :     fClusterTracks[0][i]=-1;
    1791             :     fClusterTracks[1][i]=-1;
    1792             :     fClusterTracks[2][i]=-1;    
    1793             :     fClusterTracks[3][i]=-1;  
    1794             :   }
    1795             :   */
    1796           0 :   for (Int_t i=fN;i--;) {
    1797           0 :     AliITSRecPoint * cl = (AliITSRecPoint*)GetCluster(i);
    1798           0 :     if (cl&&cl->IsUsed()) cl->Use();
    1799             :   }
    1800             : 
    1801           0 : }
    1802             : //------------------------------------------------------------------------
    1803             : void AliITStrackerMI::AliITSlayer::ResetRoad() {
    1804             :   //--------------------------------------------------------------------
    1805             :   // This function calculates the road defined by the cluster density
    1806             :   //--------------------------------------------------------------------
    1807             :   Int_t n=0;
    1808         810 :   for (Int_t i=fN; i--;) {
    1809        1312 :     if (TMath::Abs(fClusters[i]->GetZ())<fR) n++;
    1810             :   }
    1811          96 :   if (n>1) fRoad=2*fR*TMath::Sqrt(TMath::Pi()/n);
    1812          48 : }
    1813             : //------------------------------------------------------------------------
    1814             : Int_t AliITStrackerMI::AliITSlayer::InsertCluster(AliITSRecPoint *cl) {
    1815             :   //--------------------------------------------------------------------
    1816             :   //This function adds a cluster to this layer
    1817             :   //--------------------------------------------------------------------
    1818        1332 :   if (fN==AliITSRecoParam::GetMaxClusterPerLayer()) {
    1819           0 :     AliWarningGeneralF("AliITStrackerMI::AliITSlayer","Number of clusters for layer R=%.2f exceeds limit of %d",fR,fN);
    1820           0 :     return 1;
    1821             :   }
    1822         666 :   fCurrentSlice=-1;
    1823         666 :   fClusters[fN]=cl;
    1824         666 :   fN++;
    1825         666 :   AliITSdetector &det=GetDetector(cl->GetDetectorIndex());    
    1826             :   //AD
    1827         666 :   Double_t nSigmaY=fNMaxSigmaCl*TMath::Sqrt(cl->GetSigmaY2());
    1828         666 :   Double_t nSigmaZ=fNMaxSigmaCl*TMath::Sqrt(cl->GetSigmaZ2()); 
    1829        1012 :   if (cl->GetY()-nSigmaY<det.GetYmin()) det.SetYmin(cl->GetY()-nSigmaY);
    1830        1032 :   if (cl->GetY()+nSigmaY>det.GetYmax()) det.SetYmax(cl->GetY()+nSigmaY);
    1831        1040 :   if (cl->GetZ()-nSigmaZ<det.GetZmin()) det.SetZmin(cl->GetZ()-nSigmaZ);
    1832        1021 :   if (cl->GetZ()+nSigmaZ>det.GetZmax()) det.SetZmax(cl->GetZ()+nSigmaZ);
    1833             :   //AD               
    1834             :   /*
    1835             :   if (cl->GetY()<det.GetYmin()) det.SetYmin(cl->GetY());
    1836             :   if (cl->GetY()>det.GetYmax()) det.SetYmax(cl->GetY());
    1837             :   if (cl->GetZ()<det.GetZmin()) det.SetZmin(cl->GetZ());
    1838             :   if (cl->GetZ()>det.GetZmax()) det.SetZmax(cl->GetZ());
    1839             :   */                 
    1840             :   return 0;
    1841         666 : }
    1842             : //------------------------------------------------------------------------
    1843             : void  AliITStrackerMI::AliITSlayer::SortClusters()
    1844             : {
    1845             :   //
    1846             :   //sort clusters
    1847             :   //
    1848             :   //
    1849          96 :   fMaxSigmaClY=0.; //AD
    1850          48 :   fMaxSigmaClZ=0.; //AD
    1851          48 :   AliITSRecPoint *clusters[fN];
    1852          48 :   Float_t z[fN];
    1853          48 :   Int_t   index[fN];
    1854             : 
    1855        1428 :   for (Int_t i=0;i<fN;i++){
    1856         666 :     z[i] = fClusters[i]->GetZ();
    1857             :     // save largest errors in y and z for this layer
    1858         666 :     fMaxSigmaClY=TMath::Max(fMaxSigmaClY,TMath::Sqrt(fClusters[i]->GetSigmaY2()));
    1859         666 :     fMaxSigmaClZ=TMath::Max(fMaxSigmaClZ,TMath::Sqrt(fClusters[i]->GetSigmaZ2()));
    1860             :   }
    1861          48 :   TMath::Sort(fN,z,index,kFALSE);
    1862        1428 :   for (Int_t i=fN;i--;) {
    1863         666 :     clusters[i] = fClusters[index[i]];
    1864             :   }
    1865             :   //
    1866        1428 :   for (Int_t i=fN;i--;){
    1867         666 :     fClusters[i] = clusters[i];
    1868         666 :     fZ[i]        = fClusters[i]->GetZ();
    1869         666 :     AliITSdetector &det=GetDetector(fClusters[i]->GetDetectorIndex());    
    1870         666 :     Double_t y=fR*det.GetPhi() + fClusters[i]->GetY();
    1871         674 :     if (y>2.*fR*TMath::Pi()) y -= 2.*fR*TMath::Pi();
    1872         666 :     fY[i] = y;
    1873             :   }
    1874             :   //  delete[] index; // RS Moved to stack
    1875             :   //  delete[] z;
    1876             :   //  delete[] clusters;
    1877             :   //
    1878             : 
    1879          48 :   fYB[0]=10000000;
    1880          48 :   fYB[1]=-10000000;
    1881        1428 :   for (Int_t i=0;i<fN;i++){
    1882         770 :     if (fY[i]<fYB[0]) fYB[0]=fY[i];
    1883         826 :     if (fY[i]>fYB[1]) fYB[1]=fY[i];
    1884         666 :     fClusterIndex[i] = i;
    1885             :   }
    1886             :   //
    1887             :   // fill slices
    1888          48 :   fDy5 = (fYB[1]-fYB[0])/5.;
    1889          48 :   fDy10 = (fYB[1]-fYB[0])/10.;
    1890          48 :   fDy20 = (fYB[1]-fYB[0])/20.;
    1891         672 :   for (Int_t i=6;i--;)  fN5[i] =0;  
    1892        1152 :   for (Int_t i=11;i--;) fN10[i]=0;  
    1893        2112 :   for (Int_t i=21;i--;) fN20[i]=0;
    1894             :   //  
    1895         672 :   for (Int_t i=6;i--;)  {fBy5[i][0]  =  fYB[0]+(i-0.75)*fDy5;  fBy5[i][1]  =  fYB[0]+(i+0.75)*fDy5;}
    1896        1152 :   for (Int_t i=11;i--;) {fBy10[i][0] =  fYB[0]+(i-0.75)*fDy10; fBy10[i][1] =  fYB[0]+(i+0.75)*fDy10;} 
    1897        2112 :   for (Int_t i=21;i--;) {fBy20[i][0] =  fYB[0]+(i-0.75)*fDy20; fBy20[i][1] =  fYB[0]+(i+0.75)*fDy20;}
    1898             :   //
    1899             :   //
    1900        1428 :   for (Int_t i=0;i<fN;i++)
    1901        5328 :     for (Int_t irot=-1;irot<=1;irot++){
    1902        1998 :       Float_t curY = fY[i]+irot*TMath::TwoPi()*fR; 
    1903             :       // slice 5
    1904       27972 :       for (Int_t slice=0; slice<6;slice++){
    1905       19112 :         if (fBy5[slice][0]<curY && curY<fBy5[slice][1]&&fN5[slice]<AliITSRecoParam::GetMaxClusterPerLayer5()){
    1906        1232 :           fClusters5[slice][fN5[slice]] = fClusters[i];
    1907        1232 :           fY5[slice][fN5[slice]] = curY;
    1908        1232 :           fZ5[slice][fN5[slice]] = fZ[i];
    1909        1232 :           fClusterIndex5[slice][fN5[slice]]=i;
    1910        1232 :           fN5[slice]++;
    1911        1232 :         }
    1912             :       }
    1913             :       // slice 10
    1914       47952 :       for (Int_t slice=0; slice<11;slice++){
    1915       33154 :         if (fBy10[slice][0]<curY && curY<fBy10[slice][1]&&fN10[slice]<AliITSRecoParam::GetMaxClusterPerLayer10()){
    1916        1000 :           fClusters10[slice][fN10[slice]] = fClusters[i];
    1917        1000 :           fY10[slice][fN10[slice]] = curY;
    1918        1000 :           fZ10[slice][fN10[slice]] = fZ[i];
    1919        1000 :           fClusterIndex10[slice][fN10[slice]]=i;
    1920        1000 :           fN10[slice]++;
    1921        1000 :         }
    1922             :       }
    1923             :       // slice 20
    1924       87912 :       for (Int_t slice=0; slice<21;slice++){
    1925       61652 :         if (fBy20[slice][0]<curY && curY<fBy20[slice][1]&&fN20[slice]<AliITSRecoParam::GetMaxClusterPerLayer20()){
    1926         858 :           fClusters20[slice][fN20[slice]] = fClusters[i];
    1927         858 :           fY20[slice][fN20[slice]] = curY;
    1928         858 :           fZ20[slice][fN20[slice]] = fZ[i];
    1929         858 :           fClusterIndex20[slice][fN20[slice]]=i;
    1930         858 :           fN20[slice]++;
    1931         858 :         }
    1932             :       }      
    1933             :     }
    1934             : 
    1935             :   //
    1936             :   // consistency check
    1937             :   //
    1938        1332 :   for (Int_t i=0;i<fN-1;i++){
    1939         618 :     if (fZ[i]>fZ[i+1]){
    1940           0 :       printf("Bug\n");
    1941           0 :     }
    1942             :   }
    1943             :   //
    1944        2112 :   for (Int_t slice=0;slice<21;slice++)
    1945        2912 :   for (Int_t i=0;i<fN20[slice]-1;i++){
    1946         448 :     if (fZ20[slice][i]>fZ20[slice][i+1]){
    1947           0 :       printf("Bug\n");
    1948           0 :     }
    1949             :   }
    1950             : 
    1951             : 
    1952          48 : }
    1953             : //------------------------------------------------------------------------
    1954             : Int_t AliITStrackerMI::AliITSlayer::FindClusterIndex(Float_t z) const {
    1955             :   //--------------------------------------------------------------------
    1956             :   // This function returns the index of the nearest cluster 
    1957             :   //--------------------------------------------------------------------
    1958             :   Int_t ncl=0;
    1959             :   const Float_t *zcl;  
    1960       12960 :   if (fCurrentSlice<0) {
    1961         144 :     ncl = fN;
    1962         144 :     zcl   = fZ;
    1963         144 :   }
    1964             :   else{
    1965        6336 :     ncl   = fNcs;
    1966        6336 :     zcl   = fZcs;;
    1967             :   }
    1968             :   
    1969        6532 :   if (ncl==0) return 0;
    1970        6428 :   Int_t b=0, e=ncl-1, m=(b+e)/2;
    1971       29200 :   for (; b<e; m=(b+e)/2) {
    1972             :     //    if (z > fClusters[m]->GetZ()) b=m+1;
    1973       12976 :     if (z > zcl[m]) b=m+1;
    1974             :     else e=m; 
    1975             :   }
    1976             :   return m;
    1977        6480 : }
    1978             : //------------------------------------------------------------------------
    1979             : 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 {
    1980             :   //--------------------------------------------------------------------
    1981             :   // This function computes the rectangular road for this track
    1982             :   //--------------------------------------------------------------------
    1983             : 
    1984             : 
    1985        9700 :   AliITSdetector &det = fgLayers[ilayer].GetDetector(idet);
    1986             :   // take into account the misalignment: propagate track to misaligned detector plane
    1987        4850 :   if (!track->Propagate(det.GetPhi(),det.GetRmisal())) return kFALSE;
    1988             : 
    1989        9700 :   Double_t dz=AliITSReconstructor::GetRecoParam()->GetNSigmaRoadZ()*
    1990        9700 :                     TMath::Sqrt(track->GetSigmaZ2() + 
    1991        9700 :                     AliITSReconstructor::GetRecoParam()->GetNSigmaZLayerForRoadZ()*
    1992        9700 :                     AliITSReconstructor::GetRecoParam()->GetNSigmaZLayerForRoadZ()*
    1993        4850 :                     AliITSReconstructor::GetRecoParam()->GetSigmaZ2(ilayer));
    1994        9700 :   Double_t dy=AliITSReconstructor::GetRecoParam()->GetNSigmaRoadY()*
    1995        9700 :                     TMath::Sqrt(track->GetSigmaY2() + 
    1996        9700 :                     AliITSReconstructor::GetRecoParam()->GetNSigmaYLayerForRoadY()*
    1997        9700 :                     AliITSReconstructor::GetRecoParam()->GetNSigmaYLayerForRoadY()*
    1998        4850 :                     AliITSReconstructor::GetRecoParam()->GetSigmaY2(ilayer));
    1999             :       
    2000             :   // track at boundary between detectors, enlarge road
    2001        4850 :   Double_t boundaryWidth=AliITSRecoParam::GetBoundaryWidth();
    2002        4850 :   if ( (track->GetY()-dy < det.GetYmin()+boundaryWidth) || 
    2003         256 :        (track->GetY()+dy > det.GetYmax()-boundaryWidth) || 
    2004          48 :        (track->GetZ()-dz < det.GetZmin()+boundaryWidth) ||
    2005           0 :        (track->GetZ()+dz > det.GetZmax()-boundaryWidth) ) {
    2006        4850 :     Float_t tgl = TMath::Abs(track->GetTgl());
    2007        4850 :     if (tgl > 1.) tgl=1.;
    2008        4850 :     Double_t deltaXNeighbDets=AliITSRecoParam::GetDeltaXNeighbDets();
    2009        4850 :     dz = TMath::Sqrt(dz*dz+deltaXNeighbDets*deltaXNeighbDets*tgl*tgl);
    2010        4850 :     Float_t snp = TMath::Abs(track->GetSnp());
    2011        4850 :     if (snp > AliITSReconstructor::GetRecoParam()->GetMaxSnp()) return kFALSE;
    2012        4850 :     dy = TMath::Sqrt(dy*dy+deltaXNeighbDets*deltaXNeighbDets*snp*snp);
    2013        4850 :   } // boundary
    2014             :   
    2015             :   // add to the road a term (up to 2-3 mm) to deal with misalignments
    2016        4850 :   dy = TMath::Sqrt(dy*dy + AliITSReconstructor::GetRecoParam()->GetRoadMisal()*AliITSReconstructor::GetRecoParam()->GetRoadMisal());
    2017        4850 :   dz = TMath::Sqrt(dz*dz + AliITSReconstructor::GetRecoParam()->GetRoadMisal()*AliITSReconstructor::GetRecoParam()->GetRoadMisal());
    2018             : 
    2019        4850 :   Double_t r = fgLayers[ilayer].GetR();
    2020        4850 :   zmin = track->GetZ() - dz; 
    2021        4850 :   zmax = track->GetZ() + dz;
    2022        4850 :   ymin = track->GetY() + r*det.GetPhi() - dy;
    2023        4850 :   ymax = track->GetY() + r*det.GetPhi() + dy;
    2024             : 
    2025             :   // bring track back to idead detector plane
    2026        4850 :   if (!track->Propagate(det.GetPhi(),det.GetR())) return kFALSE;
    2027             : 
    2028        4850 :   return kTRUE;
    2029        4850 : }
    2030             : //------------------------------------------------------------------------
    2031             : void AliITStrackerMI::AliITSlayer::
    2032             : SelectClusters(Double_t zmin,Double_t zmax,Double_t ymin, Double_t ymax) {
    2033             :   //--------------------------------------------------------------------
    2034             :   // This function sets the "window"
    2035             :   //--------------------------------------------------------------------
    2036             :  
    2037        6480 :   Double_t circle=2*TMath::Pi()*fR;
    2038        3240 :   fYmin = ymin; 
    2039        3240 :   fYmax = ymax;
    2040        3240 :   fZmin = zmin;
    2041        3240 :   fZmax = zmax;
    2042             :   // AD
    2043             :   // enlarge road in y by maximum cluster error on this layer (3 sigma)
    2044        3240 :   fYmin -= fNMaxSigmaCl*fMaxSigmaClY;
    2045        3240 :   fYmax += fNMaxSigmaCl*fMaxSigmaClY;
    2046        3240 :   fZmin -= fNMaxSigmaCl*fMaxSigmaClZ;
    2047        3240 :   fZmax += fNMaxSigmaCl*fMaxSigmaClZ;
    2048             : 
    2049        3240 :   Float_t ymiddle = (fYmin+fYmax)*0.5;
    2050        3240 :   if (ymiddle<fYB[0]) {
    2051         202 :     fYmin+=circle; fYmax+=circle; ymiddle+=circle;
    2052        3240 :   } else if (ymiddle>fYB[1]) {
    2053         344 :     fYmin-=circle; fYmax-=circle; ymiddle-=circle;
    2054         344 :   }
    2055             :   
    2056             :   //
    2057        3240 :   fCurrentSlice =-1;
    2058             :   // defualt take all
    2059        3240 :   fClustersCs = fClusters;
    2060        3240 :   fClusterIndexCs = fClusterIndex;
    2061        3240 :   fYcs  = fY;
    2062        3240 :   fZcs  = fZ;
    2063        3240 :   fNcs  = fN;
    2064             :   //
    2065             :   //is in 20 slice?
    2066        6480 :   if (fCurrentSlice<0&&TMath::Abs(fYmax-fYmin)<1.49*fDy20){
    2067        3232 :     Int_t slice = int(0.5+(ymiddle-fYB[0])/fDy20);
    2068        3232 :     if (slice<0) slice=0;
    2069        3232 :     if (slice>20) slice=20;
    2070        9520 :     Bool_t isOK = (fYmin>fBy20[slice][0]&&fYmax<fBy20[slice][1]);
    2071        3232 :     if (isOK) {
    2072        2852 :       fCurrentSlice=slice;
    2073        2852 :       fClustersCs = fClusters20[fCurrentSlice];
    2074        2852 :       fClusterIndexCs = fClusterIndex20[fCurrentSlice];
    2075        2852 :       fYcs  = fY20[fCurrentSlice];
    2076        2852 :       fZcs  = fZ20[fCurrentSlice];
    2077        2852 :       fNcs  = fN20[fCurrentSlice];
    2078        2852 :     }
    2079        3232 :   }  
    2080             :   //
    2081             :   //is in 10 slice?
    2082        3628 :   if (fCurrentSlice<0&&TMath::Abs(fYmax-fYmin)<1.49*fDy10){
    2083         385 :     Int_t slice = int(0.5+(ymiddle-fYB[0])/fDy10);
    2084         385 :     if (slice<0) slice=0;
    2085         385 :     if (slice>10) slice=10;
    2086         979 :     Bool_t isOK = (fYmin>fBy10[slice][0]&&fYmax<fBy10[slice][1]);
    2087         385 :     if (isOK) {
    2088           6 :       fCurrentSlice=slice;
    2089           6 :       fClustersCs = fClusters10[fCurrentSlice];
    2090           6 :       fClusterIndexCs = fClusterIndex10[fCurrentSlice];
    2091           6 :       fYcs  = fY10[fCurrentSlice];
    2092           6 :       fZcs  = fZ10[fCurrentSlice];
    2093           6 :       fNcs  = fN10[fCurrentSlice];
    2094           6 :     }
    2095         385 :   }  
    2096             :   //
    2097             :   //is in 5 slice?
    2098        3622 :   if (fCurrentSlice<0&&TMath::Abs(fYmax-fYmin)<1.49*fDy5){
    2099         382 :     Int_t slice = int(0.5+(ymiddle-fYB[0])/fDy5);
    2100         382 :     if (slice<0) slice=0;
    2101         382 :     if (slice>5) slice=5;
    2102        1074 :     Bool_t isOK = (fYmin>fBy5[slice][0]&&fYmax<fBy5[slice][1]);
    2103         382 :     if (isOK) {
    2104         310 :       fCurrentSlice=slice;
    2105         310 :       fClustersCs = fClusters5[fCurrentSlice];
    2106         310 :       fClusterIndexCs = fClusterIndex5[fCurrentSlice];
    2107         310 :       fYcs  = fY5[fCurrentSlice];
    2108         310 :       fZcs  = fZ5[fCurrentSlice];
    2109         310 :       fNcs  = fN5[fCurrentSlice];
    2110         310 :     }
    2111         382 :   }  
    2112             :   //  
    2113        3240 :   fI        = FindClusterIndex(fZmin); 
    2114        3240 :   fImax     = TMath::Min(FindClusterIndex(fZmax)+1,fNcs);
    2115        3240 :   fSkip     = 0;
    2116        3240 :   fAccepted = 0;
    2117             : 
    2118             :   return;
    2119        3240 : }
    2120             : //------------------------------------------------------------------------
    2121             : Int_t AliITStrackerMI::AliITSlayer::
    2122             : FindDetectorIndex(Double_t phi, Double_t z) const {
    2123             :   //--------------------------------------------------------------------
    2124             :   //This function finds the detector crossed by the track
    2125             :   //--------------------------------------------------------------------
    2126             :   Double_t dphi;
    2127       41490 :   if (fZOffset<0)            // old geometry
    2128       13830 :     dphi = -(phi-fPhiOffset);
    2129             :   else                       // new geometry
    2130             :     dphi = phi-fPhiOffset;
    2131             : 
    2132             : 
    2133       14924 :   if      (dphi <  0) dphi += 2*TMath::Pi();
    2134       12736 :   else if (dphi >= 2*TMath::Pi()) dphi -= 2*TMath::Pi();
    2135       13830 :   Int_t np=Int_t(dphi*fNladders*0.5/TMath::Pi()+0.5);
    2136       14924 :   if (np>=fNladders) np-=fNladders;
    2137       13830 :   if (np<0)          np+=fNladders;
    2138             : 
    2139             : 
    2140       13830 :   Double_t dz=fZOffset-z;
    2141       13830 :   Double_t nnz = dz*(fNdetectors-1)*0.5/fZOffset+0.5;
    2142       13830 :   Int_t nz = (nnz<0 ? -1 : (Int_t)nnz);
    2143       13830 :   if (nz>=fNdetectors || nz<0) {
    2144             :     //printf("ndet %d phi %f z %f  np %d nz %d\n",fNdetectors,phi,z,np,nz);
    2145           4 :     return -1;
    2146             :   }
    2147             : 
    2148             :   // ad hoc correction for 3rd ladder of SDD inner layer,
    2149             :   // which is reversed (rotated by pi around local y)
    2150             :   // this correction is OK only from AliITSv11Hybrid onwards
    2151       32694 :   if (GetR()>12. && GetR()<20.) { // SDD inner
    2152        9434 :     if(np==2) { // 3rd ladder
    2153           0 :       Double_t posMod252[3]={0};
    2154           0 :       AliITSgeomTGeo::GetTranslation(252,posMod252);
    2155             :       // check the Z coordinate of Mod 252: if negative 
    2156             :       // (old SDD geometry in AliITSv11Hybrid)
    2157             :       // the swap of numeration whould be applied
    2158           0 :       if(posMod252[2]<0.){
    2159           0 :         nz = (fNdetectors-1) - nz;
    2160           0 :       } 
    2161           0 :     }
    2162             :   }
    2163             :   //printf("ndet %d phi %f z %f  np %d nz %d\n",fNdetectors,phi,z,np,nz);
    2164             : 
    2165             : 
    2166       13826 :   return np*fNdetectors + nz;
    2167       13830 : }
    2168             : //------------------------------------------------------------------------
    2169             : const AliITSRecPoint *AliITStrackerMI::AliITSlayer::GetNextCluster(Int_t &ci,Bool_t test)
    2170             : {
    2171             :   //--------------------------------------------------------------------
    2172             :   // This function returns clusters within the "window" 
    2173             :   //--------------------------------------------------------------------
    2174             : 
    2175        9770 :   if (fCurrentSlice<0) {
    2176         176 :     Double_t rpi2 = 2.*fR*TMath::Pi();
    2177         884 :     for (Int_t i=fI; i<fImax; i++) {
    2178         286 :       Double_t y = fY[i];
    2179         286 :       Double_t z = fZ[i];
    2180         572 :       if (fYmax<y) y -= rpi2;
    2181         500 :       if (fYmin>y) y += rpi2;
    2182         286 :       if (y<fYmin) continue;
    2183         500 :       if (y>fYmax) continue;
    2184             :       // AD
    2185             :       // skip clusters that are in "extended" road but they 
    2186             :       // 3sigma error does not touch the original road
    2187          72 :       if (z+fNMaxSigmaCl*TMath::Sqrt(fClusters[i]->GetSigmaZ2())<fZmin+fNMaxSigmaCl*fMaxSigmaClZ) continue;
    2188          72 :       if (z-fNMaxSigmaCl*TMath::Sqrt(fClusters[i]->GetSigmaZ2())>fZmax-fNMaxSigmaCl*fMaxSigmaClZ) continue;
    2189             :       //
    2190          72 :       if (TMath::Abs(fClusters[i]->GetQ())<1.e-13 && fSkip==2) continue;
    2191          72 :       ci=i;
    2192         112 :       if (!test) fI=i+1;
    2193          72 :       return fClusters[i];
    2194             :     }
    2195         104 :   } else {
    2196       26242 :     for (Int_t i=fI; i<fImax; i++) {
    2197        8186 :       if (fYcs[i]<fYmin) continue;
    2198        7126 :       if (fYcs[i]>fYmax) continue;
    2199        6304 :       if (TMath::Abs(fClustersCs[i]->GetQ())<1.e-13 && fSkip==2) continue;
    2200        6304 :       ci=fClusterIndexCs[i];
    2201       10068 :       if (!test) fI=i+1;
    2202        6304 :       return fClustersCs[i];
    2203             :     }
    2204             :   }
    2205        3394 :   return 0;
    2206        9770 : }
    2207             : //------------------------------------------------------------------------
    2208             : Double_t AliITStrackerMI::AliITSlayer::GetThickness(Double_t y,Double_t z,Double_t &x0)
    2209             : const {
    2210             :   //--------------------------------------------------------------------
    2211             :   // This function returns the layer thickness at this point (units X0)
    2212             :   //--------------------------------------------------------------------
    2213             :   Double_t d=0.0085;
    2214         424 :   x0=AliITSRecoParam::GetX0Air();
    2215         248 :   if (43<fR&&fR<45) { //SSD2
    2216             :      Double_t dd=0.0034;
    2217             :      d=dd;
    2218          40 :      if (TMath::Abs(y-0.00)>3.40) d+=dd;
    2219          36 :      if (TMath::Abs(y-1.90)<0.45) {d+=(0.013-0.0034);}
    2220          36 :      if (TMath::Abs(y+1.90)<0.45) {d+=(0.013-0.0034);}
    2221         334 :      for (Int_t i=0; i<12; i++) {
    2222         152 :        if (TMath::Abs(z-3.9*(i+0.5))<0.15) {
    2223           0 :           if (TMath::Abs(y-0.00)>3.40) d+=dd;
    2224           0 :           d+=0.0034; 
    2225           0 :           break;
    2226             :        }
    2227         152 :        if (TMath::Abs(z+3.9*(i+0.5))<0.15) {
    2228           0 :           if (TMath::Abs(y-0.00)>3.40) d+=dd;
    2229           0 :           d+=0.0034; 
    2230           0 :           break;
    2231             :        }         
    2232         152 :        if (TMath::Abs(z-3.4-3.9*i)<0.50) {d+=(0.016-0.0034); break;}
    2233         178 :        if (TMath::Abs(z+0.5+3.9*i)<0.50) {d+=(0.016-0.0034); break;}
    2234             :      }
    2235          36 :   } else 
    2236         212 :   if (37<fR&&fR<41) { //SSD1
    2237             :      Double_t dd=0.0034;
    2238             :      d=dd;
    2239          36 :      if (TMath::Abs(y-0.00)>3.40) d+=dd;
    2240          44 :      if (TMath::Abs(y-1.90)<0.45) {d+=(0.013-0.0034);}
    2241          38 :      if (TMath::Abs(y+1.90)<0.45) {d+=(0.013-0.0034);}
    2242         410 :      for (Int_t i=0; i<11; i++) {
    2243         184 :        if (TMath::Abs(z-3.9*i)<0.15) {
    2244          20 :           if (TMath::Abs(y-0.00)>3.40) d+=dd;
    2245          20 :           d+=dd; 
    2246          20 :           break;
    2247             :        }
    2248         164 :        if (TMath::Abs(z+3.9*i)<0.15) {
    2249           0 :           if (TMath::Abs(y-0.00)>3.40) d+=dd;
    2250           0 :           d+=dd; 
    2251           0 :           break;
    2252             :        }         
    2253         166 :        if (TMath::Abs(z-1.85-3.9*i)<0.50) {d+=(0.016-0.0034); break;}
    2254         162 :        if (TMath::Abs(z+2.05+3.9*i)<0.50) {d+=(0.016-0.0034); break;}         
    2255             :      }
    2256          36 :   } else
    2257         212 :   if (13<fR&&fR<26) { //SDD
    2258             :      Double_t dd=0.0033;
    2259             :      d=dd;
    2260          74 :      if (TMath::Abs(y-0.00)>3.30) d+=dd;
    2261             : 
    2262          72 :      if (TMath::Abs(y-1.80)<0.55) {
    2263           8 :         d+=0.016;
    2264         266 :         for (Int_t j=0; j<20; j++) {
    2265         126 :           if (TMath::Abs(z+0.7+1.47*j)<0.12) {d+=0.08; x0=9.; break;}
    2266         122 :           if (TMath::Abs(z-0.7-1.47*j)<0.12) {d+=0.08; x0=9.; break;}
    2267             :         } 
    2268           8 :      }
    2269          72 :      if (TMath::Abs(y+1.80)<0.55) {
    2270           8 :         d+=0.016;
    2271         344 :         for (Int_t j=0; j<20; j++) {
    2272         160 :           if (TMath::Abs(z-0.7-1.47*j)<0.12) {d+=0.08; x0=9.; break;}
    2273         160 :           if (TMath::Abs(z+0.7+1.47*j)<0.12) {d+=0.08; x0=9.; break;}
    2274             :         } 
    2275           8 :      }
    2276             : 
    2277         418 :      for (Int_t i=0; i<4; i++) {
    2278         164 :        if (TMath::Abs(z-7.3*i)<0.60) {
    2279          42 :           d+=dd;
    2280          42 :           if (TMath::Abs(y-0.00)>3.30) d+=dd; 
    2281          42 :           break;
    2282             :        }
    2283         122 :        if (TMath::Abs(z+7.3*i)<0.60) {
    2284           0 :           d+=dd; 
    2285           0 :           if (TMath::Abs(y-0.00)>3.30) d+=dd; 
    2286           0 :           break;
    2287             :        }
    2288             :      }
    2289          72 :   } else
    2290         102 :   if (6<fR&&fR<8) {   //SPD2
    2291          34 :      Double_t dd=0.0063; x0=21.5;
    2292             :      d=dd;
    2293          52 :      if (TMath::Abs(y-3.08)>0.5) d+=dd;
    2294          34 :      if (TMath::Abs(y-3.03)<0.10) d+=0.014;
    2295          34 :   } else
    2296          68 :   if (3<fR&&fR<5) {   //SPD1
    2297          34 :      Double_t dd=0.0063; x0=21.5;
    2298             :      d=dd;
    2299          56 :      if (TMath::Abs(y+0.21)>0.6) d+=dd;
    2300          40 :      if (TMath::Abs(y+0.10)<0.10) d+=0.014;
    2301          34 :   }
    2302             : 
    2303         212 :   return d;
    2304             : }
    2305             : //------------------------------------------------------------------------
    2306             : AliITStrackerMI::AliITSdetector::AliITSdetector(const AliITSdetector& det):
    2307           0 : fR(det.fR),
    2308           0 : fRmisal(det.fRmisal),
    2309           0 : fPhi(det.fPhi),
    2310           0 : fSinPhi(det.fSinPhi),
    2311           0 : fCosPhi(det.fCosPhi),
    2312           0 : fYmin(det.fYmin),
    2313           0 : fYmax(det.fYmax),
    2314           0 : fZmin(det.fZmin),
    2315           0 : fZmax(det.fZmax),
    2316           0 : fIsBad(det.fIsBad),
    2317           0 : fNChips(det.fNChips),
    2318           0 : fChipIsBad(det.fChipIsBad)
    2319           0 : {
    2320             :   //Copy constructor
    2321           0 : }
    2322             : //------------------------------------------------------------------------
    2323             : void AliITStrackerMI::AliITSdetector::ReadBadDetectorAndChips(Int_t ilayer,Int_t idet,
    2324             :                                                const AliITSDetTypeRec *detTypeRec)
    2325             : {
    2326             :   //--------------------------------------------------------------------
    2327             :   // Read bad detectors and chips from calibration objects in AliITSDetTypeRec
    2328             :   //--------------------------------------------------------------------
    2329             : 
    2330             :   // In AliITSDetTypeRec, detector numbers go from 0 to 2197
    2331             :   // while in the tracker they start from 0 for each layer
    2332       47580 :   for(Int_t il=0; il<ilayer; il++) 
    2333       17196 :     idet += AliITSgeomTGeo::GetNLadders(il+1)*AliITSgeomTGeo::GetNDetectors(il+1);
    2334             : 
    2335             :   Int_t detType;
    2336        4396 :   if (ilayer==0 || ilayer==1) {        // ----------  SPD
    2337             :     detType = 0;
    2338        4396 :   } else if (ilayer==2 || ilayer==3) { // ----------  SDD
    2339             :     detType = 1;
    2340        3916 :   } else if (ilayer==4 || ilayer==5) { // ----------  SSD
    2341             :     detType = 2;
    2342             :   } else {
    2343           0 :     printf("AliITStrackerMI::AliITSdetector::InitBadFromOCDB: Wrong layer number %d\n",ilayer);
    2344           0 :     return;
    2345             :   }
    2346             : 
    2347             :   // Get calibration from AliITSDetTypeRec
    2348        4396 :   AliITSCalibration *calib = (AliITSCalibration*)detTypeRec->GetCalibrationModel(idet);
    2349        4396 :   calib->SetModuleIndex(idet);
    2350             :   AliITSCalibration *calibSPDdead = 0;
    2351        4876 :   if(detType==0) calibSPDdead = (AliITSCalibration*)detTypeRec->GetSPDDeadModel(idet); // TEMPORARY
    2352        4876 :   if (calib->IsBad() ||
    2353        4744 :       (detType==0 && calibSPDdead->IsBad())) // TEMPORARY
    2354             :     {
    2355         180 :       SetBad();
    2356             :       //      printf("lay %d bad %d\n",ilayer,idet);
    2357         180 :     }
    2358             : 
    2359             :   // Get segmentation from AliITSDetTypeRec
    2360        4396 :   AliITSsegmentation *segm = (AliITSsegmentation*)detTypeRec->GetSegmentationModel(detType);
    2361             : 
    2362             :   // Read info about bad chips
    2363        4396 :   fNChips = segm->GetMaximumChipIndex()+1;
    2364             :   //printf("ilayer %d  detType %d idet %d fNChips %d %d  GetNumberOfChips %d\n",ilayer,detType,idet,fNChips,segm->GetMaximumChipIndex(),segm->GetNumberOfChips());
    2365        4396 :   if(fChipIsBad) { delete [] fChipIsBad; fChipIsBad=NULL; }
    2366        4396 :   fChipIsBad = new Bool_t[fNChips];
    2367      103416 :   for (Int_t iCh=0;iCh<fNChips;iCh++) {
    2368       47312 :     fChipIsBad[iCh] = calib->IsChipBad(iCh);
    2369       49952 :     if (detType==0 && calibSPDdead->IsChipBad(iCh)) fChipIsBad[iCh] = kTRUE; // TEMPORARY
    2370             :     //if(fChipIsBad[iCh]) {printf("lay %d det %d bad chip %d\n",ilayer,idet,iCh);}
    2371             :   }
    2372             : 
    2373             :   return;
    2374        4396 : }
    2375             : //------------------------------------------------------------------------
    2376             : Double_t AliITStrackerMI::GetEffectiveThickness()
    2377             : {
    2378             :   //--------------------------------------------------------------------
    2379             :   // Returns the thickness between the current layer and the vertex (units X0)
    2380             :   //--------------------------------------------------------------------
    2381             : 
    2382        5460 :   if(fUseTGeo!=0) {
    2383        2734 :     if(fxOverX0Layer[0]<0) BuildMaterialLUT("Layers");
    2384        2734 :     if(fxOverX0Shield[0]<0) BuildMaterialLUT("Shields");
    2385        2734 :     if(fxOverX0Pipe<0) BuildMaterialLUT("Pipe");
    2386             :   }
    2387             : 
    2388             :   // beam pipe
    2389        8190 :   Double_t dPipe = (fUseTGeo==0 ? AliITSRecoParam::GetdPipe() : fxOverX0Pipe);
    2390        2730 :   Double_t d=dPipe*AliITSRecoParam::GetrPipe()*AliITSRecoParam::GetrPipe();
    2391             : 
    2392             :   // layers
    2393        2730 :   Double_t x0=0;
    2394        2730 :   Double_t xn=fgLayers[fI].GetR();
    2395       16384 :   for (Int_t i=0; i<fI; i++) {
    2396        5462 :     Double_t xi=fgLayers[i].GetR();
    2397       16386 :     Double_t dLayer = (fUseTGeo==0 ? fgLayers[i].GetThickness(0,0,x0) : fxOverX0Layer[i]);
    2398        5462 :     d+=dLayer*xi*xi;
    2399             :   }
    2400             : 
    2401             :   // shields
    2402        2730 :   if (fI>1) {
    2403        4602 :     Double_t dshieldSPD = (fUseTGeo==0 ? AliITSRecoParam::Getdshield(0) : fxOverX0Shield[0]);
    2404        1534 :     d+=dshieldSPD*AliITSRecoParam::GetrInsideShield(0)*AliITSRecoParam::GetrInsideShield(0);
    2405        1534 :   }
    2406        2730 :   if (fI>3) {
    2407        1752 :     Double_t dshieldSDD = (fUseTGeo==0 ? AliITSRecoParam::Getdshield(1) : fxOverX0Shield[1]);
    2408         584 :     d+=dshieldSDD*AliITSRecoParam::GetrInsideShield(1)*AliITSRecoParam::GetrInsideShield(1);
    2409         584 :   }
    2410        5460 :   return d/(xn*xn);
    2411        2730 : }
    2412             : 
    2413             : //------------------------------------------------------------------------
    2414             : Int_t AliITStrackerMI::GetEffectiveThicknessLbyL(Double_t* xMS, Double_t* x2x0MS)
    2415             : {
    2416             :   //--------------------------------------------------------------------
    2417             :   // Returns the array of layers between the current layer and the vertex
    2418             :   //--------------------------------------------------------------------
    2419             :   //
    2420           0 :   if(fUseTGeo!=0) {
    2421           0 :     if(fxOverX0Layer[0]<0) BuildMaterialLUT("Layers");
    2422           0 :     if(fxOverX0Shield[0]<0) BuildMaterialLUT("Shields");
    2423           0 :     if(fxOverX0Pipe<0) BuildMaterialLUT("Pipe");
    2424             :   }
    2425             : 
    2426             :   int nl = 0;
    2427           0 :   double x0 = 0;
    2428           0 :   for (int il=fI;il--;) {
    2429             :     //
    2430           0 :     if (il==3) {
    2431           0 :       x2x0MS[nl] = (fUseTGeo==0 ? AliITSRecoParam::Getdshield(1) : fxOverX0Shield[1]);
    2432           0 :       xMS[nl++]  = AliITSRecoParam::GetrInsideShield(1);
    2433           0 :     }
    2434           0 :     else if (il==1) {
    2435           0 :       x2x0MS[nl] = (fUseTGeo==0 ? AliITSRecoParam::Getdshield(0) : fxOverX0Shield[0]);
    2436           0 :       xMS[nl++]  = AliITSRecoParam::GetrInsideShield(0);
    2437           0 :     }
    2438             :     //
    2439           0 :     x2x0MS[nl] = (fUseTGeo==0 ? fgLayers[il].GetThickness(0,0,x0) : fxOverX0Layer[il]);
    2440           0 :     xMS[nl++]  = fgLayers[il].GetR();
    2441             :     //
    2442             :   }
    2443             :   //
    2444             :   // beam pipe
    2445           0 :   x2x0MS[nl]  = (fUseTGeo==0 ? AliITSRecoParam::GetdPipe() : fxOverX0Pipe);
    2446           0 :   xMS[nl++]  = AliITSRecoParam::GetrPipe();
    2447             :   //
    2448           0 :   return nl;
    2449           0 : }
    2450             : 
    2451             : 
    2452             : //------------------------------------------------------------------------
    2453             : Int_t AliITStrackerMI::AliITSlayer::InRoad() const {
    2454             :   //-------------------------------------------------------------------
    2455             :   // This function returns number of clusters within the "window" 
    2456             :   //--------------------------------------------------------------------
    2457             :   Int_t ncl=0;
    2458           0 :   for (Int_t i=fI; i<fN; i++) {
    2459           0 :     const AliITSRecPoint *c=fClusters[i];
    2460           0 :     if (c->GetZ() > fZmax) break;
    2461           0 :     if (c->IsUsed()) continue;
    2462           0 :     const AliITSdetector &det=GetDetector(c->GetDetectorIndex());    
    2463           0 :     Double_t y=fR*det.GetPhi() + c->GetY();
    2464             : 
    2465           0 :     if (y>2.*fR*TMath::Pi()) y -= 2*fR*TMath::Pi();
    2466           0 :     if (y>1.*fR*TMath::Pi() && fYmax<y) y -= 2*fR*TMath::Pi();
    2467             : 
    2468           0 :     if (y<fYmin) continue;
    2469           0 :     if (y>fYmax) continue;
    2470           0 :     ncl++;
    2471           0 :   }
    2472           0 :   return ncl;
    2473             : }
    2474             : //------------------------------------------------------------------------
    2475             : Bool_t AliITStrackerMI::RefitAt(Double_t xx,AliITStrackMI *track,
    2476             :                                 const AliITStrackMI *clusters,Bool_t extra, Bool_t planeeff) 
    2477             : {
    2478             :   //--------------------------------------------------------------------
    2479             :   // This function refits the track "track" at the position "x" using
    2480             :   // the clusters from "clusters"
    2481             :   // If "extra"==kTRUE, 
    2482             :   //    the clusters from overlapped modules get attached to "track" 
    2483             :   // If "planeff"==kTRUE,
    2484             :   //    special approach for plane efficiency evaluation is applyed
    2485             :   //--------------------------------------------------------------------
    2486             : 
    2487        1970 :   Int_t index[AliITSgeomTGeo::kNLayers]={0};
    2488             :   Int_t k;
    2489       27580 :   for (k=0; k<AliITSgeomTGeo::GetNLayers(); k++) index[k]=-1;
    2490        1970 :   Int_t nc=clusters->GetNumberOfClusters();
    2491       22872 :   for (k=0; k<nc; k++) { 
    2492        9466 :     Int_t idx=clusters->GetClusterIndex(k);
    2493        9466 :     Int_t ilayer=(idx&0xf0000000)>>28;
    2494        9466 :     index[ilayer]=idx; 
    2495             :   }
    2496             : 
    2497        3940 :   return RefitAt(xx,track,index,extra,planeeff); // call the method below
    2498        1970 : }
    2499             : //------------------------------------------------------------------------
    2500             : Bool_t AliITStrackerMI::RefitAt(Double_t xx,AliITStrackMI *track,
    2501             :                                 const Int_t *clusters,Bool_t extra, Bool_t planeeff) 
    2502             : {
    2503             :   //--------------------------------------------------------------------
    2504             :   // This function refits the track "track" at the position "x" using
    2505             :   // the clusters from array
    2506             :   // If "extra"==kTRUE, 
    2507             :   //    the clusters from overlapped modules get attached to "track" 
    2508             :   // If "planeff"==kTRUE,
    2509             :   //    special approach for plane efficiency evaluation is applyed
    2510             :   //--------------------------------------------------------------------
    2511        1978 :   Int_t index[AliITSgeomTGeo::kNLayers]={0};
    2512             :   Int_t k;
    2513       27692 :   for (k=0; k<AliITSgeomTGeo::GetNLayers(); k++) index[k]=-1;
    2514             :   //
    2515       27692 :   for (k=0; k<AliITSgeomTGeo::GetNLayers(); k++) { 
    2516       11868 :     index[k]=clusters[k]; 
    2517             :   }
    2518             : 
    2519             :   // special for cosmics and TPC prolonged tracks: 
    2520             :   // propagate to the innermost of:
    2521             :   // - innermost layer crossed by the track
    2522             :   // - innermost layer where a cluster was associated to the track
    2523             :   static AliITSRecoParam *repa = NULL;
    2524        1978 :   if(!repa){
    2525           2 :     repa = (AliITSRecoParam*) AliITSReconstructor::GetRecoParam();
    2526           2 :     if(!repa){
    2527           0 :       repa = AliITSRecoParam::GetHighFluxParam();
    2528           0 :       AliWarning("Using default AliITSRecoParam class");
    2529           0 :     }
    2530             :   }
    2531        1978 :   Int_t evsp=repa->GetEventSpecie();
    2532             :   ULong_t trStatus=0;
    2533        3920 :   if(track->GetESDtrack()) trStatus=track->GetStatus();
    2534             :   Int_t innermostlayer=0;
    2535        3956 :   if((evsp&AliRecoParam::kCosmic) || (trStatus&AliESDtrack::kTPCin))  {
    2536             :     innermostlayer=5;
    2537        1910 :     Double_t drphi = TMath::Abs(track->GetD(0.,0.));
    2538        3896 :     for(innermostlayer=0; innermostlayer<AliITSgeomTGeo::GetNLayers(); innermostlayer++) {
    2539        1986 :       if( (drphi < (fgLayers[innermostlayer].GetR()+1.)) ||
    2540          38 :           index[innermostlayer] >= 0 ) break;
    2541             :     }
    2542             : 
    2543        5730 :     AliDebug(2,Form(" drphi  %f  innermost %d",drphi,innermostlayer));
    2544        1910 :   }
    2545             : 
    2546             :   Int_t modstatus=1; // found
    2547        1978 :   Float_t xloc,zloc;
    2548             :   Int_t from, to, step;
    2549        1978 :   if (xx > track->GetX()) {
    2550         986 :       from=innermostlayer; to=AliITSgeomTGeo::GetNLayers();
    2551             :       step=+1;
    2552         986 :   } else {
    2553         992 :       from=AliITSgeomTGeo::GetNLayers()-1; to=innermostlayer-1;
    2554             :       step=-1;
    2555             :   }
    2556        1978 :   TString dir = (step>0 ? "outward" : "inward");
    2557             : 
    2558       28437 :   for (Int_t ilayer = from; ilayer != to; ilayer += step) {
    2559       11718 :      AliITSlayer &layer=fgLayers[ilayer];
    2560       11718 :      Double_t r=layer.GetR();
    2561             : 
    2562       17846 :      if (step<0 && xx>r) break;
    2563             : 
    2564             :      // material between SSD and SDD, SDD and SPD
    2565       11408 :      Double_t hI=ilayer-0.5*step; 
    2566       11408 :      if (TMath::Abs(hI-3.5)<0.01) // SDDouter
    2567        7896 :        if(!CorrectForShieldMaterial(track,"SDD",dir)) return kFALSE;
    2568       11408 :      if (TMath::Abs(hI-1.5)<0.01) // SPDouter
    2569        7448 :        if(!CorrectForShieldMaterial(track,"SPD",dir)) return kFALSE;
    2570             : 
    2571             : 
    2572       11408 :      Double_t oldGlobXYZ[3]={0};
    2573       22816 :      if (!track->GetXYZ(oldGlobXYZ)) return kFALSE;
    2574             : 
    2575             :      // continue if we are already beyond this layer
    2576       11408 :      Double_t oldGlobR = TMath::Sqrt(oldGlobXYZ[0]*oldGlobXYZ[0]+oldGlobXYZ[1]*oldGlobXYZ[1]);
    2577       17616 :      if(step>0 && oldGlobR > r) continue; // going outward
    2578       16608 :      if(step<0 && oldGlobR < r) continue; // going inward
    2579             : 
    2580       11100 :      Double_t phi,z;
    2581       22200 :      if (!track->GetPhiZat(r,phi,z)) return kFALSE;
    2582             : 
    2583       11100 :      Int_t idet=layer.FindDetectorIndex(phi,z);
    2584             : 
    2585             :      // check if we allow a prolongation without point for large-eta tracks
    2586       11100 :      Int_t skip = CheckSkipLayer(track,ilayer,idet);
    2587       11100 :      if (skip==2) {
    2588             :        modstatus = 4; // out in z
    2589           0 :        if(LocalModuleCoord(ilayer,idet,track,xloc,zloc)) { // local module coords
    2590           0 :          track->SetModuleIndexInfo(ilayer,idet,modstatus,xloc,zloc);
    2591             :        }
    2592             :        // cross layer
    2593             :        // apply correction for material of the current layer
    2594             :        // add time if going outward
    2595           0 :        CorrectForLayerMaterial(track,ilayer,oldGlobXYZ,dir);
    2596           0 :        continue;
    2597             :      }
    2598             : 
    2599       11100 :      if (idet<0) return kFALSE;
    2600             : 
    2601             : 
    2602       11100 :      const AliITSdetector &det=layer.GetDetector(idet);
    2603             :      // only for ITS-SA tracks refit
    2604             :      Bool_t saveCheckInv = kTRUE;
    2605       27740 :      if (ilayer>1 && fTrackingPhase.Contains("RefitInward") && !(track->GetStatus()&AliESDtrack::kTPCin)) {
    2606          64 :        saveCheckInv = track->GetCheckInvariant();
    2607          64 :        track->SetCheckInvariant(kFALSE);
    2608          64 :      }
    2609             :      // 
    2610       22200 :      if (!track->Propagate(det.GetPhi(),det.GetR())) return kFALSE;
    2611             : 
    2612       11100 :      track->SetDetectorIndex(idet);
    2613       22200 :      if(!LocalModuleCoord(ilayer,idet,track,xloc,zloc)) return kFALSE; // local module coords
    2614             : 
    2615       11100 :      Double_t dz,zmin,zmax,dy,ymin,ymax;
    2616             : 
    2617             :      const AliITSRecPoint *clAcc=0;
    2618       22200 :      Double_t maxchi2=1000.*AliITSReconstructor::GetRecoParam()->GetMaxChi2();
    2619             : 
    2620       11100 :      Int_t idx=index[ilayer];
    2621       11100 :      if (idx>=0) { // cluster in this layer
    2622             :        modstatus = 6; // no refit
    2623       18980 :        const AliITSRecPoint *cl=(AliITSRecPoint *)GetCluster(idx); 
    2624        9490 :        if (cl) {
    2625        9490 :          if (idet != cl->GetDetectorIndex()) {
    2626        1430 :            idet=cl->GetDetectorIndex();
    2627        1430 :            const AliITSdetector &detc=layer.GetDetector(idet);
    2628        2860 :            if (!track->Propagate(detc.GetPhi(),detc.GetR())) return kFALSE;
    2629        1430 :            track->SetDetectorIndex(idet);
    2630        2860 :            if(!LocalModuleCoord(ilayer,idet,track,xloc,zloc)) return kFALSE; // local module coords
    2631        1430 :          }
    2632        9490 :          Int_t cllayer = (idx & 0xf0000000) >> 28;;
    2633        9490 :          Double_t chi2=GetPredictedChi2MI(track,cl,cllayer);
    2634        9490 :          if (chi2<maxchi2) { 
    2635             :            clAcc=cl; 
    2636             :            maxchi2=chi2; 
    2637             :            modstatus = 1; // found
    2638             :          } else {
    2639           0 :             return kFALSE; //
    2640             :          }
    2641        9490 :        }
    2642        9490 :      } else { // no cluster in this layer
    2643        1610 :        if (skip==1) {
    2644             :          modstatus = 3; // skipped
    2645             :          // Plane Eff determination:
    2646           0 :          if (planeeff && ilayer==AliITSReconstructor::GetRecoParam()->GetIPlanePlaneEff()) {
    2647           0 :            if (IsOKForPlaneEff(track,clusters,ilayer))  // only adequate track for plane eff. evaluation
    2648           0 :               UseTrackForPlaneEff(track,ilayer);
    2649             :          }
    2650             :        } else {
    2651             :          modstatus = 5; // no cls in road
    2652             :          // check dead
    2653        3220 :          if (!ComputeRoad(track,ilayer,idet,zmin,zmax,ymin,ymax)) return kFALSE;
    2654        1610 :          dz = 0.5*(zmax-zmin);
    2655        1610 :          dy = 0.5*(ymax-ymin);
    2656        1610 :          Int_t dead = CheckDeadZone(track,ilayer,idet,dz,dy,kTRUE);
    2657        2362 :          if (dead==1) modstatus = 7; // holes in z in SPD
    2658        1962 :          if (dead==2 || dead==3 || dead==4) modstatus = 2; // dead from OCDB
    2659             :        }
    2660             :      }
    2661             :      
    2662       11100 :      if (clAcc) {
    2663       18980 :        if (!UpdateMI(track,clAcc,maxchi2,idx)) return kFALSE;
    2664        9490 :        track->SetSampledEdx(clAcc->GetQ(),ilayer-2);
    2665             :      }
    2666       11100 :      track->SetModuleIndexInfo(ilayer,idet,modstatus,xloc,zloc);
    2667             : 
    2668             : 
    2669       11100 :      if (extra && clAcc) { // search for extra clusters in overlapped modules
    2670         514 :        AliITStrackV2 tmp(*track);
    2671        1028 :        if (!ComputeRoad(track,ilayer,idet,zmin,zmax,ymin,ymax)) return kFALSE;
    2672         514 :        layer.SelectClusters(zmin,zmax,ymin,ymax);
    2673             :        
    2674         514 :        const AliITSRecPoint *clExtra=0; Int_t ci=-1,cci=-1;
    2675             :        Int_t idetExtra=-1;  
    2676        1028 :        maxchi2=1000.*AliITSReconstructor::GetRecoParam()->GetMaxChi2();
    2677             :        Double_t tolerance=0.1;
    2678        2746 :        while ((clExtra=layer.GetNextCluster(ci))!=0) {
    2679             :          // only clusters in another module! (overlaps)
    2680         602 :          idetExtra = clExtra->GetDetectorIndex();
    2681         602 :          if (idet == idetExtra) continue;
    2682             :          
    2683          68 :          const AliITSdetector &detx=layer.GetDetector(idetExtra);
    2684             :          
    2685         136 :          if (!tmp.Propagate(detx.GetPhi(),detx.GetR()+clExtra->GetX())) continue;
    2686         184 :          if (TMath::Abs(tmp.GetZ() - clExtra->GetZ()) > tolerance) continue;
    2687          40 :          if (TMath::Abs(tmp.GetY() - clExtra->GetY()) > tolerance) continue;
    2688          40 :          if (!tmp.Propagate(detx.GetPhi(),detx.GetR())) continue;
    2689             :          
    2690          20 :          Double_t chi2=tmp.GetPredictedChi2(clExtra);
    2691          40 :          if (chi2<maxchi2) { maxchi2=chi2; cci=ci; }
    2692          20 :        }
    2693         514 :        if (cci>=0) {
    2694          20 :          track->SetExtraCluster(ilayer,(ilayer<<28)+cci);
    2695          20 :          track->SetExtraModule(ilayer,idetExtra);
    2696          20 :        }
    2697        1028 :      } // end search for extra clusters in overlapped modules
    2698             :      
    2699             :      // Correct for material of the current layer
    2700             :      // cross material
    2701             :      // add time if going outward
    2702       33301 :      if(!CorrectForLayerMaterial(track,ilayer,oldGlobXYZ,dir)) return kFALSE;
    2703       11099 :      track->SetCheckInvariant(saveCheckInv);
    2704       44707 :   } // end loop on layers
    2705             : 
    2706        3955 :   if (!track->PropagateTo(xx,0.,0.)) return kFALSE;
    2707             : 
    2708        1976 :   return kTRUE;
    2709        1978 : }
    2710             : //------------------------------------------------------------------------
    2711             : Double_t AliITStrackerMI::GetNormalizedChi2(AliITStrackMI * track, Int_t mode)
    2712             : {
    2713             :   //
    2714             :   // calculate normalized chi2
    2715             :   //  return NormalizedChi2(track,0);
    2716             :   Float_t chi2 = 0;
    2717             :   Float_t sum=0;
    2718       10636 :   Float_t *erry = GetErrY(fCurrentEsdTrack), *errz = GetErrZ(fCurrentEsdTrack);
    2719             :   //  track->fdEdxMismatch=0;
    2720             :   Float_t dedxmismatch =0;
    2721        5318 :   Float_t *ny = GetNy(fCurrentEsdTrack), *nz = GetNz(fCurrentEsdTrack); 
    2722        5318 :   if (mode<100){
    2723       74452 :     for (Int_t i = 0;i<6;i++){
    2724       31908 :       if (track->GetClIndex(i)>=0){
    2725             :         Float_t cerry, cerrz;
    2726       50706 :         if (ny[i]>0) {cerry = erry[i]; cerrz=errz[i];}
    2727             :         else 
    2728          74 :           { cerry= track->GetSigmaY(i); cerrz = track->GetSigmaZ(i);}
    2729       25390 :         cerry*=cerry;
    2730       25390 :         cerrz*=cerrz;   
    2731       25390 :         Float_t cchi2 = (track->GetDy(i)*track->GetDy(i)/cerry)+(track->GetDz(i)*track->GetDz(i)/cerrz);
    2732       45498 :         if (i>1 && AliITSReconstructor::GetRecoParam()->GetUseAmplitudeInfo(i)) {
    2733       20108 :           Float_t ratio = track->GetNormQ(i)/track->GetExpQ();
    2734       20108 :           if (ratio<0.5) {
    2735           0 :             cchi2+=(0.5-ratio)*10.;
    2736             :             //track->fdEdxMismatch+=(0.5-ratio)*10.;
    2737           0 :             dedxmismatch+=(0.5-ratio)*10.;          
    2738           0 :           }
    2739       20108 :         }
    2740       25390 :         if (i<2 ||i>3){
    2741       15190 :           AliITSRecPoint * cl = (AliITSRecPoint*)GetCluster( track->GetClIndex(i));  
    2742       15190 :           Double_t delta = cl->GetNy()+cl->GetNz()-ny[i]-nz[i];
    2743       15680 :           if (delta>1) chi2 +=0.5*TMath::Min(delta/2,2.); 
    2744       20472 :           if (i<2) chi2+=2*cl->GetDeltaProbability();
    2745       15190 :         }
    2746       25390 :         chi2+=cchi2;
    2747       25390 :         sum++;
    2748       25390 :       }
    2749             :     }
    2750        5318 :     if (TMath::Abs(track->GetdEdxMismatch()-dedxmismatch)>0.0001){
    2751           0 :       track->SetdEdxMismatch(dedxmismatch);
    2752           0 :     }
    2753             :   }
    2754             :   else{
    2755           0 :     for (Int_t i = 0;i<4;i++){
    2756           0 :       if (track->GetClIndex(i)>=0){
    2757             :         Float_t cerry, cerrz;
    2758           0 :         if (ny[i]>0) {cerry = erry[i]; cerrz=errz[i];}
    2759           0 :         else { cerry= track->GetSigmaY(i); cerrz = track->GetSigmaZ(i);}
    2760           0 :         cerry*=cerry;
    2761           0 :         cerrz*=cerrz;
    2762           0 :         chi2+= (track->GetDy(i)*track->GetDy(i)/cerry);
    2763           0 :         chi2+= (track->GetDz(i)*track->GetDz(i)/cerrz);      
    2764           0 :         sum++;
    2765           0 :       }
    2766             :     }
    2767           0 :     for (Int_t i = 4;i<6;i++){
    2768           0 :       if (track->GetClIndex(i)>=0){       
    2769             :         Float_t cerry, cerrz;
    2770           0 :         if (ny[i]>0) {cerry = erry[i]; cerrz=errz[i];}
    2771           0 :         else { cerry= track->GetSigmaY(i); cerrz = track->GetSigmaZ(i);}
    2772           0 :         cerry*=cerry;
    2773           0 :         cerrz*=cerrz;   
    2774             :         Float_t cerryb, cerrzb;
    2775           0 :         if (ny[i+6]>0) {cerryb = erry[i+6]; cerrzb=errz[i+6];}
    2776           0 :         else { cerryb= track->GetSigmaY(i+6); cerrzb = track->GetSigmaZ(i+6);}
    2777           0 :         cerryb*=cerryb;
    2778           0 :         cerrzb*=cerrzb;
    2779           0 :         chi2+= TMath::Min((track->GetDy(i+6)*track->GetDy(i+6)/cerryb),track->GetDy(i)*track->GetDy(i)/cerry);
    2780           0 :         chi2+= TMath::Min((track->GetDz(i+6)*track->GetDz(i+6)/cerrzb),track->GetDz(i)*track->GetDz(i)/cerrz);      
    2781           0 :         sum++;
    2782           0 :       }
    2783             :     }
    2784             :   }
    2785        5318 :   if (track->GetESDtrack()->GetTPCsignal()>85){
    2786           0 :     Float_t ratio = track->GetdEdx()/track->GetESDtrack()->GetTPCsignal();
    2787           0 :     if (ratio<0.5) {
    2788           0 :       chi2+=(0.5-ratio)*5.;      
    2789           0 :     }
    2790           0 :     if (ratio>2){
    2791           0 :       chi2+=(ratio-2.0)*3; 
    2792           0 :     }
    2793           0 :   }
    2794             :   //
    2795        5318 :   Double_t match = TMath::Sqrt(track->GetChi22());
    2796        8724 :   if (track->GetConstrain())  match/=track->GetNumberOfClusters();
    2797        5318 :   if (!track->GetConstrain()) { 
    2798        1912 :     if (track->GetNumberOfClusters()>2) {
    2799        1912 :       match/=track->GetNumberOfClusters()-2.;
    2800        1912 :     } else {
    2801             :       match=0;
    2802             :     }
    2803             :   }
    2804        5318 :   if (match<0) match=0;
    2805             : 
    2806             :   // penalty factor for missing points (NDeadZone>0), but no penalty
    2807             :   // for layer with deadZoneProb close to 1 (either we wanted to skip layer
    2808             :   // or there is a dead from OCDB)
    2809             :   Float_t deadzonefactor = 0.; 
    2810        5318 :   if (track->GetNDeadZone()>0.) {    
    2811             :     Int_t sumDeadZoneProbability=0; 
    2812       35420 :     for(Int_t ilay=0;ilay<6;ilay++) {
    2813       17508 :       if(track->GetDeadZoneProbability(ilay)>0.) sumDeadZoneProbability++;
    2814             :     }
    2815        2530 :     Int_t nDeadZoneWithProbNot1=(Int_t)(track->GetNDeadZone())-sumDeadZoneProbability;
    2816        2530 :     if(nDeadZoneWithProbNot1>0) {
    2817         272 :       Float_t deadZoneProbability = track->GetNDeadZone()-(Float_t)sumDeadZoneProbability;
    2818         816 :       AliDebug(2,Form("nDeadZone %f sumDZProbability %d nDZWithProbNot1 %d deadZoneProb %f\n",track->GetNDeadZone(),sumDeadZoneProbability,nDeadZoneWithProbNot1,deadZoneProbability));
    2819         272 :       deadZoneProbability /= (Float_t)nDeadZoneWithProbNot1;
    2820             :       Float_t one = 1.;
    2821         272 :       deadZoneProbability = TMath::Min(deadZoneProbability,one);
    2822         272 :       deadzonefactor = 3.*(1.1-deadZoneProbability);  
    2823         272 :     }
    2824        2530 :   }  
    2825             : 
    2826       10636 :   Double_t normchi2 = 2*track->GetNSkipped()+match+deadzonefactor+(1+(2*track->GetNSkipped()+deadzonefactor)/track->GetNumberOfClusters())*
    2827       10636 :     (chi2)/TMath::Max(double(sum-track->GetNSkipped()),
    2828        5318 :                                 1./(1.+track->GetNSkipped()));     
    2829       15954 :   AliDebug(2,Form("match %f deadzonefactor %f chi2 %f sum %f skipped %f\n",match,deadzonefactor,chi2,sum,track->GetNSkipped()));
    2830       15954 :   AliDebug(2,Form("NormChi2 %f  cls %d\n",normchi2,track->GetNumberOfClusters()));
    2831        5318 :   return normchi2;
    2832             : }
    2833             : //------------------------------------------------------------------------
    2834             : Double_t AliITStrackerMI::GetMatchingChi2(const AliITStrackMI * track1,const AliITStrackMI * track2)
    2835             : {
    2836             :   //
    2837             :   // return matching chi2 between two tracks
    2838             :   Double_t largeChi2=1000.;
    2839             : 
    2840        1740 :   AliITStrackMI track3(*track2);
    2841        3480 :   if (!track3.Propagate(track1->GetAlpha(),track1->GetX())) return largeChi2;
    2842         870 :   TMatrixD vec(5,1);
    2843        3480 :   vec(0,0)=track1->GetY()   - track3.GetY();
    2844        3480 :   vec(1,0)=track1->GetZ()   - track3.GetZ();
    2845        3480 :   vec(2,0)=track1->GetSnp() - track3.GetSnp();
    2846        3480 :   vec(3,0)=track1->GetTgl() - track3.GetTgl();
    2847        3480 :   vec(4,0)=track1->GetSigned1Pt() - track3.GetSigned1Pt();
    2848             :   //
    2849         870 :   TMatrixD cov(5,5);
    2850        1740 :   cov(0,0) = track1->GetSigmaY2()+track3.GetSigmaY2();
    2851        1740 :   cov(1,1) = track1->GetSigmaZ2()+track3.GetSigmaZ2();
    2852        3480 :   cov(2,2) = track1->GetSigmaSnp2()+track3.GetSigmaSnp2();
    2853        1740 :   cov(3,3) = track1->GetSigmaTgl2()+track3.GetSigmaTgl2();
    2854        1740 :   cov(4,4) = track1->GetSigma1Pt2()+track3.GetSigma1Pt2();
    2855             :   
    2856        2610 :   cov(0,1)=cov(1,0) = track1->GetSigmaZY()+track3.GetSigmaZY();
    2857        2610 :   cov(0,2)=cov(2,0) = track1->GetSigmaSnpY()+track3.GetSigmaSnpY();
    2858        2610 :   cov(0,3)=cov(3,0) = track1->GetSigmaTglY()+track3.GetSigmaTglY();
    2859        2610 :   cov(0,4)=cov(4,0) = track1->GetSigma1PtY()+track3.GetSigma1PtY();
    2860             :   //
    2861        2610 :   cov(1,2)=cov(2,1) = track1->GetSigmaSnpZ()+track3.GetSigmaSnpZ();
    2862        2610 :   cov(1,3)=cov(3,1) = track1->GetSigmaTglZ()+track3.GetSigmaTglZ();
    2863        2610 :   cov(1,4)=cov(4,1) = track1->GetSigma1PtZ()+track3.GetSigma1PtZ();
    2864             :   //
    2865        2610 :   cov(2,3)=cov(3,2) = track1->GetSigmaTglSnp()+track3.GetSigmaTglSnp();
    2866        2610 :   cov(2,4)=cov(4,2) = track1->GetSigma1PtSnp()+track3.GetSigma1PtSnp();
    2867             :   //
    2868        2610 :   cov(3,4)=cov(4,3) = track1->GetSigma1PtTgl()+track3.GetSigma1PtTgl();
    2869             :   
    2870         870 :   cov.Invert();
    2871         870 :   TMatrixD vec2(cov,TMatrixD::kMult,vec);
    2872         870 :   TMatrixD chi2(vec2,TMatrixD::kTransposeMult,vec);
    2873        1740 :   return chi2(0,0);
    2874        1740 : }
    2875             : //------------------------------------------------------------------------
    2876             : Double_t  AliITStrackerMI::GetSPDDeadZoneProbability(Double_t zpos, Double_t zerr) const
    2877             : {
    2878             :   //
    2879             :   //  return probability that given point (characterized by z position and error) 
    2880             :   //  is in SPD dead zone
    2881             :   //     This method assumes that fSPDdetzcentre is ordered from -z to +z
    2882             :   //
    2883             :   Double_t probability = 0.;
    2884             :   Double_t nearestz = 0.,distz=0.;
    2885             :   Int_t    nearestzone = -1;
    2886             :   Double_t mindistz = 1000.;
    2887             : 
    2888             :   // find closest dead zone
    2889       15570 :   for (Int_t i=0; i<3; i++) {
    2890        5190 :     distz=TMath::Abs(zpos-0.5*(fSPDdetzcentre[i]+fSPDdetzcentre[i+1]));
    2891        5190 :     if (distz<mindistz) {
    2892             :       nearestzone=i;
    2893        3460 :       nearestz=0.5*(fSPDdetzcentre[i]+fSPDdetzcentre[i+1]);
    2894             :       mindistz=distz;
    2895        3460 :     }
    2896             :   }
    2897             : 
    2898             :   // too far from dead zone
    2899        1852 :   if (TMath::Abs(zpos-nearestz)>0.25+3.*zerr) return probability;
    2900             : 
    2901             : 
    2902             :   Double_t zmin, zmax;   
    2903        1608 :   if (nearestzone==0) { // dead zone at z = -7
    2904           0 :     zmin = fSPDdetzcentre[0] + 0.5*AliITSRecoParam::GetSPDdetzlength();
    2905           0 :     zmax = fSPDdetzcentre[1] - 0.5*AliITSRecoParam::GetSPDdetzlength();
    2906        1608 :   } else if (nearestzone==1) { // dead zone at z = 0
    2907        1608 :     zmin = fSPDdetzcentre[1] + 0.5*AliITSRecoParam::GetSPDdetzlength();
    2908        1608 :     zmax = fSPDdetzcentre[2] - 0.5*AliITSRecoParam::GetSPDdetzlength();
    2909        1608 :   } else if (nearestzone==2) { // dead zone at z = +7
    2910           0 :     zmin = fSPDdetzcentre[2] + 0.5*AliITSRecoParam::GetSPDdetzlength();
    2911           0 :     zmax = fSPDdetzcentre[3] - 0.5*AliITSRecoParam::GetSPDdetzlength();
    2912           0 :   } else {
    2913             :     zmin = 0.;
    2914             :     zmax = 0.;
    2915             :   }
    2916             :   // probability that the true z is in the range [zmin,zmax] (i.e. inside 
    2917             :   // dead zone)
    2918        3216 :   probability = 0.5*( AliMathBase::ErfFast((zpos-zmin)/zerr/TMath::Sqrt(2.)) - 
    2919        1608 :                       AliMathBase::ErfFast((zpos-zmax)/zerr/TMath::Sqrt(2.)) );
    2920        4824 :   AliDebug(2,Form("zpos %f +- %f nearestzone %d  zmin zmax %f %f prob %f\n",zpos,zerr,nearestzone,zmin,zmax,probability));
    2921             :   return probability;
    2922        1730 : }
    2923             : //------------------------------------------------------------------------
    2924             : Double_t AliITStrackerMI::GetTruncatedChi2(const AliITStrackMI * track, Float_t fac)
    2925             : {
    2926             :   //
    2927             :   // calculate normalized chi2
    2928           0 :   Float_t chi2[6]={0};
    2929           0 :   Float_t *erry = GetErrY(fCurrentEsdTrack), *errz = GetErrZ(fCurrentEsdTrack);
    2930             :   Float_t ncl = 0;
    2931           0 :   for (Int_t i = 0;i<6;i++){
    2932           0 :     if (TMath::Abs(track->GetDy(i))>0){      
    2933           0 :       chi2[i]= (track->GetDy(i)/erry[i])*(track->GetDy(i)/erry[i]);
    2934           0 :       chi2[i]+= (track->GetDz(i)/errz[i])*(track->GetDz(i)/errz[i]);
    2935           0 :       ncl++;
    2936           0 :     }
    2937           0 :     else{chi2[i]=10000;}
    2938             :   }
    2939           0 :   Int_t index[6]={0};
    2940           0 :   TMath::Sort(6,chi2,index,kFALSE);
    2941           0 :   Float_t max = float(ncl)*fac-1.;
    2942             :   Float_t sumchi=0, sumweight=0; 
    2943           0 :   for (Int_t i=0;i<max+1;i++){
    2944           0 :     Float_t weight = (i<max)?1.:(max+1.-i);
    2945           0 :     sumchi+=weight*chi2[index[i]];
    2946           0 :     sumweight+=weight;
    2947             :   }
    2948           0 :   Double_t normchi2 = sumchi/sumweight;
    2949           0 :   return normchi2;
    2950           0 : }
    2951             : //------------------------------------------------------------------------
    2952             : Double_t AliITStrackerMI::GetInterpolatedChi2(const AliITStrackMI * forwardtrack,const AliITStrackMI * backtrack)
    2953             : {
    2954             :   //
    2955             :   // calculate normalized chi2
    2956             :   //  if (forwardtrack->fNUsed>0.3*float(forwardtrack->GetNumberOfClusters())) return 10000;
    2957             :   Int_t npoints = 0;
    2958             :   Double_t res =0;
    2959       13020 :   for (Int_t i=0;i<6;i++){
    2960        9538 :     if ( (backtrack->GetSigmaY(i)<0.000000001) || (forwardtrack->GetSigmaY(i)<0.000000001)) continue;
    2961        4116 :     Double_t sy1 = forwardtrack->GetSigmaY(i);
    2962        4116 :     Double_t sz1 = forwardtrack->GetSigmaZ(i);
    2963        4116 :     Double_t sy2 = backtrack->GetSigmaY(i);
    2964        4116 :     Double_t sz2 = backtrack->GetSigmaZ(i);
    2965        4942 :     if (i<2){ sy2=1000.;sz2=1000;}
    2966             :     //    
    2967        4116 :     Double_t dy0 = (forwardtrack->GetDy(i)/(sy1*sy1) +backtrack->GetDy(i)/(sy2*sy2))/(1./(sy1*sy1)+1./(sy2*sy2));
    2968        4116 :     Double_t dz0 = (forwardtrack->GetDz(i)/(sz1*sz1) +backtrack->GetDz(i)/(sz2*sz2))/(1./(sz1*sz1)+1./(sz2*sz2));
    2969             :     // 
    2970        4116 :     Double_t nz0 = dz0*TMath::Sqrt((1./(sz1*sz1)+1./(sz2*sz2)));
    2971        4116 :     Double_t ny0 = dy0*TMath::Sqrt((1./(sy1*sy1)+1./(sy2*sy2)));
    2972             :     //
    2973        4116 :     res+= nz0*nz0+ny0*ny0;
    2974        4116 :     npoints++;
    2975        4116 :   }
    2976        1736 :   if (npoints>1) return 
    2977        1736 :                    TMath::Max(0.3*forwardtrack->OneOverPt()-0.5,0.)+
    2978             :                    //2*forwardtrack->fNUsed+
    2979        1736 :                    res/TMath::Max(double(npoints-forwardtrack->GetNSkipped()),
    2980         868 :                                   1./(1.+forwardtrack->GetNSkipped()));
    2981           0 :   return 1000;
    2982         868 : }
    2983             : /*
    2984             :   RS: Not used
    2985             : //------------------------------------------------------------------------
    2986             : Float_t  *AliITStrackerMI::GetWeight(Int_t index) {
    2987             :   //--------------------------------------------------------------------
    2988             :   //       Return pointer to a given cluster
    2989             :   //--------------------------------------------------------------------
    2990             :   Int_t l=(index & 0xf0000000) >> 28;
    2991             :   Int_t c=(index & 0x0fffffff) >> 00;
    2992             :   return fgLayers[l].GetWeight(c);
    2993             : }
    2994             : */
    2995             : 
    2996             : //------------------------------------------------------------------------
    2997             : void AliITStrackerMI::RegisterClusterTracks(const AliITStrackMI* track,Int_t id)
    2998             : {
    2999             :   //---------------------------------------------
    3000             :   // register track to the list
    3001             :   //
    3002         512 :   if (track->GetESDtrack()->GetKinkIndex(0)!=0) return;  //don't register kink tracks
    3003             :   //
    3004             :   //
    3005        2960 :   for (Int_t icluster=0;icluster<track->GetNumberOfClusters();icluster++){
    3006        1224 :     Int_t index = track->GetClusterIndex(icluster);
    3007        1224 :     Int_t l=(index & 0xf0000000) >> 28;
    3008        1224 :     Int_t c=(index & 0x0fffffff) >> 00;
    3009        1224 :     if (c>fgLayers[l].GetNumberOfClusters()) continue;
    3010        3304 :     for (Int_t itrack=0;itrack<4;itrack++){
    3011        1652 :       if (fgLayers[l].GetClusterTracks(itrack,c)<0){
    3012        1224 :         fgLayers[l].SetClusterTracks(itrack,c,id);
    3013        1224 :         break;
    3014             :       }
    3015             :     }
    3016        1224 :   }
    3017         256 : }
    3018             : //------------------------------------------------------------------------
    3019             : void AliITStrackerMI::UnRegisterClusterTracks(const AliITStrackMI* track, Int_t id)
    3020             : {
    3021             :   //---------------------------------------------
    3022             :   // unregister track from the list
    3023        2218 :   for (Int_t icluster=0;icluster<track->GetNumberOfClusters();icluster++){
    3024         812 :     Int_t index = track->GetClusterIndex(icluster);
    3025         812 :     Int_t l=(index & 0xf0000000) >> 28;
    3026         812 :     Int_t c=(index & 0x0fffffff) >> 00;
    3027         812 :     if (c>fgLayers[l].GetNumberOfClusters()) continue;
    3028        8120 :     for (Int_t itrack=0;itrack<4;itrack++){
    3029        3248 :       if (fgLayers[l].GetClusterTracks(itrack,c)==id){
    3030         464 :         fgLayers[l].SetClusterTracks(itrack,c,-1);
    3031         464 :       }
    3032             :     }
    3033         812 :   }
    3034         198 : }
    3035             : //------------------------------------------------------------------------
    3036             : Float_t AliITStrackerMI::GetNumberOfSharedClusters(AliITStrackMI* track,Int_t id, Int_t list[6], AliITSRecPoint *clist[6])
    3037             : {
    3038             :   //-------------------------------------------------------------
    3039             :   //get number of shared clusters
    3040             :   //-------------------------------------------------------------
    3041             :   Float_t shared=0;
    3042       19620 :   for (Int_t i=0;i<6;i++) { list[i]=-1, clist[i]=0;}
    3043             :   // mean  number of clusters
    3044        1308 :   Float_t *ny = GetNy(id), *nz = GetNz(id); 
    3045             : 
    3046             :  
    3047       15180 :   for (Int_t icluster=0;icluster<track->GetNumberOfClusters();icluster++){
    3048        6282 :     Int_t index = track->GetClusterIndex(icluster);
    3049        6282 :     Int_t l=(index & 0xf0000000) >> 28;
    3050        6282 :     Int_t c=(index & 0x0fffffff) >> 00;
    3051        6282 :     if (c>fgLayers[l].GetNumberOfClusters()) continue;
    3052             :     // if (ny[l]<1.e-13){
    3053             :     //   printf("problem\n");
    3054             :     // }
    3055        6282 :     AliITSRecPoint *cl = (AliITSRecPoint*)GetCluster(index);
    3056             :     Float_t weight=1;
    3057             :     //
    3058             :     Float_t deltan = 0;
    3059        8818 :     if (l>3&&cl->GetNy()+cl->GetNz()>6) continue;
    3060        9954 :     if (l>2&&AliITSReconstructor::GetRecoParam()->GetUseAmplitudeInfo(l))
    3061        5353 :       if (track->GetNormQ(l)/track->GetExpQ()>3.5) continue;
    3062        4601 :     if (l<2 || l>3){      
    3063        2638 :       deltan = (cl->GetNy()+cl->GetNz()-ny[l]-nz[l]);
    3064        2638 :     }
    3065             :     else{
    3066        1963 :       deltan = (cl->GetNz()-nz[l]);
    3067             :     }
    3068        4633 :     if (deltan>2.0) continue;  // extended - highly probable shared cluster
    3069        4569 :     weight = 2./TMath::Max(3.+deltan,2.);
    3070             :     //
    3071       49339 :     for (Int_t itrack=0;itrack<4;itrack++){
    3072       21018 :       if (fgLayers[l].GetClusterTracks(itrack,c)>=0 && fgLayers[l].GetClusterTracks(itrack,c)!=id){
    3073         112 :         list[l]=index;
    3074         112 :         clist[l] = (AliITSRecPoint*)GetCluster(index);
    3075         112 :         track->SetSharedWeight(l,weight);
    3076         112 :         shared+=weight; 
    3077         112 :         break;
    3078             :       }
    3079             :     }
    3080        4569 :   }
    3081        1308 :   track->SetNUsed(shared);
    3082        1308 :   return shared;
    3083             : }
    3084             : //------------------------------------------------------------------------
    3085             : Int_t AliITStrackerMI::GetOverlapTrack(const AliITStrackMI *track, Int_t trackID, Int_t &shared, Int_t clusterlist[6],Int_t overlist[6])
    3086             : {
    3087             :   //
    3088             :   // find first shared track 
    3089             :   //
    3090             :   // mean  number of clusters
    3091          20 :   Float_t *ny = GetNy(trackID), *nz = GetNz(trackID); 
    3092             :   //
    3093         140 :   for (Int_t i=0;i<6;i++) overlist[i]=-1;
    3094             :   Int_t sharedtrack=100000;
    3095          10 :   Int_t tracks[24]={0},trackindex=0;
    3096         500 :   for (Int_t i=0;i<24;i++) {tracks[i]=-1;}
    3097             :   //
    3098         140 :   for (Int_t icluster=0;icluster<6;icluster++){
    3099          60 :     if (clusterlist[icluster]<0) continue;
    3100             :     Int_t index = clusterlist[icluster];
    3101          10 :     Int_t l=(index & 0xf0000000) >> 28;
    3102          10 :     Int_t c=(index & 0x0fffffff) >> 00;
    3103             :     // if (ny[l]<1.e-13){
    3104             :     //   printf("problem\n");
    3105             :     // }
    3106          10 :     if (c>fgLayers[l].GetNumberOfClusters()) continue;
    3107             :     //if (l>3) continue;
    3108          10 :     AliITSRecPoint *cl = (AliITSRecPoint*)GetCluster(index);
    3109             :     //
    3110             :     Float_t deltan = 0;
    3111          10 :     if (l>3&&cl->GetNy()+cl->GetNz()>6) continue;
    3112          14 :     if (l>2&&AliITSReconstructor::GetRecoParam()->GetUseAmplitudeInfo(l))
    3113           4 :       if (track->GetNormQ(l)/track->GetExpQ()>3.5) continue;
    3114          10 :     if (l<2 || l>3){      
    3115           0 :       deltan = (cl->GetNy()+cl->GetNz()-ny[l]-nz[l]);
    3116           0 :     }
    3117             :     else{
    3118          10 :       deltan = (cl->GetNz()-nz[l]);
    3119             :     }
    3120          10 :     if (deltan>2.0) continue;  // extended - highly probable shared cluster
    3121             :     //
    3122         100 :     for (Int_t itrack=3;itrack>=0;itrack--){
    3123          40 :       if (fgLayers[l].GetClusterTracks(itrack,c)<0) continue;
    3124          12 :       if (fgLayers[l].GetClusterTracks(itrack,c)!=trackID){
    3125          12 :        tracks[trackindex]  = fgLayers[l].GetClusterTracks(itrack,c);
    3126          12 :        trackindex++;
    3127          12 :       }
    3128             :     }
    3129          10 :   }
    3130          10 :   if (trackindex==0) return -1;
    3131          10 :   if (trackindex==1){    
    3132           8 :     sharedtrack = tracks[0];
    3133           8 :   }else{
    3134           4 :     if (trackindex==2) sharedtrack =TMath::Min(tracks[0],tracks[1]);
    3135             :     else{
    3136             :       //
    3137           0 :       Int_t tracks2[24]={0}, cluster[24]={0};
    3138           0 :       for (Int_t i=0;i<24;i++){ tracks2[i]=-1; cluster[i]=0;}
    3139             :       Int_t index =0;
    3140             :       //
    3141           0 :       for (Int_t i=0;i<trackindex;i++){
    3142           0 :         if (tracks[i]<0) continue;
    3143           0 :         tracks2[index] = tracks[i];
    3144           0 :         cluster[index]++;       
    3145           0 :         for (Int_t j=i+1;j<trackindex;j++){
    3146           0 :           if (tracks[j]<0) continue;
    3147           0 :           if (tracks[j]==tracks[i]){
    3148           0 :             cluster[index]++;
    3149           0 :             tracks[j]=-1;
    3150           0 :           }
    3151             :         }
    3152           0 :         index++;
    3153           0 :       }
    3154             :       Int_t max=0;
    3155           0 :       for (Int_t i=0;i<index;i++){
    3156           0 :         if (cluster[index]>max) {
    3157           0 :           sharedtrack=tracks2[index];
    3158             :           max=cluster[index];
    3159           0 :         }
    3160             :       }
    3161           0 :     }
    3162             :   }
    3163             :   
    3164          10 :   if (sharedtrack>=100000) return -1;
    3165             :   //
    3166             :   // make list of overlaps
    3167          10 :   shared =0;
    3168         140 :   for (Int_t icluster=0;icluster<6;icluster++){
    3169          60 :     if (clusterlist[icluster]<0) continue;
    3170             :     Int_t index = clusterlist[icluster];
    3171          10 :     Int_t l=(index & 0xf0000000) >> 28;
    3172          10 :     Int_t c=(index & 0x0fffffff) >> 00;
    3173          10 :     if (c>fgLayers[l].GetNumberOfClusters()) continue;
    3174          10 :     AliITSRecPoint *cl = (AliITSRecPoint*)GetCluster(index);
    3175          10 :     if (l==0 || l==1){
    3176           0 :       if (cl->GetNy()>2) continue;
    3177           0 :       if (cl->GetNz()>2) continue;
    3178             :     }
    3179          10 :     if (l==4 || l==5){
    3180           0 :       if (cl->GetNy()>3) continue;
    3181           0 :       if (cl->GetNz()>3) continue;
    3182             :     }
    3183             :     //
    3184         100 :     for (Int_t itrack=3;itrack>=0;itrack--){
    3185          40 :       if (fgLayers[l].GetClusterTracks(itrack,c)<0) continue;
    3186          12 :       if (fgLayers[l].GetClusterTracks(itrack,c)==sharedtrack){
    3187          12 :         overlist[l]=index;
    3188          12 :         shared++;      
    3189          12 :       }
    3190             :     }
    3191          10 :   }
    3192          10 :   return sharedtrack;
    3193          10 : }
    3194             : //------------------------------------------------------------------------
    3195             : AliITStrackMI *  AliITStrackerMI::GetBest2Tracks(Int_t trackID1, Int_t trackID2, Float_t th0, Float_t th1,AliITStrackMI* original){
    3196             :   //
    3197             :   // try to find track hypothesys without conflicts
    3198             :   // with minimal chi2;
    3199          20 :   TClonesArray *arr1 = (TClonesArray*)fTrackHypothesys.At(trackID1);
    3200          10 :   Int_t entries1 = arr1->GetEntriesFast();
    3201          10 :   TClonesArray *arr2 = (TClonesArray*)fTrackHypothesys.At(trackID2);
    3202          10 :   if (!arr2) return (AliITStrackMI*) arr1->UncheckedAt(0);
    3203          10 :   Int_t entries2 = arr2->GetEntriesFast();
    3204          10 :   if (entries2<=0) return (AliITStrackMI*) arr1->UncheckedAt(0);
    3205             :   //
    3206          10 :   AliITStrackMI * track10=(AliITStrackMI*) arr1->UncheckedAt(0);
    3207          10 :   AliITStrackMI * track20=(AliITStrackMI*) arr2->UncheckedAt(0);
    3208          10 :   if (track10->Pt()>0.5+track20->Pt()) return track10;
    3209             :   //
    3210          84 :   for (Int_t itrack=0;itrack<entries1;itrack++){
    3211          32 :     AliITStrackMI * track=(AliITStrackMI*) arr1->UncheckedAt(itrack);
    3212          32 :     UnRegisterClusterTracks(track,trackID1);
    3213             :   }
    3214             :   //
    3215          52 :   for (Int_t itrack=0;itrack<entries2;itrack++){
    3216          16 :     AliITStrackMI * track=(AliITStrackMI*) arr2->UncheckedAt(itrack);
    3217          16 :     UnRegisterClusterTracks(track,trackID2);
    3218             :   }
    3219             :   Int_t index1=0;
    3220             :   Int_t index2=0;
    3221             :   Float_t maxconflicts=6;
    3222             :   Double_t maxchi2 =1000.;
    3223             :   //
    3224             :   // get weight of hypothesys - using best hypothesy
    3225             :   Double_t w1,w2;
    3226             :  
    3227          10 :   Int_t list1[6]={0},list2[6]={0};
    3228          10 :   AliITSRecPoint *clist1[6]={0}, *clist2[6]={0} ;
    3229          10 :   RegisterClusterTracks(track10,trackID1);
    3230          10 :   RegisterClusterTracks(track20,trackID2);
    3231          10 :   Float_t conflict1 = GetNumberOfSharedClusters(track10,trackID1,list1,clist1);
    3232          10 :   Float_t conflict2 = GetNumberOfSharedClusters(track20,trackID2,list2,clist2);
    3233          10 :   UnRegisterClusterTracks(track10,trackID1);
    3234          10 :   UnRegisterClusterTracks(track20,trackID2);
    3235             :   //
    3236             :   // normalized chi2
    3237             :   Float_t chi21 =0,chi22=0,ncl1=0,ncl2=0;
    3238          10 :   Float_t nerry[6]={0},nerrz[6]={0};
    3239          10 :   Float_t *erry1=GetErrY(trackID1),*errz1 = GetErrZ(trackID1);
    3240          10 :   Float_t *erry2=GetErrY(trackID2),*errz2 = GetErrZ(trackID2);
    3241         140 :   for (Int_t i=0;i<6;i++){
    3242         102 :      if ( (erry1[i]>0) && (erry2[i]>0)) {
    3243          42 :        nerry[i] = TMath::Min(erry1[i],erry2[i]);
    3244          42 :        nerrz[i] = TMath::Min(errz1[i],errz2[i]);
    3245          42 :      }else{
    3246          18 :        nerry[i] = TMath::Max(erry1[i],erry2[i]);
    3247          18 :        nerrz[i] = TMath::Max(errz1[i],errz2[i]);
    3248             :      }
    3249          60 :      if (TMath::Abs(track10->GetDy(i))>0.000000000000001){
    3250          42 :        chi21 += track10->GetDy(i)*track10->GetDy(i)/(nerry[i]*nerry[i]);
    3251          42 :        chi21 += track10->GetDz(i)*track10->GetDz(i)/(nerrz[i]*nerrz[i]);
    3252          42 :        ncl1++;
    3253          42 :      }
    3254          60 :      if (TMath::Abs(track20->GetDy(i))>0.000000000000001){
    3255          40 :        chi22 += track20->GetDy(i)*track20->GetDy(i)/(nerry[i]*nerry[i]);
    3256          40 :        chi22 += track20->GetDz(i)*track20->GetDz(i)/(nerrz[i]*nerrz[i]);
    3257          40 :        ncl2++;
    3258          40 :      }
    3259             :   }
    3260          10 :   chi21/=ncl1;
    3261          10 :   chi22/=ncl2;
    3262             :   //
    3263             :   // 
    3264          10 :   Float_t d1 = TMath::Sqrt(track10->GetD(0)*track10->GetD(0)+track10->GetD(1)*track10->GetD(1))+0.1;
    3265          10 :   Float_t d2 = TMath::Sqrt(track20->GetD(0)*track20->GetD(0)+track20->GetD(1)*track20->GetD(1))+0.1;
    3266          10 :   Float_t s1 = TMath::Sqrt(track10->GetSigmaY2()*track10->GetSigmaZ2());
    3267          10 :   Float_t s2 = TMath::Sqrt(track20->GetSigmaY2()*track20->GetSigmaZ2());
    3268             :   //
    3269          20 :   w1 = (d2/(d1+d2)+ 2*s2/(s1+s2)+
    3270          10 :         +s2/(s1+s2)*0.5*(chi22+2.)/(chi21+chi22+4.)
    3271          10 :         +1.*track10->Pt()/(track10->Pt()+track20->Pt())
    3272             :         );
    3273          20 :   w2 = (d1/(d1+d2)+ 2*s1/(s1+s2)+
    3274          10 :         s1/(s1+s2)*0.5*(chi21+2.)/(chi21+chi22+4.)
    3275          10 :         +1.*track20->Pt()/(track10->Pt()+track20->Pt())
    3276             :         );
    3277             : 
    3278          10 :   Double_t sumw = w1+w2;
    3279          10 :   w1/=sumw;
    3280          10 :   w2/=sumw;
    3281          10 :   if (w1<w2*0.5) {
    3282           4 :     w1 = (d2+0.5)/(d1+d2+1.);
    3283           4 :     w2 = (d1+0.5)/(d1+d2+1.);
    3284           4 :   }
    3285             :   //  Float_t maxmax       = w1*track10->fChi2MIP[0]+w2*track20->fChi2MIP[0]+w1*conflict1+w2*conflict2+1.;
    3286             :   //Float_t maxconflicts0 = w1*conflict1+w2*conflict2;
    3287             :   //
    3288             :   // get pair of "best" hypothesys
    3289             :   //  
    3290          10 :   Float_t * ny1 = GetNy(trackID1), * nz1 = GetNz(trackID1); 
    3291          10 :   Float_t * ny2 = GetNy(trackID2), * nz2 = GetNz(trackID2); 
    3292             : 
    3293          84 :   for (Int_t itrack1=0;itrack1<entries1;itrack1++){
    3294          32 :     AliITStrackMI * track1=(AliITStrackMI*) arr1->UncheckedAt(itrack1);
    3295             :     //if (track1->fFakeRatio>0) continue;
    3296          32 :     RegisterClusterTracks(track1,trackID1);
    3297         164 :     for (Int_t itrack2=0;itrack2<entries2;itrack2++){
    3298          50 :       AliITStrackMI * track2=(AliITStrackMI*) arr2->UncheckedAt(itrack2);
    3299             : 
    3300             :       //      Float_t current = w1*track1->fChi2MIP[0]+w2*track2->fChi2MIP[0];
    3301             :       //if (track2->fFakeRatio>0) continue;
    3302             :       Float_t nskipped=0;            
    3303          50 :       RegisterClusterTracks(track2,trackID2);
    3304          50 :       Float_t cconflict1 = GetNumberOfSharedClusters(track1,trackID1,list1,clist1);
    3305          50 :       Float_t cconflict2 = GetNumberOfSharedClusters(track2,trackID2,list2,clist2);
    3306          50 :       UnRegisterClusterTracks(track2,trackID2);
    3307             :       //
    3308          66 :       if (track1->GetConstrain()) nskipped+=w1*track1->GetNSkipped();
    3309          82 :       if (track2->GetConstrain()) nskipped+=w2*track2->GetNSkipped();
    3310          66 :       if (nskipped>0.5) continue;
    3311             :       //
    3312             :       //if ( w1*conflict1+w2*conflict2>maxconflicts0) continue;
    3313          34 :       if (conflict1+1<cconflict1) continue;
    3314          34 :       if (conflict2+1<cconflict2) continue;
    3315             :       Float_t conflict=0;
    3316             :       Float_t sumchi2=0;
    3317             :       Float_t sum=0;
    3318         476 :       for (Int_t i=0;i<6;i++){
    3319             :         //
    3320             :         Float_t c1 =0.; // conflict coeficients
    3321             :         Float_t c2 =0.; 
    3322         234 :         if (clist1[i]&&clist2[i]){
    3323             :           Float_t deltan = 0;
    3324          30 :           if (i<2 || i>3){      
    3325           0 :             deltan = (clist1[i]->GetNy()+clist1[i]->GetNz()-TMath::Max(ny1[i],ny2[i])-TMath::Max(nz1[i],nz2[i]));
    3326           0 :           }
    3327             :           else{
    3328          30 :             deltan = (clist1[i]->GetNz()-TMath::Max(nz1[i],nz2[i]));
    3329             :           }
    3330          30 :           c1  = 2./TMath::Max(3.+deltan,2.);      
    3331          30 :           c2  = 2./TMath::Max(3.+deltan,2.);      
    3332          30 :         }
    3333             :         else{
    3334         174 :           if (clist1[i]){
    3335             :             Float_t deltan = 0;
    3336           0 :             if (i<2 || i>3){      
    3337           0 :               deltan = (clist1[i]->GetNy()+clist1[i]->GetNz()-ny1[i]-nz1[i]);
    3338           0 :             }
    3339             :             else{
    3340           0 :               deltan = (clist1[i]->GetNz()-nz1[i]);
    3341             :             }
    3342           0 :             c1  = 2./TMath::Max(3.+deltan,2.);    
    3343             :             c2  = 0;
    3344           0 :           }
    3345             : 
    3346         174 :           if (clist2[i]){
    3347             :             Float_t deltan = 0;
    3348           0 :             if (i<2 || i>3){      
    3349           0 :               deltan = (clist2[i]->GetNy()+clist2[i]->GetNz()-ny2[i]-nz2[i]);
    3350           0 :             }
    3351             :             else{
    3352           0 :               deltan = (clist2[i]->GetNz()-nz2[i]);
    3353             :             }
    3354           0 :             c2  = 2./TMath::Max(3.+deltan,2.);    
    3355             :             c1  = 0;
    3356           0 :           }       
    3357             :         }
    3358             :         //
    3359             :         chi21=0;chi22=0;
    3360         204 :         if (TMath::Abs(track1->GetDy(i))>0.) {
    3361         296 :           chi21 = (track1->GetDy(i)/track1->GetSigmaY(i))*(track1->GetDy(i)/track1->GetSigmaY(i))+
    3362         148 :             (track1->GetDz(i)/track1->GetSigmaZ(i))*(track1->GetDz(i)/track1->GetSigmaZ(i));
    3363             :           //chi21 = (track1->fDy[i]*track1->fDy[i])/(nerry[i]*nerry[i])+
    3364             :           //  (track1->GetDz(i)*track1->GetDz(i))/(nerrz[i]*nerrz[i]);
    3365         148 :         }else{
    3366          56 :           if (TMath::Abs(track1->GetSigmaY(i)>0.)) c1=1;
    3367             :         }
    3368             :         //
    3369         204 :         if (TMath::Abs(track2->GetDy(i))>0.) {
    3370         272 :           chi22 = (track2->GetDy(i)/track2->GetSigmaY(i))*(track2->GetDy(i)/track2->GetSigmaY(i))+
    3371         136 :             (track2->GetDz(i)/track2->GetSigmaZ(i))*(track2->GetDz(i)/track2->GetSigmaZ(i));
    3372             :           //chi22 = (track2->fDy[i]*track2->fDy[i])/(nerry[i]*nerry[i])+
    3373             :           //  (track2->fDz[i]*track2->fDz[i])/(nerrz[i]*nerrz[i]);
    3374         136 :         }
    3375             :         else{
    3376          86 :           if (TMath::Abs(track2->GetSigmaY(i)>0.)) c2=1;
    3377             :         }
    3378         204 :         sumchi2+=w1*(1.+c1)*(1+c1)*(chi21+c1)+w2*(1.+c2)*(1+c2)*(chi22+c2);
    3379         352 :         if (chi21>0) sum+=w1;
    3380         340 :         if (chi22>0) sum+=w2;
    3381         204 :         conflict+=(c1+c2);
    3382             :       }
    3383          34 :       Double_t norm = sum-w1*track1->GetNSkipped()-w2*track2->GetNSkipped();
    3384          34 :       if (norm<0) norm =1/(w1*track1->GetNSkipped()+w2*track2->GetNSkipped());
    3385          34 :       Double_t normchi2 = 2*conflict+sumchi2/sum;
    3386          34 :       if ( normchi2 <maxchi2 ){        
    3387             :         index1 = itrack1;
    3388             :         index2 = itrack2;
    3389             :         maxconflicts = conflict;
    3390             :         maxchi2 = normchi2;
    3391          20 :       }      
    3392          34 :     }
    3393          32 :     UnRegisterClusterTracks(track1,trackID1);
    3394             :   }
    3395             :   //
    3396             :   //  if (maxconflicts<4 && maxchi2<th0){   
    3397          10 :   if (maxchi2<th0*2.){   
    3398          10 :     Float_t orig = track10->GetFakeRatio()*track10->GetNumberOfClusters();
    3399          10 :     AliITStrackMI* track1=(AliITStrackMI*) arr1->UncheckedAt(index1);
    3400          10 :     track1->SetChi2MIP(5,maxconflicts);
    3401          10 :     track1->SetChi2MIP(6,maxchi2);
    3402          10 :     track1->SetChi2MIP(7,0.01+orig-(track1->GetFakeRatio()*track1->GetNumberOfClusters()));
    3403             :     //    track1->UpdateESDtrack(AliESDtrack::kITSin);
    3404          10 :     track1->SetChi2MIP(8,index1);
    3405          10 :     fBestTrackIndex[trackID1] =index1;
    3406          10 :     UpdateESDtrack(track1, AliESDtrack::kITSin);
    3407          10 :     original->SetWinner(track1);
    3408          10 :   }  
    3409           0 :   else if (track10->GetChi2MIP(0)<th1){
    3410           0 :     track10->SetChi2MIP(5,maxconflicts);
    3411           0 :     track10->SetChi2MIP(6,maxchi2);    
    3412             :     //    track10->UpdateESDtrack(AliESDtrack::kITSin);
    3413           0 :     UpdateESDtrack(track10,AliESDtrack::kITSin);
    3414           0 :     original->SetWinner(track10);
    3415           0 :   }   
    3416             :   
    3417          84 :   for (Int_t itrack=0;itrack<entries1;itrack++){
    3418          32 :     AliITStrackMI * track=(AliITStrackMI*) arr1->UncheckedAt(itrack);
    3419          32 :     UnRegisterClusterTracks(track,trackID1);
    3420             :   }
    3421             :   //
    3422          52 :   for (Int_t itrack=0;itrack<entries2;itrack++){
    3423          16 :     AliITStrackMI * track=(AliITStrackMI*) arr2->UncheckedAt(itrack);
    3424          16 :     UnRegisterClusterTracks(track,trackID2);
    3425             :   }
    3426             : 
    3427          28 :   if (track10->GetConstrain()&&track10->GetChi2MIP(0)<AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(0)&&track10->GetChi2MIP(1)<AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(1)
    3428          18 :       &&track10->GetChi2MIP(2)<AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(2)&&track10->GetChi2MIP(3)<AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(3)){ 
    3429             :     //  if (track10->fChi2MIP[0]<AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(0)&&track10->fChi2MIP[1]<AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(1)
    3430             :   //    &&track10->fChi2MIP[2]<AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(2)&&track10->fChi2MIP[3]<AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(3)){ 
    3431           0 :     RegisterClusterTracks(track10,trackID1);
    3432           0 :   }
    3433          40 :   if (track20->GetConstrain()&&track20->GetChi2MIP(0)<AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(0)&&track20->GetChi2MIP(1)<AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(1)
    3434          30 :       &&track20->GetChi2MIP(2)<AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(2)&&track20->GetChi2MIP(3)<AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(3)){ 
    3435             :     //if (track20->fChi2MIP[0]<AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(0)&&track20->fChi2MIP[1]<AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(1)
    3436             :     //  &&track20->fChi2MIP[2]<AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(2)&&track20->fChi2MIP[3]<AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(3)){ 
    3437          10 :     RegisterClusterTracks(track20,trackID2);  
    3438          10 :   }
    3439             :   return track10; 
    3440             :  
    3441          20 : }
    3442             : //------------------------------------------------------------------------
    3443             : void AliITStrackerMI::UseClusters(const AliKalmanTrack *t, Int_t from) const {
    3444             :   //--------------------------------------------------------------------
    3445             :   // This function marks clusters assigned to the track
    3446             :   //--------------------------------------------------------------------
    3447           0 :   AliTracker::UseClusters(t,from);
    3448             : 
    3449           0 :   AliITSRecPoint *c=(AliITSRecPoint *)GetCluster(t->GetClusterIndex(0));
    3450             :   //if (c->GetQ()>2) c->Use();
    3451           0 :   if (c->GetSigmaZ2()>0.1) c->Use();
    3452           0 :   c=(AliITSRecPoint *)GetCluster(t->GetClusterIndex(1));
    3453             :   //if (c->GetQ()>2) c->Use();
    3454           0 :   if (c->GetSigmaZ2()>0.1) c->Use();
    3455             : 
    3456           0 : }
    3457             : //------------------------------------------------------------------------
    3458             : void AliITStrackerMI::AddTrackHypothesys(AliITStrackMI * track, Int_t esdindex)
    3459             : {
    3460             :   //------------------------------------------------------------------
    3461             :   // add track to the list of hypothesys
    3462             :   //------------------------------------------------------------------
    3463             : 
    3464             :   //
    3465        1900 :   TObjArray * array = (TObjArray*) fTrackHypothesys.At(esdindex);
    3466         950 :   if (!array) {
    3467          82 :     array = new TObjArray(10);
    3468          82 :     fTrackHypothesys.AddAtAndExpand(array,esdindex);
    3469          82 :   }
    3470         950 :   array->AddLast(track);
    3471         950 : }
    3472             : //------------------------------------------------------------------------
    3473             : void AliITStrackerMI::SortTrackHypothesys(Int_t esdindex, Int_t maxcut, Int_t mode)
    3474             : {
    3475             :   //-------------------------------------------------------------------
    3476             :   // compress array of track hypothesys
    3477             :   // keep only maxsize best hypothesys
    3478             :   //-------------------------------------------------------------------
    3479         728 :   if (esdindex>fTrackHypothesys.GetEntriesFast()) return;
    3480         362 :   if (! (fTrackHypothesys.At(esdindex)) ) return;
    3481         316 :   TObjArray * array = (TObjArray*) fTrackHypothesys.At(esdindex);
    3482         316 :   Int_t entries = array->GetEntriesFast();
    3483             :   //
    3484             :   //- find preliminary besttrack as a reference
    3485             :   Float_t minchi2=10000;
    3486             :   Int_t maxn=0;
    3487             :   AliITStrackMI * besttrack=0;
    3488             :   //
    3489        4164 :   for (Int_t itrack=0;itrack<array->GetEntriesFast();itrack++){
    3490        1766 :     AliITStrackMI * track = (AliITStrackMI*)array->At(itrack);
    3491        1766 :     if (!track) continue;
    3492        1766 :     Float_t chi2 = NormalizedChi2(track,0);
    3493             :     //
    3494        1766 :     Int_t tpcLabel=track->GetESDtrack()->GetTPCLabel();
    3495        1766 :     track->SetLabel(tpcLabel);
    3496        1766 :     CookdEdx(track);
    3497        1766 :     track->SetFakeRatio(1.);
    3498        1766 :     CookLabel(track,0.); //For comparison only
    3499             :     //
    3500             :     //if (chi2<AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(0)&&track->fFakeRatio==0){
    3501        1766 :     if (chi2<AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(0)){
    3502        2824 :       if (track->GetNumberOfClusters()<maxn) continue;
    3503         704 :       maxn = track->GetNumberOfClusters();
    3504             :       //      if (fSelectBestMIP03 && track->GetChi2MIP(3)>0) chi2 *= track->GetChi2MIP(3); // RS    
    3505         704 :       if (chi2<minchi2){
    3506             :         minchi2=chi2;
    3507             :         besttrack=track;
    3508         392 :       }
    3509             :     }
    3510             :     else{
    3511           2 :       if (track->GetConstrain() || track->GetNumberOfClusters()>5){  //keep best short tracks - without vertex constrain
    3512           4 :         delete array->RemoveAt(itrack);
    3513             :       }  
    3514             :     }
    3515         706 :   }
    3516         316 :   if (!besttrack) return;
    3517             :   //
    3518             :   //
    3519             :   //take errors of best track as a reference
    3520         316 :   Float_t *erry = GetErrY(esdindex), *errz = GetErrZ(esdindex);
    3521         316 :   Float_t *ny = GetNy(esdindex), *nz = GetNz(esdindex);
    3522        4424 :   for (Int_t j=0;j<6;j++) {
    3523        1896 :     if (besttrack->GetClIndex(j)>=0){
    3524        1660 :       erry[j] = besttrack->GetSigmaY(j); erry[j+6] = besttrack->GetSigmaY(j+6);
    3525        1660 :       errz[j] = besttrack->GetSigmaZ(j); errz[j+6] = besttrack->GetSigmaZ(j+6);
    3526        1660 :       ny[j]   = besttrack->GetNy(j);
    3527        1660 :       nz[j]   = besttrack->GetNz(j);
    3528        1660 :     }
    3529             :   }
    3530             :   //
    3531             :   // calculate normalized chi2
    3532             :   //
    3533         316 :   Float_t * chi2        = new Float_t[entries];
    3534         316 :   Int_t * index         = new Int_t[entries];  
    3535        4164 :   for (Int_t i=0;i<entries;i++) chi2[i] =10000;
    3536        4164 :   for (Int_t itrack=0;itrack<entries;itrack++){
    3537        1766 :     AliITStrackMI * track = (AliITStrackMI*)array->At(itrack);
    3538        1766 :     if (track){
    3539        5292 :       AliDebug(2,Form("track %d  ncls %d\n",itrack,track->GetNumberOfClusters()));      
    3540        1764 :       double chi2t = GetNormalizedChi2(track, mode);
    3541        1764 :       track->SetChi2MIP(0,chi2t);
    3542        1764 :       if (chi2t<AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(0)) {
    3543        1616 :         if (fSelectBestMIP03 && track->GetChi2MIP(3)>0) chi2t *= track->GetChi2MIP(3); // RS
    3544        1616 :         chi2[itrack] = chi2t;
    3545        1616 :       }
    3546             :       else{
    3547         154 :         if (track->GetConstrain() || track->GetNumberOfClusters()>5){  //keep best short tracks - without vertex constrain
    3548         284 :           delete array->RemoveAt(itrack);         
    3549             :         }
    3550             :       }
    3551        1764 :     }
    3552             :   }
    3553             :   //
    3554         316 :   TMath::Sort(entries,chi2,index,kFALSE);
    3555         316 :   besttrack = (AliITStrackMI*)array->At(index[0]);
    3556        1264 :   if(besttrack) AliDebug(2,Form("ncls best track %d\n",besttrack->GetNumberOfClusters()));
    3557         632 :   if (besttrack&&besttrack->GetChi2MIP(0)<AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(0)){
    3558        4424 :     for (Int_t j=0;j<6;j++){
    3559        1896 :       if (besttrack->GetClIndex(j)>=0){
    3560        1664 :         erry[j] = besttrack->GetSigmaY(j); erry[j+6] = besttrack->GetSigmaY(j+6);
    3561        1664 :         errz[j] = besttrack->GetSigmaZ(j); erry[j+6] = besttrack->GetSigmaY(j+6);
    3562        1664 :         ny[j]   = besttrack->GetNy(j);
    3563        1664 :         nz[j]   = besttrack->GetNz(j);
    3564        1664 :       }
    3565             :     }
    3566         316 :   }
    3567             :   //
    3568             :   // calculate one more time with updated normalized errors
    3569        4164 :   for (Int_t i=0;i<entries;i++) chi2[i] =10000;  
    3570        4164 :   for (Int_t itrack=0;itrack<entries;itrack++){
    3571        1766 :     AliITStrackMI * track = (AliITStrackMI*)array->At(itrack);
    3572        1766 :     if (track){      
    3573        1622 :       double chi2t = GetNormalizedChi2(track, mode);
    3574        1622 :       track->SetChi2MIP(0,chi2t);
    3575        4866 :       AliDebug(2,Form("track %d  ncls %d\n",itrack,track->GetNumberOfClusters()));            
    3576        1622 :       if (track->GetChi2MIP(0)<AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(0)) {
    3577        1610 :         if (fSelectBestMIP03 && track->GetChi2MIP(3)>0) chi2t *= track->GetChi2MIP(3); // RS
    3578        1610 :         chi2[itrack] = chi2t;  //-0*(track->GetNumberOfClusters()+track->GetNDeadZone()); 
    3579        1610 :       }
    3580             :       else {
    3581          18 :         if (track->GetConstrain() || track->GetNumberOfClusters()>5){  //keep best short tracks - without vertex constrain
    3582          12 :           delete array->RemoveAt(itrack);    
    3583             :         }
    3584             :       }
    3585        1622 :     }   
    3586             :   }
    3587         316 :   entries = array->GetEntriesFast();  
    3588             :   //
    3589             :   //
    3590         316 :   if (entries>0){
    3591         316 :     TObjArray * newarray = new TObjArray();  
    3592         316 :     TMath::Sort(entries,chi2,index,kFALSE);
    3593         316 :     besttrack = (AliITStrackMI*)array->At(index[0]);
    3594         316 :     if (besttrack){
    3595         948 :       AliDebug(2,Form("ncls best track %d     %f   %f\n",besttrack->GetNumberOfClusters(),besttrack->GetChi2MIP(0),chi2[index[0]]));
    3596             :       //
    3597        4424 :       for (Int_t j=0;j<6;j++){
    3598        3562 :         if (besttrack->GetNz(j)>0&&besttrack->GetNy(j)>0){
    3599        1666 :           erry[j] = besttrack->GetSigmaY(j); erry[j+6] = besttrack->GetSigmaY(j+6);
    3600        1666 :           errz[j] = besttrack->GetSigmaZ(j); errz[j+6] = besttrack->GetSigmaZ(j+6);
    3601        1666 :           ny[j]   = besttrack->GetNy(j);
    3602        1666 :           nz[j]   = besttrack->GetNz(j);
    3603        1666 :         }
    3604             :       }
    3605         316 :       besttrack->SetChi2MIP(0,GetNormalizedChi2(besttrack,mode));
    3606         316 :       minchi2 = TMath::Min(besttrack->GetChi2MIP(0)+5.+besttrack->GetNUsed(), double(AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(0)));
    3607         316 :       Float_t minn = besttrack->GetNumberOfClusters()-3;
    3608             :       Int_t accepted=0;
    3609        4444 :       for (Int_t i=0;i<entries;i++){
    3610        1748 :         AliITStrackMI * track = (AliITStrackMI*)array->At(index[i]); 
    3611        1880 :         if (!track) continue;
    3612        1616 :         if (accepted>maxcut) break;
    3613        1616 :         track->SetChi2MIP(0,GetNormalizedChi2(track,mode));
    3614        2224 :         if (track->GetConstrain() || track->GetNumberOfClusters()>5){  //keep best short tracks - without vertex constrain
    3615        1928 :           if (track->GetNumberOfClusters()<6 && (track->GetChi2MIP(0)+track->GetNUsed()>minchi2)){
    3616         220 :             delete array->RemoveAt(index[i]);
    3617         110 :             continue;
    3618             :           }
    3619             :         }
    3620        3620 :         Bool_t shortbest = !track->GetConstrain() && track->GetNumberOfClusters()<6;
    3621        3012 :         if ((track->GetChi2MIP(0)+track->GetNUsed()<minchi2 && track->GetNumberOfClusters()>=minn) ||shortbest){
    3622        2492 :           if (!shortbest) accepted++;
    3623             :           //
    3624        1506 :           newarray->AddLast(array->RemoveAt(index[i]));      
    3625       21084 :           for (Int_t j=0;j<6;j++){
    3626        9036 :             if (nz[j]==0){
    3627           0 :               erry[j] = track->GetSigmaY(j); erry[j+6] = track->GetSigmaY(j+6);
    3628           0 :               errz[j] = track->GetSigmaZ(j); errz[j]   = track->GetSigmaZ(j+6);
    3629           0 :               ny[j]   = track->GetNy(j);
    3630           0 :               nz[j]   = track->GetNz(j);
    3631           0 :             }
    3632             :           }
    3633        1506 :         }
    3634             :         else{
    3635           0 :           delete array->RemoveAt(index[i]);
    3636             :         }
    3637        1506 :       }
    3638         316 :       array->Delete();
    3639         632 :       delete fTrackHypothesys.RemoveAt(esdindex);
    3640         316 :       fTrackHypothesys.AddAt(newarray,esdindex);
    3641         316 :     }
    3642             :     else{
    3643           0 :       array->Delete();
    3644           0 :       delete fTrackHypothesys.RemoveAt(esdindex);
    3645             :     }
    3646         316 :   }
    3647         632 :   delete [] chi2;
    3648         632 :   delete [] index;
    3649         680 : }
    3650             : //------------------------------------------------------------------------
    3651             : AliITStrackMI * AliITStrackerMI::GetBestHypothesys(Int_t esdindex, AliITStrackMI * original, Int_t checkmax)
    3652             : {
    3653             :   //-------------------------------------------------------------
    3654             :   // try to find best hypothesy
    3655             :   // currently - minimal chi2 of track+backpropagated track+matching to the tpc track
    3656             :   // RS: optionally changing this to product of Chi2MIP(0)*Chi2MIP(3) == (chi2*chi2_interpolated)
    3657             :   //-------------------------------------------------------------
    3658         442 :   if (fTrackHypothesys.GetEntriesFast()<=esdindex) return 0;
    3659         176 :   TObjArray * array = (TObjArray*) fTrackHypothesys.At(esdindex);
    3660         194 :   if (!array) return 0;
    3661         158 :   Int_t entries = array->GetEntriesFast();
    3662         158 :   if (!entries) return 0;  
    3663             :   Float_t minchi2 = 100000;
    3664             :   AliITStrackMI * besttrack=0;
    3665             :   //
    3666         158 :   AliITStrackMI * backtrack    = new AliITStrackMI(*original);
    3667         158 :   AliITStrackMI * forwardtrack = new AliITStrackMI(*original);
    3668         158 :   Double_t xyzVtx[]={GetX(),GetY(),GetZ()};     
    3669         158 :   Double_t ersVtx[]={GetSigmaX()/3.,GetSigmaY()/3.,GetSigmaZ()/3.};
    3670             :   //
    3671        2056 :   for (Int_t i=0;i<entries;i++){    
    3672         870 :     AliITStrackMI * track = (AliITStrackMI*)array->At(i);    
    3673         870 :     if (!track) continue;
    3674         870 :     Float_t sigmarfi,sigmaz;
    3675         870 :     GetDCASigma(track,sigmarfi,sigmaz);
    3676         870 :     track->SetDnorm(0,sigmarfi);
    3677         870 :     track->SetDnorm(1,sigmaz);
    3678             :     //
    3679         870 :     track->SetChi2MIP(1,1000000);
    3680         870 :     track->SetChi2MIP(2,1000000);
    3681         870 :     track->SetChi2MIP(3,1000000);
    3682             :     //
    3683             :     // backtrack
    3684         870 :     backtrack = new(backtrack) AliITStrackMI(*track); 
    3685         870 :     if (track->GetConstrain()) {
    3686        1132 :       if (!CorrectForPipeMaterial(backtrack,"inward")) continue;
    3687         566 :       if (AliITSReconstructor::GetRecoParam()->GetImproveWithVertex()) {
    3688           0 :         if (fUseImproveKalman) {if (!backtrack->ImproveKalman(xyzVtx,ersVtx,0,0,0)) continue;}
    3689           0 :         else                   {if (!backtrack->Improve(0,xyzVtx,ersVtx)) continue;}
    3690             :       }
    3691         566 :       backtrack->ResetCovariance(10.);      
    3692         566 :     }else{
    3693         304 :       backtrack->ResetCovariance(10.);
    3694             :     }
    3695         870 :     backtrack->ResetClusters();
    3696             : 
    3697         870 :     Double_t x = original->GetX();
    3698         870 :     if (!RefitAt(x,backtrack,track)) continue;
    3699             :     //
    3700         870 :     track->SetChi2MIP(1,NormalizedChi2(backtrack,0));
    3701             :     //for (Int_t i=2;i<6;i++){track->fDy[i]+=backtrack->fDy[i]; track->fDz[i]+=backtrack->fDz[i];}
    3702         870 :     if (track->GetChi2MIP(1)>AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(1)*6.)  continue;
    3703         870 :     track->SetChi22(GetMatchingChi2(backtrack,original));
    3704             : 
    3705        1436 :     if ((track->GetConstrain()) && track->GetChi22()>90.)  continue;
    3706        1176 :     if ((!track->GetConstrain()) && track->GetChi22()>30.)  continue;
    3707         868 :     if ( track->GetChi22()/track->GetNumberOfClusters()>11.)  continue;
    3708             : 
    3709             : 
    3710        1170 :     if  (!(track->GetConstrain())&&track->GetChi2MIP(1)>AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(1))  continue;
    3711             :     //
    3712             :     //forward track - without constraint
    3713         868 :     forwardtrack = new(forwardtrack) AliITStrackMI(*original);
    3714         868 :     forwardtrack->ResetClusters();
    3715         868 :     x = track->GetX();
    3716         868 :     if (!RefitAt(x,forwardtrack,track) && fSelectBestMIP03) continue;  // w/o fwd track MIP03 is meaningless
    3717         868 :     track->SetChi2MIP(2,NormalizedChi2(forwardtrack,0));    
    3718         868 :     if  (track->GetChi2MIP(2)>AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(2)*6.0)  continue;
    3719        1170 :     if  (!(track->GetConstrain())&&track->GetChi2MIP(2)>AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(2))  continue;
    3720             :     
    3721             :     //track->fD[0] = forwardtrack->GetD(GetX(),GetY());
    3722             :     //track->fD[1] = forwardtrack->GetZat(GetX())-GetZ();
    3723         868 :     forwardtrack->GetDZ(GetX(),GetY(),GetZ(),track->GetDP());   //I.B.
    3724         868 :     forwardtrack->SetD(0,track->GetD(0));
    3725         868 :     forwardtrack->SetD(1,track->GetD(1));    
    3726             :     {
    3727         868 :       Int_t list[6]={0};
    3728         868 :       AliITSRecPoint* clist[6]={0};
    3729         868 :       track->SetChi2MIP(4,GetNumberOfSharedClusters(track,esdindex,list,clist));      
    3730        1170 :       if ( (!track->GetConstrain()) && track->GetChi2MIP(4)>1.0) continue;
    3731        1736 :     }
    3732             :     
    3733         868 :     track->SetChi2MIP(3,GetInterpolatedChi2(forwardtrack,backtrack));
    3734         868 :     if  ( (track->GetChi2MIP(3)>6.*AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(3))) continue;    
    3735        1170 :     if  ( (!track->GetConstrain()) && (track->GetChi2MIP(3)>2*AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(3))) {
    3736           0 :       track->SetChi2MIP(3,1000);
    3737           0 :       continue; 
    3738             :     }
    3739         868 :     Double_t chi2 = track->GetChi2MIP(0); // +track->GetNUsed();    //RS
    3740         868 :     if (fSelectBestMIP03) chi2 *= track->GetChi2MIP(3);
    3741         868 :     else chi2 += track->GetNUsed();
    3742             :     //
    3743       10416 :     for (Int_t ichi=0;ichi<5;ichi++){
    3744        4340 :       forwardtrack->SetChi2MIP(ichi, track->GetChi2MIP(ichi));
    3745             :     }
    3746         868 :     if (chi2 < minchi2){
    3747             :       //besttrack = new AliITStrackMI(*forwardtrack);
    3748             :       besttrack = track;
    3749         158 :       besttrack->SetLabel(track->GetLabel());
    3750         158 :       besttrack->SetFakeRatio(track->GetFakeRatio());
    3751         158 :       minchi2   = chi2;
    3752             :       //original->fD[0] = forwardtrack->GetD(GetX(),GetY());
    3753             :       //original->fD[1] = forwardtrack->GetZat(GetX())-GetZ();
    3754         158 :       forwardtrack->GetDZ(GetX(),GetY(),GetZ(),original->GetDP());    //I.B.
    3755         158 :     }    
    3756        1738 :   }
    3757         316 :   delete backtrack;
    3758         316 :   delete forwardtrack;
    3759             : 
    3760         158 :   if (!besttrack)  return 0;
    3761             : 
    3762             :   Int_t accepted=0;
    3763        2056 :   for (Int_t i=0;i<entries;i++){    
    3764         870 :     AliITStrackMI * track = (AliITStrackMI*)array->At(i);
    3765             :    
    3766         870 :     if (!track) continue;
    3767             :     
    3768        2560 :     if (accepted>checkmax || track->GetChi2MIP(3)>AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(3)*6. || 
    3769         868 :         (track->GetNumberOfClusters()<besttrack->GetNumberOfClusters()-1.)
    3770             :         // RS: don't apply this cut when fSelectBestMIP03 is on
    3771        2508 :         || (!fSelectBestMIP03 && (track->GetChi2MIP(0)>besttrack->GetChi2MIP(0)+2.*besttrack->GetNUsed()+3.))
    3772             :         ){
    3773         530 :       if (track->GetConstrain() || track->GetNumberOfClusters()>5){  //keep best short tracks - without vertex constrain
    3774         468 :         delete array->RemoveAt(i);    
    3775         234 :         continue;
    3776             :       }
    3777             :     }
    3778             :     else{
    3779         488 :       accepted++;
    3780             :     }
    3781         636 :   }
    3782             :   //
    3783         158 :   array->Compress();
    3784         158 :   SortTrackHypothesys(esdindex,checkmax,1);
    3785             : 
    3786         158 :   array = (TObjArray*) fTrackHypothesys.At(esdindex);
    3787         158 :   if (!array) return 0; // PH What can be the reason? Check SortTrackHypothesys
    3788         158 :   besttrack = (AliITStrackMI*)array->At(0);  
    3789         158 :   if (!besttrack)  return 0;
    3790         158 :   besttrack->SetChi2MIP(8,0);
    3791         158 :   fBestTrackIndex[esdindex]=0;
    3792         158 :   entries = array->GetEntriesFast();
    3793             :   AliITStrackMI *longtrack =0;
    3794             :   minchi2 =1000;
    3795         158 :   Float_t minn=besttrack->GetNumberOfClusters()+besttrack->GetNDeadZone();
    3796        1272 :   for (Int_t itrack=entries-1;itrack>0;itrack--) {
    3797         478 :     AliITStrackMI * track = (AliITStrackMI*)array->At(itrack);
    3798         776 :     if (!track->GetConstrain()) continue;
    3799         304 :     if (track->GetNumberOfClusters()+track->GetNDeadZone()<minn) continue;
    3800         112 :     if (track->GetChi2MIP(0)-besttrack->GetChi2MIP(0)>0.0) continue;
    3801           0 :     if (track->GetChi2MIP(0)>4.) continue;
    3802           0 :     minn = track->GetNumberOfClusters()+track->GetNDeadZone();
    3803             :     longtrack =track;
    3804           0 :   }
    3805             :   //if (longtrack) besttrack=longtrack;
    3806             :   //
    3807             :   // RS do shared cluster analysis here only if the new sharing analysis is not requested
    3808             :   //RRR if (fFlagFakes) return besttrack;
    3809             : 
    3810         158 :   Int_t list[6]={0};
    3811         158 :   AliITSRecPoint * clist[6]={0};
    3812         158 :   Float_t shared = GetNumberOfSharedClusters(besttrack,esdindex,list,clist);
    3813         614 :   if (besttrack->GetConstrain()&&besttrack->GetChi2MIP(0)<AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(0)&&besttrack->GetChi2MIP(1)<AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(1)
    3814         456 :       &&besttrack->GetChi2MIP(2)<AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(2)&&besttrack->GetChi2MIP(3)<AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(3)){ 
    3815         144 :     RegisterClusterTracks(besttrack,esdindex);
    3816         144 :   }
    3817             :   //
    3818             :   //
    3819         158 :   if (shared>0.0){
    3820           4 :     Int_t nshared;
    3821           4 :     Int_t overlist[6]={0};
    3822           4 :     Int_t sharedtrack = GetOverlapTrack(besttrack, esdindex, nshared, list, overlist);
    3823           4 :     if (sharedtrack>=0){
    3824             :       //
    3825           4 :       besttrack = GetBest2Tracks(esdindex,sharedtrack,10,5.5,original);     
    3826           4 :       if (besttrack){
    3827           4 :         shared = GetNumberOfSharedClusters(besttrack,esdindex,list,clist);
    3828             :       }
    3829           0 :       else return 0;
    3830           4 :     }
    3831           8 :   }  
    3832             :   
    3833         158 :   if (shared>2.5) return 0;
    3834         158 :   if (shared>1.0) return besttrack;
    3835             :   //
    3836             :   // Don't sign clusters if not gold track
    3837             :   //
    3838         316 :   if (!besttrack->IsGoldPrimary()) return besttrack;
    3839           0 :   if (besttrack->GetESDtrack()->GetKinkIndex(0)!=0) return besttrack;   //track belong to kink
    3840             :   //
    3841           0 :   if (fConstraint[fPass]){
    3842             :     //
    3843             :     // sign clusters
    3844             :     //
    3845           0 :     Float_t *ny = GetNy(esdindex), *nz = GetNz(esdindex);
    3846           0 :     for (Int_t i=0;i<6;i++){
    3847           0 :       Int_t index = besttrack->GetClIndex(i);
    3848           0 :       if (index<0) continue; 
    3849           0 :       Int_t ilayer =  (index & 0xf0000000) >> 28;
    3850           0 :       if (besttrack->GetSigmaY(ilayer)<0.00000000001) continue;
    3851           0 :       AliITSRecPoint *c = (AliITSRecPoint*)GetCluster(index);     
    3852           0 :       if (!c) continue;
    3853           0 :       if (ilayer>3&&c->GetNy()+c->GetNz()>6) continue;
    3854           0 :       if ( (c->GetNy()+c->GetNz() )> ny[i]+nz[i]+0.7) continue; //shared track
    3855           0 :       if (  c->GetNz()> nz[i]+0.7) continue; //shared track
    3856           0 :       if ( ilayer>2&& AliITSReconstructor::GetRecoParam()->GetUseAmplitudeInfo(ilayer)) 
    3857           0 :         if (besttrack->GetNormQ(ilayer)/besttrack->GetExpQ()>1.5) continue;
    3858             :       //if (  c->GetNy()> ny[i]+0.7) continue; //shared track
    3859             : 
    3860             :       Bool_t cansign = kTRUE;
    3861           0 :       for (Int_t itrack=0;itrack<entries; itrack++){
    3862           0 :         AliITStrackMI * track = (AliITStrackMI*)array->At(i);   
    3863           0 :         if (!track) continue;
    3864           0 :         if (track->GetChi2MIP(0)>besttrack->GetChi2MIP(0)+2.*shared+1.) break;
    3865           0 :         if ( (track->GetClIndex(ilayer)>=0) && (track->GetClIndex(ilayer)!=besttrack->GetClIndex(ilayer))){
    3866             :           cansign = kFALSE;
    3867           0 :           break;
    3868             :         }
    3869           0 :       }
    3870           0 :       if (cansign){
    3871           0 :         if (TMath::Abs(besttrack->GetDy(ilayer)/besttrack->GetSigmaY(ilayer))>3.) continue;
    3872           0 :         if (TMath::Abs(besttrack->GetDz(ilayer)/besttrack->GetSigmaZ(ilayer))>3.) continue;    
    3873           0 :         if (!c->IsUsed()) c->Use();
    3874             :       }
    3875           0 :     }
    3876           0 :   }
    3877           0 :   return besttrack;
    3878         522 : } 
    3879             : //------------------------------------------------------------------------
    3880             : void  AliITStrackerMI::GetBestHypothesysMIP(TObjArray &itsTracks)
    3881             : {
    3882             :   //
    3883             :   // get "best" hypothesys
    3884             :   //
    3885             : 
    3886          32 :   Int_t nentries = itsTracks.GetEntriesFast();
    3887         472 :   for (Int_t i=0;i<nentries;i++){
    3888         220 :     AliITStrackMI* track = (AliITStrackMI*)itsTracks.At(i);
    3889         220 :     if (!track) continue;
    3890         220 :     TObjArray * array = (TObjArray*) fTrackHypothesys.At(i);
    3891         282 :     if (!array) continue;
    3892         158 :     if (array->GetEntriesFast()<=0) continue;
    3893             :     //
    3894             :     AliITStrackMI* longtrack=0;
    3895             :     Float_t minn=0;
    3896             :     Float_t maxchi2=1000;
    3897        1746 :     for (Int_t j=0;j<array->GetEntriesFast();j++){
    3898         636 :       AliITStrackMI* trackHyp = (AliITStrackMI*)array->At(j);
    3899         636 :       if (!trackHyp) continue;
    3900         636 :       if (trackHyp->GetGoldV0()) {
    3901             :         longtrack = trackHyp;   //gold V0 track taken
    3902           0 :         break;
    3903             :       }
    3904         954 :       if (trackHyp->GetNumberOfClusters()+trackHyp->GetNDeadZone()<minn) continue;
    3905         318 :       Float_t chi2 = trackHyp->GetChi2MIP(0);
    3906         318 :       if (fSelectBestMIP03) chi2 *= trackHyp->GetChi2MIP(3);
    3907         478 :       if (trackHyp->GetNumberOfClusters()+trackHyp->GetNDeadZone()>minn) maxchi2 = chi2; //trackHyp->GetChi2MIP(0);
    3908             :       //
    3909         318 :       if (fAfterV0){ // ??? RS
    3910         578 :         if (!trackHyp->GetGoldV0()&&trackHyp->GetConstrain()==kFALSE) chi2+=5;
    3911             :       }
    3912         484 :       if (chi2 > maxchi2) continue;
    3913         152 :       minn = trackHyp->GetNumberOfClusters()+trackHyp->GetNDeadZone();
    3914         152 :       if (fSelectBestMIP03) minn++; // allow next to longest to win
    3915             :       maxchi2 = chi2;
    3916             :       longtrack=trackHyp;
    3917         152 :     }    
    3918             :     //
    3919             :     //
    3920             :     //
    3921         158 :     AliITStrackMI * besttrack = (AliITStrackMI*)array->At(0);
    3922         164 :     if (!longtrack) {longtrack = besttrack;}
    3923             :     else besttrack= longtrack;
    3924             :     //
    3925         158 :     if (besttrack) {
    3926         158 :       Int_t list[6]={0};
    3927         158 :       AliITSRecPoint * clist[6]={0};
    3928         158 :       Float_t shared = GetNumberOfSharedClusters(longtrack,i,list,clist);
    3929             :       //
    3930         158 :       track->SetNUsed(shared);      
    3931         158 :       track->SetNSkipped(besttrack->GetNSkipped());
    3932         158 :       track->SetChi2MIP(0,besttrack->GetChi2MIP(0));
    3933         158 :       if (shared>0) {
    3934           6 :         if(!AliITSReconstructor::GetRecoParam()->GetAllowSharedClusters()) continue;
    3935           6 :         Int_t nshared;
    3936           6 :         Int_t overlist[6]={0}; 
    3937             :         //
    3938           6 :         Int_t sharedtrack = GetOverlapTrack(longtrack, i, nshared, list, overlist);
    3939             :         //if (sharedtrack==-1) sharedtrack=0;
    3940           6 :         if (sharedtrack>=0) {       
    3941           6 :           besttrack = GetBest2Tracks(i,sharedtrack,10,5.5,track);                         
    3942           6 :         }
    3943           6 :       }   
    3944         316 :       if (besttrack&&fAfterV0) {
    3945         122 :         UpdateESDtrack(besttrack,AliESDtrack::kITSin);
    3946         122 :         track->SetWinner(besttrack);
    3947         122 :       }
    3948         158 :       if (besttrack) {
    3949         158 :         if (fConstraint[fPass]) {
    3950          76 :           UpdateESDtrack(besttrack,AliESDtrack::kITSin);
    3951          76 :           track->SetWinner(besttrack);
    3952          76 :         }
    3953         280 :         if (besttrack->GetChi2MIP(0)+besttrack->GetNUsed()>1.5 && fConstraint[fPass]) {
    3954         116 :           if ( TMath::Abs(besttrack->GetD(0))>0.1 || 
    3955          58 :                TMath::Abs(besttrack->GetD(1))>0.1 ) track->SetReconstructed(kFALSE);   
    3956             :         }       
    3957             :       }
    3958         316 :     }
    3959         158 :   }
    3960          16 : } 
    3961             : 
    3962             : //------------------------------------------------------------------------
    3963             : void AliITStrackerMI::FlagFakes(const TObjArray &itsTracks)
    3964             : {
    3965             :   //
    3966             :   // RS: flag those tracks which are suxpected to have fake clusters
    3967             :   //
    3968             :   const double kThreshPt = 0.5;
    3969           0 :   AliRefArray *refArr[6]={0};
    3970             :   //
    3971           0 :   for (int i=0;i<6;i++) {
    3972           0 :     int ncl = fgLayers[i].GetNumberOfClusters();
    3973           0 :     refArr[i] = new AliRefArray(ncl,TMath::Min(ncl,1000));
    3974             :   }
    3975           0 :   Int_t nentries = itsTracks.GetEntriesFast();
    3976             :   //
    3977             :   // fill cluster->track associations
    3978           0 :   for (Int_t itr=0;itr<nentries;itr++){
    3979           0 :     AliITStrackMI* track = (AliITStrackMI*)itsTracks.UncheckedAt(itr);   
    3980           0 :     if (!track) continue;
    3981           0 :     AliITStrackMI* trackITS = track->GetWinner();
    3982           0 :     if (!trackITS) continue;
    3983           0 :     for (int il=trackITS->GetNumberOfClusters();il--;) {
    3984           0 :       int idx = trackITS->GetClusterIndex(il);
    3985           0 :       Int_t l=(idx & 0xf0000000) >> 28, c=(idx & 0x0fffffff) >> 00;
    3986             :       //      if (c>fgLayers[l].GetNumberOfClusters()) continue;
    3987           0 :       refArr[l]->AddReference(c, itr);
    3988             :     }
    3989           0 :   }
    3990             :   //
    3991             :   const UInt_t kMaxRef = 100;
    3992           0 :   UInt_t crefs[kMaxRef]={0};
    3993             :   Int_t ncrefs=0;
    3994             :   // process tracks with shared clusters
    3995           0 :   for (int itr=0;itr<nentries;itr++){
    3996           0 :     AliITStrackMI* track0 = (AliITStrackMI*)itsTracks.UncheckedAt(itr);  
    3997           0 :     AliITStrackMI* trackH0 = track0->GetWinner(); 
    3998           0 :     if (!trackH0) continue;
    3999           0 :     AliESDtrack* esd0 = track0->GetESDtrack();
    4000             :     //
    4001           0 :     for (int il=0;il<trackH0->GetNumberOfClusters();il++) {
    4002           0 :       int idx = trackH0->GetClusterIndex(il);
    4003           0 :       Int_t l=(idx & 0xf0000000) >> 28, c=(idx & 0x0fffffff) >> 00;
    4004           0 :       ncrefs = refArr[l]->GetReferences(c,crefs,kMaxRef);                
    4005           0 :       if (ncrefs<2) continue; // there will be always self-reference, for sharing needs at least 2
    4006           0 :       esd0->SetITSSharedFlag(l); 
    4007           0 :       for (int ir=ncrefs;ir--;) {
    4008           0 :         if (int(crefs[ir]) <= itr) continue; // ==:selfreference, <: the same pair will be checked with >
    4009           0 :         AliITStrackMI* track1 = (AliITStrackMI*)itsTracks.UncheckedAt(crefs[ir]);
    4010           0 :         AliITStrackMI* trackH1 = track1->GetWinner(); 
    4011           0 :         AliESDtrack* esd1 = track1->GetESDtrack();
    4012           0 :         esd1->SetITSSharedFlag(l);
    4013             :         //
    4014           0 :         double pt0 = trackH0->Pt(), pt1 = trackH1->Pt(), res = 0.;        
    4015           0 :         if      (pt0>kThreshPt && pt0-pt1>0.2+0.2*(pt0-kThreshPt) ) res = -100;
    4016           0 :         else if (pt1>kThreshPt && pt1-pt0>0.2+0.2*(pt1-kThreshPt) ) res = 100;
    4017             : 
    4018             :         // select the one with smallest chi2's product
    4019           0 :         res += trackH0->GetChi2MIP(0)*trackH0->GetChi2MIP(3); 
    4020           0 :         res -= trackH1->GetChi2MIP(0)*trackH1->GetChi2MIP(3);
    4021             :         //
    4022           0 :         if (res<0) esd1->SetITSFakeFlag();  // esd0 is winner
    4023           0 :         else       esd0->SetITSFakeFlag();  // esd1 is winner
    4024             :       }
    4025             :       //
    4026           0 :     }
    4027             :     //
    4028           0 :   }
    4029             :   //
    4030           0 :   for (int i=6;i--;) delete refArr[i];
    4031           0 : }
    4032             : 
    4033             : 
    4034             : 
    4035             : //------------------------------------------------------------------------
    4036             : void AliITStrackerMI::CookLabel(AliITStrackMI *track,Float_t wrong) const {
    4037             :   //--------------------------------------------------------------------
    4038             :   //This function "cooks" a track label. If label<0, this track is fake.
    4039             :   //--------------------------------------------------------------------
    4040             :   const int kMaxLbPerCl = 3;
    4041        5064 :   int lbID[36]={0},lbStat[36]={0};
    4042        2532 :   Int_t nLab=0, nCl = track->GetNumberOfClusters();
    4043             :   //
    4044             :   //  track->SetLabel(-1);
    4045             :   //  track->SetFakeRatio(0);
    4046             :   //
    4047       28420 :   for (Int_t i=0;i<nCl;i++) { // fill all labels
    4048       11678 :     Int_t cindex = track->GetClusterIndex(i);
    4049             :     //    Int_t l=(cindex & 0xf0000000) >> 28;
    4050       11678 :     AliITSRecPoint *cl = (AliITSRecPoint*)GetCluster(cindex);
    4051             :     //
    4052       40014 :     for (int imc=0;imc<kMaxLbPerCl;imc++) { // labels within single cluster
    4053       19968 :       int trLb = cl->GetLabel(imc);
    4054       31620 :       if (trLb<0) break;
    4055             :       // search this mc track in already accounted ones
    4056             :       int iLab;
    4057       23201 :       for (iLab=0;iLab<nLab;iLab++) if (lbID[iLab]==trLb) break;
    4058       13985 :       if (iLab<nLab) lbStat[iLab]++;
    4059             :       else {
    4060        2647 :         lbID[nLab] = trLb;
    4061        2647 :         lbStat[nLab++] = 1;
    4062             :       }
    4063        8316 :     } // loop over given cluster's labels   
    4064             :   } // loop over clusters
    4065             :   //
    4066        2579 :   if (nLab<1) return; // no labels at all
    4067             :   //
    4068             :   Int_t tpcLabel=-1; 
    4069        4970 :   if (track->GetESDtrack() && track->GetESDtrack()->IsOn(AliESDtrack::kTPCin)){
    4070        2453 :     tpcLabel = TMath::Abs(track->GetESDtrack()->GetTPCLabel());
    4071        2453 :   }
    4072             :   //
    4073             :   // find majority label
    4074        2485 :   if (nCl && nLab) {
    4075             :     int maxLab=0,tpcLabID=-1;
    4076       10264 :     for (int ilb=nLab;ilb--;) {
    4077        2647 :       int st = lbStat[ilb];
    4078        2651 :       if (lbStat[maxLab]<st) maxLab = ilb;
    4079        3884 :       if (lbID[ilb] == tpcLabel) tpcLabID = ilb;
    4080             :     }
    4081             :     // if there is an equal choice, prefer ITS label consistent with TPC label
    4082        3722 :     if (tpcLabID>=0 && (tpcLabID!=maxLab) && lbStat[maxLab]==lbStat[tpcLabID]) maxLab=tpcLabID;
    4083             :                                                                                
    4084        2485 :     track->SetFakeRatio(1.-float(lbStat[maxLab])/nCl);
    4085        2485 :     track->SetLabel( lbStat[maxLab]>=nCl-wrong ? lbID[maxLab] : -lbID[maxLab]);
    4086        2485 :   }
    4087             :   //
    4088        5017 : }
    4089             : 
    4090             : /*
    4091             : //------------------------------------------------------------------------
    4092             : void AliITStrackerMI::CookLabel(AliITStrackMI *track,Float_t wrong) const {
    4093             :   //--------------------------------------------------------------------
    4094             :   //This function "cooks" a track label. If label<0, this track is fake.
    4095             :   //--------------------------------------------------------------------
    4096             :   Int_t tpcLabel=-1; 
    4097             :      
    4098             :   if (track->GetESDtrack()){
    4099             :     tpcLabel = track->GetESDtrack()->GetTPCLabel();
    4100             :     ULong_t trStatus=track->GetESDtrack()->GetStatus();
    4101             :     if(!(trStatus&AliESDtrack::kTPCin)) tpcLabel=track->GetLabel(); // for ITSsa tracks
    4102             :   }
    4103             :    track->SetChi2MIP(9,0);
    4104             :    Int_t nwrong=0;
    4105             :    for (Int_t i=0;i<track->GetNumberOfClusters();i++){
    4106             :      Int_t cindex = track->GetClusterIndex(i);
    4107             :      Int_t l=(cindex & 0xf0000000) >> 28;
    4108             :      AliITSRecPoint *cl = (AliITSRecPoint*)GetCluster(cindex);
    4109             :      Int_t isWrong=1;
    4110             :      for (Int_t ind=0;ind<3;ind++){
    4111             :        if (cl->GetLabel(ind)==TMath::Abs(tpcLabel)) isWrong=0;
    4112             :        //AliDebug(2,Form("icl %d  ilab %d lab %d",i,ind,cl->GetLabel(ind)));
    4113             :      }
    4114             :      track->SetChi2MIP(9,track->GetChi2MIP(9)+isWrong*(2<<l));
    4115             :      nwrong+=isWrong;
    4116             :    }
    4117             :    Int_t nclusters = track->GetNumberOfClusters();
    4118             :    if (nclusters > 0) //PH Some tracks don't have any cluster
    4119             :      track->SetFakeRatio(double(nwrong)/double(nclusters));
    4120             :    if (tpcLabel>0 && track->GetFakeRatio()>wrong) {
    4121             :      track->SetLabel(-tpcLabel);
    4122             :    } else {
    4123             :      track->SetLabel(tpcLabel);
    4124             :    }
    4125             :    AliDebug(2,Form(" nls %d wrong %d  label %d  tpcLabel %d\n",nclusters,nwrong,track->GetLabel(),tpcLabel)); 
    4126             : }
    4127             : */
    4128             : 
    4129             : //------------------------------------------------------------------------
    4130             : void AliITStrackerMI::CookdEdx(AliITStrackMI* track){
    4131             :   //
    4132             :   // Fill the dE/dx in this track
    4133             :   //
    4134        4040 :   track->SetChi2MIP(9,0);
    4135       23388 :   for (Int_t i=0;i<track->GetNumberOfClusters();i++){
    4136        9674 :     Int_t cindex = track->GetClusterIndex(i);
    4137        9674 :     Int_t l=(cindex & 0xf0000000) >> 28;
    4138        9674 :     AliITSRecPoint *cl = (AliITSRecPoint*)GetCluster(cindex);
    4139        9674 :     Int_t lab = TMath::Abs(track->GetESDtrack()->GetTPCLabel());
    4140             :     Int_t isWrong=1;
    4141       77392 :     for (Int_t ind=0;ind<3;ind++){
    4142       33780 :       if (cl->GetLabel(ind)==lab) isWrong=0;
    4143             :     }
    4144        9674 :     track->SetChi2MIP(9,track->GetChi2MIP(9)+isWrong*(2<<l));
    4145             :   }
    4146             :   Double_t low=0.;
    4147             :   Double_t up=0.51;    
    4148        2020 :   track->CookdEdx(low,up);
    4149        2020 : }
    4150             : //------------------------------------------------------------------------
    4151             : void AliITStrackerMI::MakeCoefficients(Int_t ntracks){
    4152             :   //
    4153             :   // Create some arrays
    4154             :   //
    4155          16 :   if (fCoefficients) delete []fCoefficients;
    4156           8 :   fCoefficients = new Float_t[ntracks*48];
    4157       10576 :   for (Int_t i=0;i<ntracks*48;i++) fCoefficients[i]=-1.;
    4158           8 : }
    4159             : //------------------------------------------------------------------------
    4160             : Double_t AliITStrackerMI::GetPredictedChi2MI(AliITStrackMI* track, const AliITSRecPoint *cluster,Int_t layer) 
    4161             : {
    4162             :   //
    4163             :   // Compute predicted chi2
    4164             :   //
    4165             :   // Take into account the mis-alignment (bring track to cluster plane)
    4166       23936 :   Double_t xTrOrig=track->GetX();
    4167       11968 :   if (!track->Propagate(xTrOrig+cluster->GetX())) return 1000.;
    4168       11968 :   Float_t erry,errz,covyz;
    4169       11968 :   Float_t theta = track->GetTgl();
    4170       11968 :   Float_t phi   = track->GetSnp();
    4171       11968 :   phi *= TMath::Sqrt(1./((1.-phi)*(1.+phi)));
    4172       11968 :   AliITSClusterParam::GetError(layer,cluster,theta,phi,track->GetExpQ(),erry,errz,covyz);
    4173       35904 :   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()));
    4174       35904 :   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()));
    4175       11968 :   Double_t chi2 = track->GetPredictedChi2MI(cluster->GetY(),cluster->GetZ(),erry,errz,covyz);
    4176             :   // Bring the track back to detector plane in ideal geometry
    4177             :   // [mis-alignment will be accounted for in UpdateMI()]
    4178       11968 :   if (!track->Propagate(xTrOrig)) return 1000.;
    4179       11968 :   Float_t ny,nz;
    4180       11968 :   AliITSClusterParam::GetNTeor(layer,cluster,theta,phi,ny,nz);  
    4181       11968 :   Double_t delta = cluster->GetNy()+cluster->GetNz()-nz-ny;
    4182       11968 :   if (delta>1){
    4183         202 :     chi2+=0.5*TMath::Min(delta/2,2.);
    4184         202 :     chi2+=2.*cluster->GetDeltaProbability();
    4185         202 :   }
    4186             :   //
    4187       11968 :   track->SetNy(layer,ny);
    4188       11968 :   track->SetNz(layer,nz);
    4189       11968 :   track->SetSigmaY(layer,erry);
    4190       11968 :   track->SetSigmaZ(layer, errz);
    4191       11968 :   track->SetSigmaYZ(layer,covyz);
    4192             :   //track->fNormQ[layer] = cluster->GetQ()/TMath::Sqrt(1+theta*theta+phi*phi);
    4193       11968 :   track->SetNormQ(layer,cluster->GetQ()/TMath::Sqrt((1.+ track->GetTgl()*track->GetTgl())/((1.-track->GetSnp())*(1.+track->GetSnp()))));
    4194             :   return chi2;
    4195             : 
    4196       35904 : }
    4197             : //------------------------------------------------------------------------
    4198             : Int_t AliITStrackerMI::UpdateMI(AliITStrackMI* track, const AliITSRecPoint* cl,Double_t chi2,Int_t index) const 
    4199             : {
    4200             :   //
    4201             :   // Update ITS track
    4202             :   //
    4203       23736 :   Int_t layer = (index & 0xf0000000) >> 28;
    4204       11868 :   track->SetClIndex(layer, index);
    4205       20902 :   if (layer>1&&AliITSReconstructor::GetRecoParam()->GetUseAmplitudeInfo(layer)) {
    4206        9034 :     if (track->GetNormQ(layer)/track->GetExpQ()<0.5 ) {
    4207           0 :       chi2+= (0.5-track->GetNormQ(layer)/track->GetExpQ())*10.;
    4208           0 :       track->SetdEdxMismatch(track->GetdEdxMismatch()+(0.5-track->GetNormQ(layer)/track->GetExpQ())*10.);
    4209           0 :     }
    4210             :   }
    4211             : 
    4212       11868 :   if (TMath::Abs(cl->GetQ())<1.e-13) return 0;  // ingore the "virtual" clusters
    4213             : 
    4214             : 
    4215             :   // Take into account the mis-alignment (bring track to cluster plane)
    4216       11868 :   Double_t xTrOrig=track->GetX();
    4217       11868 :   Float_t clxyz[3]={0}; cl->GetGlobalXYZ(clxyz);Double_t trxyz[3]={0}; track->GetXYZ(trxyz);
    4218       35604 :   AliDebug(2,Form("gtr %f %f %f",trxyz[0],trxyz[1],trxyz[2]));
    4219       35604 :   AliDebug(2,Form("gcl %f %f %f",clxyz[0],clxyz[1],clxyz[2]));
    4220       35604 :   AliDebug(2,Form(" xtr %f  xcl %f",track->GetX(),cl->GetX()));
    4221             : 
    4222       11868 :   if (!track->Propagate(xTrOrig+cl->GetX())) return 0;
    4223             :   
    4224       11868 :   AliCluster c(*cl);
    4225       11868 :   c.SetSigmaY2(track->GetSigmaY(layer)*track->GetSigmaY(layer));
    4226       11868 :   c.SetSigmaZ2(track->GetSigmaZ(layer)*track->GetSigmaZ(layer));
    4227       11868 :   c.SetSigmaYZ(track->GetSigmaYZ(layer));
    4228             : 
    4229             : 
    4230       23736 :   Int_t updated = track->UpdateMI(&c,chi2,index);
    4231             :   // Bring the track back to detector plane in ideal geometry
    4232       23736 :   if (!track->Propagate(xTrOrig)) return 0;
    4233             :  
    4234       11868 :   if(!updated) AliDebug(2,"update failed");
    4235       11868 :   return updated;
    4236       35604 : }
    4237             : 
    4238             : //------------------------------------------------------------------------
    4239             : void AliITStrackerMI::GetDCASigma(const AliITStrackMI* track, Float_t & sigmarfi, Float_t &sigmaz)
    4240             : {
    4241             :   //
    4242             :   //DCA sigmas parameterization
    4243             :   //to be paramterized using external parameters in future 
    4244             :   //
    4245             :   // 
    4246        1740 :   Double_t curv=track->GetC();
    4247         870 :   sigmarfi = 0.0040+1.4 *TMath::Abs(curv)+332.*curv*curv;
    4248         870 :   sigmaz   = 0.0110+4.37*TMath::Abs(curv);
    4249         870 : }
    4250             : //------------------------------------------------------------------------
    4251             : void AliITStrackerMI::SignDeltas(const TObjArray *clusterArray, Float_t vz)
    4252             : {
    4253             :   //
    4254             :   // Clusters from delta electrons?
    4255             :   //  
    4256       35168 :   Int_t entries = clusterArray->GetEntriesFast();
    4257       35158 :   if (entries<4) return;
    4258          10 :   AliITSRecPoint* cluster = (AliITSRecPoint*)clusterArray->At(0);
    4259          10 :   Int_t layer = cluster->GetLayer();
    4260          20 :   if (layer>1) return;
    4261           0 :   Int_t index[10000]={0};
    4262             :   Int_t ncandidates=0;
    4263           0 :   Float_t r = (layer>0)? 7:4;
    4264             :   // 
    4265           0 :   for (Int_t i=0;i<entries;i++){
    4266           0 :     AliITSRecPoint* cl0 = (AliITSRecPoint*)clusterArray->At(i);
    4267           0 :     Float_t nz = 1+TMath::Abs((cl0->GetZ()-vz)/r);
    4268           0 :     if (cl0->GetNy()+cl0->GetNz()<=5+2*layer+nz) continue;
    4269           0 :     index[ncandidates] = i;  //candidate to belong to delta electron track
    4270           0 :     ncandidates++;
    4271           0 :     if (cl0->GetNy()+cl0->GetNz()>9+2*layer+nz) {
    4272           0 :       cl0->SetDeltaProbability(1);
    4273           0 :     }
    4274           0 :   }
    4275             :   //
    4276             :   //  
    4277             :   //
    4278           0 :   for (Int_t i=0;i<ncandidates;i++){
    4279           0 :     AliITSRecPoint* cl0 = (AliITSRecPoint*)clusterArray->At(index[i]);
    4280           0 :     if (cl0->GetDeltaProbability()>0.8) continue;
    4281             :     // 
    4282             :     Int_t ncl = 0;
    4283           0 :     Float_t y[100]={0},z[100]={0},sumy,sumz,sumy2, sumyz, sumw;
    4284             :     sumy=sumz=sumy2=sumyz=sumw=0.0;
    4285           0 :     for (Int_t j=0;j<ncandidates;j++){
    4286           0 :       if (i==j) continue;
    4287           0 :       AliITSRecPoint* cl1 = (AliITSRecPoint*)clusterArray->At(index[j]);
    4288             :       //
    4289           0 :       Float_t dz = cl0->GetZ()-cl1->GetZ();
    4290           0 :       Float_t dy = cl0->GetY()-cl1->GetY();
    4291           0 :       if (TMath::Sqrt(dz*dz+dy*dy)<0.2){
    4292           0 :         Float_t weight = cl1->GetNy()+cl1->GetNz()-2;
    4293           0 :         y[ncl] = cl1->GetY();
    4294           0 :         z[ncl] = cl1->GetZ();
    4295           0 :         sumy+= y[ncl]*weight;
    4296           0 :         sumz+= z[ncl]*weight;
    4297           0 :         sumy2+=y[ncl]*y[ncl]*weight;
    4298           0 :         sumyz+=y[ncl]*z[ncl]*weight;
    4299           0 :         sumw+=weight;
    4300           0 :         ncl++;
    4301           0 :       }
    4302           0 :     }
    4303           0 :     if (ncl<4) continue;
    4304           0 :     Float_t det = sumw*sumy2  - sumy*sumy;
    4305             :     Float_t delta=1000;
    4306           0 :     if (TMath::Abs(det)>0.01){
    4307           0 :       Float_t z0  = (sumy2*sumz - sumy*sumyz)/det;
    4308           0 :       Float_t k   = (sumyz*sumw - sumy*sumz)/det;
    4309           0 :       delta = TMath::Abs(cl0->GetZ()-(z0+k*cl0->GetY()));
    4310           0 :     }
    4311             :     else{
    4312           0 :       Float_t z0  = sumyz/sumy;
    4313           0 :       delta = TMath::Abs(cl0->GetZ()-z0);
    4314             :     }
    4315           0 :     if ( delta<0.05) {
    4316           0 :       cl0->SetDeltaProbability(1-20.*delta);
    4317           0 :     }   
    4318           0 :   }
    4319       17584 : }
    4320             : //------------------------------------------------------------------------
    4321             : void AliITStrackerMI::UpdateESDtrack(AliITStrackMI* track, ULong_t flags) const
    4322             : {
    4323             :   //
    4324             :   // Update ESD track
    4325             :   //
    4326         732 :   track->UpdateESDtrack(flags);
    4327         366 :   AliITStrackMI * oldtrack = (AliITStrackMI*)(track->GetESDtrack()->GetITStrack());
    4328         934 :   if (oldtrack) delete oldtrack; 
    4329         732 :   track->GetESDtrack()->SetITStrack(new AliITStrackMI(*track));
    4330             :   // if (TMath::Abs(track->GetDnorm(1))<0.000000001){
    4331             :   //   printf("Problem\n");
    4332             :   // }
    4333         366 : }
    4334             : //------------------------------------------------------------------------
    4335             : Int_t AliITStrackerMI::GetNearestLayer(const Double_t *xr) const{
    4336             :   //
    4337             :   // Get nearest upper layer close to the point xr.
    4338             :   // rough approximation 
    4339             :   //
    4340             :   const Float_t kRadiuses[6]={4,6.5,15.03,24.,38.5,43.7};
    4341          28 :   Float_t radius = TMath::Sqrt(xr[0]*xr[0]+xr[1]*xr[1]);
    4342             :   Int_t res =6;
    4343         172 :   for (Int_t i=0;i<6;i++){
    4344          74 :     if (radius<kRadiuses[i]){
    4345             :       res =i;
    4346           6 :       break;
    4347             :     }
    4348             :   }
    4349          14 :   return res;
    4350             : }
    4351             : //------------------------------------------------------------------------
    4352             : void AliITStrackerMI::BuildMaterialLUT(TString material) {
    4353             :   //--------------------------------------------------------------------
    4354             :   // Fill a look-up table with mean material
    4355             :   //--------------------------------------------------------------------
    4356             : 
    4357             :   Int_t n=1000;
    4358          12 :   Double_t mparam[7]={0};
    4359           6 :   Double_t point1[3]={0},point2[3]={0};
    4360             :   Double_t phi,cosphi,sinphi,z;
    4361             :   // 0-5 layers, 6 pipe, 7-8 shields 
    4362           6 :   Double_t rmin[9]={ 3.5, 5.5,13.0,22.0,35.0,41.0, 2.0, 8.0,25.0};
    4363           6 :   Double_t rmax[9]={ 5.5, 8.0,17.0,26.0,41.0,47.0, 3.0,10.5,30.0};
    4364             : 
    4365             :   Int_t ifirst=0,ilast=0;  
    4366           6 :   if(material.Contains("Pipe")) {
    4367             :     ifirst=6; ilast=6;
    4368           6 :   } else if(material.Contains("Shields")) {
    4369             :     ifirst=7; ilast=8;
    4370           4 :   } else if(material.Contains("Layers")) {
    4371             :     ifirst=0; ilast=5;
    4372           2 :   } else {
    4373           0 :     Error("BuildMaterialLUT","Wrong layer name\n");
    4374             :   }
    4375             :   const double kAngEps = 1e-4; // tiny slope to avoid tracks strictly normal to Z axis
    4376          48 :   for(Int_t imat=ifirst; imat<=ilast; imat++) {
    4377          18 :     Double_t param[5]={0.,0.,0.,0.,0.};
    4378       36036 :     for (Int_t i=0; i<n; i++) {
    4379       18000 :       phi = 2.*TMath::Pi()*gRandom->Rndm();
    4380       18000 :       cosphi = TMath::Cos(phi); sinphi = TMath::Sin(phi); 
    4381       18000 :       z = 14.*(-1.+2.*gRandom->Rndm()); // SPD barrel
    4382       18000 :       point1[0] = rmin[imat]*cosphi;
    4383       18000 :       point1[1] = rmin[imat]*sinphi;
    4384       18000 :       point1[2] = z;
    4385       18000 :       point2[0] = rmax[imat]*cosphi;
    4386       18000 :       point2[1] = rmax[imat]*sinphi;
    4387       18000 :       point2[2] = z+(rmax[imat]-rmin[imat])*kAngEps;
    4388       18000 :       AliTracker::MeanMaterialBudget(point1,point2,mparam);
    4389       18000 :       if (mparam[1]>999) {n--; continue;}  // skip anomalous values in failed propagation
    4390      216000 :       for(Int_t j=0;j<5;j++) param[j]+=mparam[j];
    4391       18000 :     }
    4392         216 :     for(Int_t j=0;j<5;j++) param[j]/=(Float_t)n;
    4393          18 :     if(imat<=5) {
    4394          12 :       fxOverX0Layer[imat] = param[1];
    4395          12 :       fxTimesRhoLayer[imat] = param[0]*param[4];
    4396          18 :     } else if(imat==6) {
    4397           2 :       fxOverX0Pipe = param[1];
    4398           2 :       fxTimesRhoPipe = param[0]*param[4];
    4399           6 :     } else if(imat==7) {
    4400           2 :       fxOverX0Shield[0] = param[1];
    4401           2 :       fxTimesRhoShield[0] = param[0]*param[4];
    4402           4 :     } else if(imat==8) {
    4403           2 :       fxOverX0Shield[1] = param[1];
    4404           2 :       fxTimesRhoShield[1] = param[0]*param[4];
    4405           2 :     }
    4406          18 :   }
    4407             :   /*
    4408             :   printf("%s\n",material.Data());
    4409             :   printf("%f  %f\n",fxOverX0Pipe,fxTimesRhoPipe);
    4410             :   printf("%f  %f\n",fxOverX0Shield[0],fxTimesRhoShield[0]);
    4411             :   printf("%f  %f\n",fxOverX0Shield[1],fxTimesRhoShield[1]);
    4412             :   printf("%f  %f\n",fxOverX0Layer[0],fxTimesRhoLayer[0]);
    4413             :   printf("%f  %f\n",fxOverX0Layer[1],fxTimesRhoLayer[1]);
    4414             :   printf("%f  %f\n",fxOverX0Layer[2],fxTimesRhoLayer[2]);
    4415             :   printf("%f  %f\n",fxOverX0Layer[3],fxTimesRhoLayer[3]);
    4416             :   printf("%f  %f\n",fxOverX0Layer[4],fxTimesRhoLayer[4]);
    4417             :   printf("%f  %f\n",fxOverX0Layer[5],fxTimesRhoLayer[5]);
    4418             :   */
    4419             :   return;
    4420           6 : }
    4421             : //------------------------------------------------------------------------
    4422             : Int_t AliITStrackerMI::CorrectForPipeMaterial(AliITStrackMI *t,
    4423             :                                               TString direction) {
    4424             :   //-------------------------------------------------------------------
    4425             :   // Propagate beyond beam pipe and correct for material
    4426             :   // (material budget in different ways according to fUseTGeo value)
    4427             :   // Add time if going outward (PropagateTo or PropagateToTGeo)
    4428             :   //-------------------------------------------------------------------
    4429             : 
    4430             :   // Define budget mode:
    4431             :   // 0: material from AliITSRecoParam (hard coded)
    4432             :   // 1: material from TGeo in one step (on the fly)
    4433             :   // 2: material from lut
    4434             :   // 3: material from TGeo in one step (same for all hypotheses)
    4435             :   Int_t mode;
    4436        1324 :   switch(fUseTGeo) {
    4437             :   case 0:
    4438             :     mode=0; 
    4439           0 :     break;    
    4440             :   case 1:
    4441             :     mode=1;
    4442           0 :     break;    
    4443             :   case 2:
    4444             :     mode=2;
    4445           0 :     break;
    4446             :   case 3:
    4447         662 :     if(fTrackingPhase.Contains("Clusters2Tracks")) 
    4448         566 :       { mode=3; } else { mode=1; }
    4449             :     break;
    4450             :   case 4:
    4451           0 :     if(fTrackingPhase.Contains("Clusters2Tracks")) 
    4452           0 :       { mode=3; } else { mode=2; }
    4453             :     break;
    4454             :   default:
    4455             :     mode=0;
    4456           0 :     break;
    4457             :   }
    4458         662 :   if(fTrackingPhase.Contains("Default")) mode=0;
    4459             : 
    4460         662 :   Int_t index=fCurrentEsdTrack;
    4461             : 
    4462         662 :   Float_t  dir = (direction.Contains("inward") ? 1. : -1.);
    4463        1986 :   Double_t rToGo=(dir>0 ? AliITSRecoParam::GetrInsidePipe() : AliITSRecoParam::GetrOutsidePipe());
    4464         662 :   Double_t xToGo;
    4465         666 :   if (!t->GetLocalXat(rToGo,xToGo)) return 0;
    4466             : 
    4467        1240 :   Double_t xOverX0,x0,lengthTimesMeanDensity;
    4468             : 
    4469        1240 :   switch(mode) {
    4470             :   case 0:
    4471           0 :     xOverX0 = AliITSRecoParam::GetdPipe();
    4472           0 :     x0 = AliITSRecoParam::GetX0Be();
    4473           0 :     lengthTimesMeanDensity = xOverX0*x0;
    4474           0 :     lengthTimesMeanDensity *= dir;
    4475           0 :     if (!t->PropagateTo(xToGo,xOverX0,lengthTimesMeanDensity/xOverX0)) return 0;
    4476             :     break;
    4477             :   case 1:
    4478          92 :     if (!t->PropagateToTGeo(xToGo,1)) return 0;
    4479             :     break;
    4480             :   case 2:
    4481           0 :     if(fxOverX0Pipe<0) BuildMaterialLUT("Pipe");  
    4482           0 :     xOverX0 = fxOverX0Pipe;
    4483           0 :     lengthTimesMeanDensity = fxTimesRhoPipe;
    4484           0 :     lengthTimesMeanDensity *= dir;
    4485           0 :     if (!t->PropagateTo(xToGo,xOverX0,lengthTimesMeanDensity/xOverX0)) return 0;
    4486             :     break;
    4487             :   case 3:
    4488        1132 :     if(!fxOverX0PipeTrks || index<0 || index>=fNtracks) Error("CorrectForPipeMaterial","Incorrect usage of UseTGeo option!\n");
    4489         566 :     if(fxOverX0PipeTrks[index]<0) {
    4490          76 :       if (!t->PropagateToTGeo(xToGo,1,xOverX0,lengthTimesMeanDensity)) return 0;
    4491         152 :       Double_t angle=TMath::Sqrt((1.+t->GetTgl()*t->GetTgl())/
    4492          76 :                                  ((1.-t->GetSnp())*(1.+t->GetSnp())));
    4493          76 :       fxOverX0PipeTrks[index] = TMath::Abs(xOverX0)/angle;
    4494          76 :       fxTimesRhoPipeTrks[index] = TMath::Abs(lengthTimesMeanDensity)/angle;
    4495             :       return 1;
    4496             :     }
    4497         490 :     xOverX0 = fxOverX0PipeTrks[index];
    4498         490 :     lengthTimesMeanDensity = fxTimesRhoPipeTrks[index];
    4499         490 :     lengthTimesMeanDensity *= dir;
    4500         490 :     if (!t->PropagateTo(xToGo,xOverX0,lengthTimesMeanDensity/xOverX0)) return 0;
    4501             :     break;
    4502             :   }
    4503             : 
    4504         582 :   return 1;
    4505        1320 : }
    4506             : //------------------------------------------------------------------------
    4507             : Int_t AliITStrackerMI::CorrectForShieldMaterial(AliITStrackMI *t,
    4508             :                                                 TString shield,
    4509             :                                                 TString direction) {
    4510             :   //-------------------------------------------------------------------
    4511             :   // Propagate beyond SPD or SDD shield and correct for material
    4512             :   // (material budget in different ways according to fUseTGeo value)
    4513             :   // Add time if going outward (PropagateTo or PropagateToTGeo)
    4514             :   //-------------------------------------------------------------------
    4515             : 
    4516             :   // Define budget mode:
    4517             :   // 0: material from AliITSRecoParam (hard coded)
    4518             :   // 1: material from TGeo in steps of X cm (on the fly)
    4519             :   //    X = AliITSRecoParam::GetStepSizeTGeo()
    4520             :   // 2: material from lut
    4521             :   // 3: material from TGeo in one step (same for all hypotheses)
    4522             :   Int_t mode;
    4523        9724 :   switch(fUseTGeo) {
    4524             :   case 0:
    4525             :     mode=0; 
    4526           0 :     break;    
    4527             :   case 1:
    4528             :     mode=1;
    4529           0 :     break;    
    4530             :   case 2:
    4531             :     mode=2;
    4532           0 :     break;
    4533             :   case 3:
    4534        4862 :     if(fTrackingPhase.Contains("Clusters2Tracks")) 
    4535        4398 :       { mode=3; } else { mode=1; }
    4536             :     break;
    4537             :   case 4:
    4538           0 :     if(fTrackingPhase.Contains("Clusters2Tracks")) 
    4539           0 :       { mode=3; } else { mode=2; }
    4540             :     break;
    4541             :   default:
    4542             :     mode=0;
    4543           0 :     break;
    4544             :   }
    4545        4934 :   if(fTrackingPhase.Contains("Default")) mode=0;
    4546             : 
    4547        4862 :   Float_t  dir = (direction.Contains("inward") ? 1. : -1.);
    4548             :   Double_t rToGo;
    4549             :   Int_t    shieldindex=0;
    4550        4862 :   if (shield.Contains("SDD")) { // SDDouter
    4551        7236 :     rToGo=(dir>0 ? AliITSRecoParam::GetrInsideShield(1) : AliITSRecoParam::GetrOutsideShield(1));
    4552             :     shieldindex=1;
    4553        4862 :   } else if (shield.Contains("SPD")) {        // SPDouter
    4554        7350 :     rToGo=(dir>0 ? AliITSRecoParam::GetrInsideShield(0) : AliITSRecoParam::GetrOutsideShield(0)); 
    4555             :     shieldindex=0;
    4556             :   } else {
    4557           0 :     Error("CorrectForShieldMaterial"," Wrong shield name\n");
    4558           0 :     return 0;
    4559             :   }
    4560             : 
    4561             :   // do nothing if we are already beyond the shield
    4562        4862 :   Double_t rTrack = TMath::Sqrt(t->GetX()*t->GetX()+t->GetY()*t->GetY());
    4563        6948 :   if(dir<0 && rTrack > rToGo) return 1; // going outward
    4564        7638 :   if(dir>0 && rTrack < rToGo) return 1; // going inward
    4565             : 
    4566             : 
    4567        4748 :   Double_t xToGo;
    4568        4754 :   if (!t->GetLocalXat(rToGo,xToGo)) return 0;
    4569             : 
    4570        9296 :   Int_t index=2*fCurrentEsdTrack+shieldindex;
    4571             : 
    4572        9296 :   Double_t xOverX0,x0,lengthTimesMeanDensity;
    4573             :   Int_t nsteps=1;
    4574             : 
    4575        9296 :   switch(mode) {
    4576             :   case 0:
    4577          70 :     xOverX0 = AliITSRecoParam::Getdshield(shieldindex);
    4578          70 :     x0 = AliITSRecoParam::GetX0shield(shieldindex);
    4579          70 :     lengthTimesMeanDensity = xOverX0*x0;
    4580          70 :     lengthTimesMeanDensity *= dir;
    4581          70 :     if (!t->PropagateTo(xToGo,xOverX0,lengthTimesMeanDensity/xOverX0)) return 0;
    4582             :     break;
    4583             :   case 1:
    4584         386 :     nsteps= (Int_t)(TMath::Abs(t->GetX()-xToGo)/AliITSReconstructor::GetRecoParam()->GetStepSizeTGeo())+1;
    4585         386 :     if (!t->PropagateToTGeo(xToGo,nsteps)) return 0; // cross the material and apply correction
    4586             :     break;
    4587             :   case 2:
    4588           0 :     if(fxOverX0Shield[shieldindex]<0) BuildMaterialLUT("Shields");  
    4589           0 :     xOverX0 = fxOverX0Shield[shieldindex];
    4590           0 :     lengthTimesMeanDensity = fxTimesRhoShield[shieldindex];
    4591           0 :     lengthTimesMeanDensity *= dir;
    4592           0 :     if (!t->PropagateTo(xToGo,xOverX0,lengthTimesMeanDensity/xOverX0)) return 0;
    4593             :     break;
    4594             :   case 3:
    4595        8572 :     if(!fxOverX0ShieldTrks || index<0 || index>=2*fNtracks) Error("CorrectForShieldMaterial","Incorrect usage of UseTGeo option!\n");
    4596        4286 :     if(fxOverX0ShieldTrks[index]<0) {
    4597         188 :       if (!t->PropagateToTGeo(xToGo,1,xOverX0,lengthTimesMeanDensity)) return 0;
    4598         376 :       Double_t angle=TMath::Sqrt((1.+t->GetTgl()*t->GetTgl())/
    4599         188 :                                  ((1.-t->GetSnp())*(1.+t->GetSnp())));
    4600         188 :       fxOverX0ShieldTrks[index] = TMath::Abs(xOverX0)/angle;
    4601         188 :       fxTimesRhoShieldTrks[index] = TMath::Abs(lengthTimesMeanDensity)/angle;
    4602             :       return 1;
    4603             :     }
    4604        4098 :     xOverX0 = fxOverX0ShieldTrks[index];
    4605        4098 :     lengthTimesMeanDensity = fxTimesRhoShieldTrks[index];
    4606        4098 :     lengthTimesMeanDensity *= dir;
    4607        4098 :     if (!t->PropagateTo(xToGo,xOverX0,lengthTimesMeanDensity/xOverX0)) return 0;
    4608             :     break;
    4609             :   }
    4610             : 
    4611        4554 :   return 1;
    4612       14352 : }
    4613             : //------------------------------------------------------------------------
    4614             : Int_t AliITStrackerMI::CorrectForLayerMaterial(AliITStrackMI *t,
    4615             :                                                Int_t layerindex,
    4616             :                                                Double_t oldGlobXYZ[3],
    4617             :                                                TString direction) {
    4618             :   //-------------------------------------------------------------------
    4619             :   // Propagate beyond layer and correct for material
    4620             :   // (material budget in different ways according to fUseTGeo value)
    4621             :   // Add time if going outward (PropagateTo or PropagateToTGeo)
    4622             :   //-------------------------------------------------------------------
    4623             : 
    4624             :   // Define budget mode:
    4625             :   // 0: material from AliITSRecoParam (hard coded)
    4626             :   // 1: material from TGeo in stepsof X cm (on the fly)
    4627             :   //    X = AliITSRecoParam::GetStepSizeTGeo()
    4628             :   // 2: material from lut
    4629             :   // 3: material from TGeo in one step (same for all hypotheses)
    4630             :   Int_t mode;
    4631       28944 :   switch(fUseTGeo) {
    4632             :   case 0:
    4633             :     mode=0; 
    4634           0 :     break;    
    4635             :   case 1:
    4636             :     mode=1;
    4637           0 :     break;    
    4638             :   case 2:
    4639             :     mode=2;
    4640           0 :     break;
    4641             :   case 3:
    4642       14472 :     if(fTrackingPhase.Contains("Clusters2Tracks"))
    4643       13082 :       { mode=3; } else { mode=1; }
    4644             :     break;
    4645             :   case 4:
    4646           0 :     if(fTrackingPhase.Contains("Clusters2Tracks")) 
    4647           0 :       { mode=3; } else { mode=2; }
    4648             :     break;
    4649             :   default:
    4650             :     mode=0;
    4651           0 :     break;
    4652             :   }
    4653       14684 :   if(fTrackingPhase.Contains("Default")) mode=0;
    4654             : 
    4655       14472 :   Float_t  dir = (direction.Contains("inward") ? 1. : -1.);
    4656             : 
    4657       14472 :   Double_t r=fgLayers[layerindex].GetR();
    4658       14472 :   Double_t deltar=(layerindex<2 ? 0.10*r : 0.05*r);
    4659             : 
    4660       14472 :   Double_t rToGo=TMath::Sqrt(t->GetX()*t->GetX()+t->GetY()*t->GetY())-deltar*dir;
    4661       14472 :   Double_t xToGo;
    4662       14473 :   if (!t->GetLocalXat(rToGo,xToGo)) return 0;
    4663             : 
    4664       14471 :   Int_t index=6*fCurrentEsdTrack+layerindex;
    4665             : 
    4666             : 
    4667       14471 :   Double_t xOverX0=0.0,x0=0.0,lengthTimesMeanDensity=0.0;
    4668             :   Int_t nsteps=1;
    4669             : 
    4670             :   // back before material (no correction)
    4671       14471 :   Double_t rOld,xOld;
    4672       14471 :   rOld=TMath::Sqrt(oldGlobXYZ[0]*oldGlobXYZ[0]+oldGlobXYZ[1]*oldGlobXYZ[1]);
    4673       14471 :   if (!t->GetLocalXat(rOld,xOld)) return 0;
    4674       14471 :   if (!t->Propagate(xOld)) return 0;
    4675             : 
    4676       28374 :   switch(mode) {
    4677             :   case 0:
    4678         212 :     xOverX0 = fgLayers[layerindex].GetThickness(t->GetY(),t->GetZ(),x0);
    4679         212 :     lengthTimesMeanDensity = xOverX0*x0;
    4680         212 :     lengthTimesMeanDensity *= dir;
    4681             :     // Bring the track beyond the material
    4682         212 :     if (!t->PropagateTo(xToGo,xOverX0,lengthTimesMeanDensity/xOverX0)) return 0;
    4683             :     break;
    4684             :   case 1:
    4685        1177 :     nsteps = (Int_t)(TMath::Abs(xOld-xToGo)/AliITSReconstructor::GetRecoParam()->GetStepSizeTGeo())+1;
    4686        1177 :     if (!t->PropagateToTGeo(xToGo,nsteps)) return 0; // cross the material and apply correction
    4687             :     break;
    4688             :   case 2:
    4689           0 :     if(fxOverX0Layer[layerindex]<0) BuildMaterialLUT("Layers");  
    4690           0 :     xOverX0 = fxOverX0Layer[layerindex];
    4691           0 :     lengthTimesMeanDensity = fxTimesRhoLayer[layerindex];
    4692           0 :     lengthTimesMeanDensity *= dir;
    4693             :     // Bring the track beyond the material
    4694           0 :     if (!t->PropagateTo(xToGo,xOverX0,lengthTimesMeanDensity/xOverX0)) return 0;
    4695             :     break;
    4696             :   case 3:
    4697       26164 :     if(!fxOverX0LayerTrks || index<0 || index>=6*fNtracks) Error("CorrectForLayerMaterial","Incorrect usage of UseTGeo option!\n");
    4698       13082 :     if(fxOverX0LayerTrks[index]<0) {
    4699         568 :       nsteps = (Int_t)(TMath::Abs(xOld-xToGo)/AliITSReconstructor::GetRecoParam()->GetStepSizeTGeo())+1;
    4700         568 :       if (!t->PropagateToTGeo(xToGo,nsteps,xOverX0,lengthTimesMeanDensity)) return 0;
    4701        1136 :       Double_t angle=TMath::Sqrt((1.+t->GetTgl()*t->GetTgl())/
    4702         568 :                                  ((1.-t->GetSnp())*(1.+t->GetSnp())));
    4703         568 :       fxOverX0LayerTrks[index] = TMath::Abs(xOverX0)/angle;
    4704         568 :       fxTimesRhoLayerTrks[index] = TMath::Abs(lengthTimesMeanDensity)/angle;
    4705             :       return 1;
    4706             :     }
    4707       12514 :     xOverX0 = fxOverX0LayerTrks[index];
    4708       12514 :     lengthTimesMeanDensity = fxTimesRhoLayerTrks[index];
    4709       12514 :     lengthTimesMeanDensity *= dir;
    4710       12514 :     if (!t->PropagateTo(xToGo,xOverX0,lengthTimesMeanDensity/xOverX0)) return 0;
    4711             :     break;
    4712             :   }
    4713             : 
    4714             : 
    4715       13903 :   return 1;
    4716       28943 : }
    4717             : //------------------------------------------------------------------------
    4718             : void AliITStrackerMI::MakeTrksMaterialLUT(Int_t ntracks) {
    4719             :   //-----------------------------------------------------------------
    4720             :   // Initialize LUT for storing material for each prolonged track
    4721             :   //-----------------------------------------------------------------
    4722          16 :   fxOverX0PipeTrks = new Float_t[ntracks]; 
    4723           8 :   fxTimesRhoPipeTrks = new Float_t[ntracks]; 
    4724           8 :   fxOverX0ShieldTrks = new Float_t[ntracks*2]; 
    4725           8 :   fxTimesRhoShieldTrks = new Float_t[ntracks*2]; 
    4726           8 :   fxOverX0LayerTrks = new Float_t[ntracks*6]; 
    4727           8 :   fxTimesRhoLayerTrks = new Float_t[ntracks*6]; 
    4728             : 
    4729         288 :   for(Int_t i=0; i<ntracks; i++) {
    4730         136 :     fxOverX0PipeTrks[i] = -1.;
    4731         136 :     fxTimesRhoPipeTrks[i] = -1.;
    4732             :   }
    4733         560 :   for(Int_t j=0; j<ntracks*2; j++) {
    4734         272 :     fxOverX0ShieldTrks[j] = -1.;
    4735         272 :     fxTimesRhoShieldTrks[j] = -1.;
    4736             :   }
    4737        1648 :   for(Int_t k=0; k<ntracks*6; k++) {
    4738         816 :     fxOverX0LayerTrks[k] = -1.;
    4739         816 :     fxTimesRhoLayerTrks[k] = -1.;
    4740             :   }
    4741             : 
    4742           8 :   fNtracks = ntracks;  
    4743             : 
    4744           8 :   return;
    4745             : }
    4746             : //------------------------------------------------------------------------
    4747             : void AliITStrackerMI::DeleteTrksMaterialLUT() {
    4748             :   //-----------------------------------------------------------------
    4749             :   // Delete LUT for storing material for each prolonged track
    4750             :   //-----------------------------------------------------------------
    4751          20 :   if(fxOverX0PipeTrks) { 
    4752          24 :     delete [] fxOverX0PipeTrks; fxOverX0PipeTrks = 0; 
    4753           8 :   } 
    4754          10 :   if(fxOverX0ShieldTrks) { 
    4755          24 :     delete [] fxOverX0ShieldTrks; fxOverX0ShieldTrks = 0; 
    4756           8 :   } 
    4757             :   
    4758          10 :   if(fxOverX0LayerTrks) { 
    4759          24 :     delete [] fxOverX0LayerTrks;  fxOverX0LayerTrks = 0; 
    4760           8 :   } 
    4761          10 :   if(fxTimesRhoPipeTrks) { 
    4762          24 :     delete [] fxTimesRhoPipeTrks;  fxTimesRhoPipeTrks = 0; 
    4763           8 :   } 
    4764          10 :   if(fxTimesRhoShieldTrks) { 
    4765          24 :     delete [] fxTimesRhoShieldTrks; fxTimesRhoShieldTrks = 0; 
    4766           8 :   } 
    4767          10 :   if(fxTimesRhoLayerTrks) { 
    4768          24 :     delete [] fxTimesRhoLayerTrks; fxTimesRhoLayerTrks = 0; 
    4769           8 :   } 
    4770          10 :   return;
    4771             : }
    4772             : //------------------------------------------------------------------------
    4773             : void AliITStrackerMI::SetForceSkippingOfLayer() {
    4774             :   //-----------------------------------------------------------------
    4775             :   // Check if we are forced to skip layers
    4776             :   // either we set to skip them in RecoParam
    4777             :   // or they were off during data-taking
    4778             :   //-----------------------------------------------------------------
    4779             : 
    4780          16 :   const AliEventInfo *eventInfo = GetEventInfo();
    4781             :   
    4782         112 :   for(Int_t l=0; l<AliITSgeomTGeo::kNLayers; l++) {
    4783          48 :     fForceSkippingOfLayer[l] = 0;
    4784             :     // check reco param
    4785          48 :     if(AliITSReconstructor::GetRecoParam()->GetLayersToSkip(l)) fForceSkippingOfLayer[l] = 1;
    4786             :     // check run info
    4787             : 
    4788          96 :     if(eventInfo && 
    4789          48 :        AliITSReconstructor::GetRecoParam()->GetSkipSubdetsNotInTriggerCluster()) {
    4790         144 :       AliDebug(2,Form("GetEventInfo->GetTriggerCluster: %s",eventInfo->GetTriggerCluster()));
    4791          48 :       if(l==0 || l==1)  {
    4792          16 :         if(!strstr(eventInfo->GetTriggerCluster(),"ITSSPD")) fForceSkippingOfLayer[l] = 1;
    4793          64 :       } else if(l==2 || l==3) {
    4794          48 :         if(!strstr(eventInfo->GetTriggerCluster(),"ITSSDD")) fForceSkippingOfLayer[l] = 1; 
    4795             :       } else {
    4796          16 :         if(!strstr(eventInfo->GetTriggerCluster(),"ITSSSD")) fForceSkippingOfLayer[l] = 1;
    4797             :       } 
    4798             :     }
    4799             :   }
    4800             :   return;
    4801           8 : }
    4802             : //------------------------------------------------------------------------
    4803             : Int_t AliITStrackerMI::CheckSkipLayer(const AliITStrackMI *track,
    4804             :                                       Int_t ilayer,Int_t idet) const {
    4805             :   //-----------------------------------------------------------------
    4806             :   // This method is used to decide whether to allow a prolongation 
    4807             :   // without clusters, because we want to skip the layer.
    4808             :   // In this case the return value is > 0:
    4809             :   // return 1: the user requested to skip a layer
    4810             :   // return 2: track outside z acceptance
    4811             :   //-----------------------------------------------------------------
    4812             : 
    4813       27660 :   if (ForceSkippingOfLayer(ilayer)) return 1;
    4814             : 
    4815             :   Int_t innerLayCanSkip=0; // was 2, changed on 05.11.2009
    4816             : 
    4817       13834 :   if (idet<0 &&  // out in z
    4818           4 :       ilayer>innerLayCanSkip && 
    4819           4 :       AliITSReconstructor::GetRecoParam()->GetExtendedEtaAcceptance()) {
    4820             :     // check if track will cross SPD outer layer
    4821           4 :     Double_t phiAtSPD2,zAtSPD2;
    4822           4 :     if (track->GetPhiZat(fgLayers[1].GetR(),phiAtSPD2,zAtSPD2)) {
    4823           0 :       if (TMath::Abs(zAtSPD2)<2.*AliITSRecoParam::GetSPDdetzlength()) return 2;
    4824             :     }
    4825           4 :     return 2; // always allow skipping, changed on 05.11.2009
    4826           4 :   }
    4827             : 
    4828       13826 :   return 0;
    4829       13830 : }
    4830             : //------------------------------------------------------------------------
    4831             : Int_t AliITStrackerMI::CheckDeadZone(AliITStrackMI *track,
    4832             :                                      Int_t ilayer,Int_t idet,
    4833             :                                      Double_t dz,Double_t dy,
    4834             :                                      Bool_t noClusters) const {
    4835             :   //-----------------------------------------------------------------
    4836             :   // This method is used to decide whether to allow a prolongation 
    4837             :   // without clusters, because there is a dead zone in the road.
    4838             :   // In this case the return value is > 0:
    4839             :   // return 1: dead zone at z=0,+-7cm in SPD
    4840             :   //     This method assumes that fSPDdetzcentre is ordered from -z to +z
    4841             :   // return 2: all road is "bad" (dead or noisy) from the OCDB
    4842             :   // return 3: at least a chip is "bad" (dead or noisy) from the OCDB
    4843             :   // return 4: at least a single channel is "bad" (dead or noisy) from the OCDB
    4844             :   //-----------------------------------------------------------------
    4845             : 
    4846             :   // check dead zones at z=0,+-7cm in the SPD
    4847        6744 :   if (ilayer<2 && !AliITSReconstructor::GetRecoParam()->GetAddVirtualClustersInDeadZone()) {
    4848        7224 :     Double_t zmindead[3]={fSPDdetzcentre[0] + 0.5*AliITSRecoParam::GetSPDdetzlength(),
    4849        2408 :                           fSPDdetzcentre[1] + 0.5*AliITSRecoParam::GetSPDdetzlength(),
    4850        2408 :                           fSPDdetzcentre[2] + 0.5*AliITSRecoParam::GetSPDdetzlength()};
    4851        7224 :     Double_t zmaxdead[3]={fSPDdetzcentre[1] - 0.5*AliITSRecoParam::GetSPDdetzlength(),
    4852        2408 :                           fSPDdetzcentre[2] - 0.5*AliITSRecoParam::GetSPDdetzlength(),
    4853        2408 :                           fSPDdetzcentre[3] - 0.5*AliITSRecoParam::GetSPDdetzlength()};
    4854       16502 :     for (Int_t i=0; i<3; i++)
    4855        9690 :       if (track->GetZ()-dz<zmaxdead[i] && track->GetZ()+dz>zmindead[i]) {
    4856        4344 :         AliDebug(2,Form("crack SPD %d track z %f   %f   %f  %f\n",ilayer,track->GetZ(),dz,zmaxdead[i],zmindead[i]));
    4857        2482 :         if (GetSPDDeadZoneProbability(track->GetZ(),TMath::Sqrt(track->GetSigmaZ2()))>0.1) return 1; 
    4858             :       } 
    4859        3782 :   }
    4860             : 
    4861             :   // check bad zones from OCDB
    4862        3302 :   if (!AliITSReconstructor::GetRecoParam()->GetUseBadZonesFromOCDB()) return 0;
    4863             : 
    4864        3302 :   if (idet<0) return 0;
    4865             : 
    4866        3302 :   AliITSdetector &det=fgLayers[ilayer].GetDetector(idet);  
    4867             : 
    4868             :   Int_t detType=-1;
    4869             :   Float_t detSizeFactorX=0.0001,detSizeFactorZ=0.0001;
    4870        3302 :   if (ilayer==0 || ilayer==1) {        // ----------  SPD
    4871             :     detType = 0;
    4872        3302 :   } else if (ilayer==2 || ilayer==3) { // ----------  SDD
    4873             :     detType = 1;
    4874             :     detSizeFactorX *= 2.;
    4875        1928 :   } else if (ilayer==4 || ilayer==5) { // ----------  SSD
    4876             :     detType = 2;
    4877         836 :   }
    4878        3302 :   AliITSsegmentation *segm = (AliITSsegmentation*)fkDetTypeRec->GetSegmentationModel(detType);
    4879        4138 :   if (detType==2) segm->SetLayer(ilayer+1);
    4880        3302 :   Float_t detSizeX = detSizeFactorX*segm->Dx(); 
    4881        3302 :   Float_t detSizeZ = detSizeFactorZ*segm->Dz(); 
    4882             : 
    4883             :   // check if the road overlaps with bad chips
    4884        3302 :   Float_t xloc,zloc;
    4885        3302 :   if(!(LocalModuleCoord(ilayer,idet,track,xloc,zloc)))return 0;
    4886        3302 :   Float_t zlocmin = zloc-dz;
    4887        3302 :   Float_t zlocmax = zloc+dz;
    4888        3302 :   Float_t xlocmin = xloc-dy;
    4889        3302 :   Float_t xlocmax = xloc+dy;
    4890        3302 :   Int_t chipsInRoad[100]={0};
    4891             : 
    4892             :   // check if road goes out of detector
    4893             :   Bool_t touchNeighbourDet=kFALSE; 
    4894        3567 :   if (TMath::Abs(xlocmin)>0.5*detSizeX) {xlocmin=-0.4999*detSizeX; touchNeighbourDet=kTRUE;} 
    4895        3545 :   if (TMath::Abs(xlocmax)>0.5*detSizeX) {xlocmax=+0.4999*detSizeX; touchNeighbourDet=kTRUE;} 
    4896        4072 :   if (TMath::Abs(zlocmin)>0.5*detSizeZ) {zlocmin=-0.4999*detSizeZ; touchNeighbourDet=kTRUE;} 
    4897        4234 :   if (TMath::Abs(zlocmax)>0.5*detSizeZ) {zlocmax=+0.4999*detSizeZ; touchNeighbourDet=kTRUE;} 
    4898        9906 :   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));
    4899             : 
    4900             :   // check if this detector is bad
    4901        3302 :   if (det.IsBad()) {
    4902         684 :     AliDebug(2,Form("lay %d  bad detector %d",ilayer,idet));
    4903         228 :     if(!touchNeighbourDet) {
    4904         162 :       return 2; // all detectors in road are bad
    4905             :     } else { 
    4906          66 :       return 3; // at least one is bad
    4907             :     }
    4908             :   }
    4909             : 
    4910        3074 :   if(zlocmin>zlocmax)return 0;
    4911        3074 :   Int_t nChipsInRoad = segm->GetChipsInLocalWindow(chipsInRoad,zlocmin,zlocmax,xlocmin,xlocmax);
    4912        9222 :   AliDebug(2,Form("lay %d nChipsInRoad %d",ilayer,nChipsInRoad));
    4913        3076 :   if (!nChipsInRoad) return 0;
    4914             : 
    4915             :   Bool_t anyBad=kFALSE,anyGood=kFALSE;
    4916       17200 :   for (Int_t iCh=0; iCh<nChipsInRoad; iCh++) {
    4917       11056 :     if (chipsInRoad[iCh]<0 || chipsInRoad[iCh]>det.GetNChips()-1) continue;
    4918       16584 :     AliDebug(2,Form("  chip %d bad %d",chipsInRoad[iCh],(Int_t)det.IsChipBad(chipsInRoad[iCh])));
    4919        5528 :     if (det.IsChipBad(chipsInRoad[iCh])) {
    4920             :       anyBad=kTRUE;
    4921          19 :     } else {
    4922             :       anyGood=kTRUE;
    4923             :     } 
    4924             :   }
    4925             : 
    4926        3072 :   if (!anyGood) {
    4927           0 :     if(!touchNeighbourDet) {
    4928           0 :       AliDebug(2,"all bad in road");
    4929           0 :       return 2;  // all chips in road are bad
    4930             :     } else {
    4931           0 :       return 3; // at least a bad chip in road
    4932             :     }
    4933             :   }
    4934             : 
    4935        3072 :   if (anyBad) {
    4936          30 :     AliDebug(2,"at least a bad in road");
    4937          10 :     return 3; // at least a bad chip in road
    4938             :   } 
    4939             : 
    4940             : 
    4941        6124 :   if (!AliITSReconstructor::GetRecoParam()->GetUseSingleBadChannelsFromOCDB()
    4942        8414 :       || !noClusters) return 0;
    4943             : 
    4944             :   // There are no clusters in road: check if there is at least 
    4945             :   // a bad SPD pixel or SDD anode or SSD strips on both sides
    4946             : 
    4947             :   Int_t idetInITS=idet;
    4948        5132 :   for(Int_t l=0;l<ilayer;l++) idetInITS+=AliITSgeomTGeo::GetNLadders(l+1)*AliITSgeomTGeo::GetNDetectors(l+1);
    4949             : 
    4950         772 :   if (fITSChannelStatus->AnyBadInRoad(idetInITS,zlocmin,zlocmax,xlocmin,xlocmax)) {
    4951         630 :     AliDebug(2,Form("Bad channel in det %d of layer %d\n",idet,ilayer));
    4952         210 :     return 4;
    4953             :   }
    4954             :   //if (fITSChannelStatus->FractionOfBadInRoad(idet,zlocmin,zlocmax,xlocmin,xlocmax) > AliITSReconstructor::GetRecoParam()->GetMinFractionOfBadInRoad()) return 3;
    4955             : 
    4956         562 :   return 0;
    4957       10940 : }
    4958             : //------------------------------------------------------------------------
    4959             : Bool_t AliITStrackerMI::LocalModuleCoord(Int_t ilayer,Int_t idet,
    4960             :                                        const AliITStrackMI *track,
    4961             :                                        Float_t &xloc,Float_t &zloc) const {
    4962             :   //-----------------------------------------------------------------
    4963             :   // Gives position of track in local module ref. frame
    4964             :   //-----------------------------------------------------------------
    4965             : 
    4966       37912 :   xloc=0.; 
    4967       18956 :   zloc=0.;
    4968             : 
    4969       18960 :   if(idet<0) return kTRUE; // track out of z acceptance of layer
    4970             : 
    4971       18952 :   Int_t ndet=AliITSgeomTGeo::GetNDetectors(ilayer+1); // layers from 1 to 6 
    4972             : 
    4973       18952 :   Int_t lad = Int_t(idet/ndet) + 1;
    4974             : 
    4975       18952 :   Int_t det = idet - (lad-1)*ndet + 1;
    4976             : 
    4977       18952 :   Double_t xyzGlob[3]={0},xyzLoc[3]={0};
    4978             : 
    4979       18952 :   AliITSdetector &detector = fgLayers[ilayer].GetDetector(idet);
    4980             :   // take into account the misalignment: xyz at real detector plane
    4981       18952 :   if(!track->GetXYZAt(detector.GetRmisal(),GetBz(),xyzGlob)) return kFALSE;
    4982             : 
    4983       18952 :   if(!AliITSgeomTGeo::GlobalToLocal(ilayer+1,lad,det,xyzGlob,xyzLoc)) return kFALSE;
    4984             : 
    4985       18952 :   xloc = (Float_t)xyzLoc[0];
    4986       18952 :   zloc = (Float_t)xyzLoc[2];
    4987             : 
    4988       18952 :   return kTRUE;
    4989       37908 : }
    4990             : //------------------------------------------------------------------------
    4991             : //------------------------------------------------------------------------
    4992             : Bool_t AliITStrackerMI::IsOKForPlaneEff(const AliITStrackMI* track, const Int_t *clusters, Int_t ilayer){
    4993             : //
    4994             : // Method to be optimized further: 
    4995             : // Aim: decide whether a track can be used for PlaneEff evaluation
    4996             : //      the decision is taken based on the track quality at the layer under study
    4997             : //      no information on the clusters on this layer has to be used
    4998             : //      The criterium is to reject tracks at boundaries between basic block (e.g. SPD chip)
    4999             : //      the cut is done on number of sigmas from the boundaries
    5000             : //
    5001             : //  Input: Actual track, layer [0,5] under study
    5002             : //  Output: none
    5003             : //  Return: kTRUE if this is a good track
    5004             : //
    5005             : // it will apply a pre-selection to obtain good quality tracks.  
    5006             : // Here also  you will have the possibility to put a control on the 
    5007             : // impact point of the track on the basic block, in order to exclude border regions 
    5008             : // this will be done by calling a proper method of the AliITSPlaneEff class.  
    5009             : //
    5010             : // input: AliITStrackMI* track, ilayer= layer number [0,5]
    5011             : // return: Bool_t   -> kTRUE if usable track, kFALSE if not usable. 
    5012             : //
    5013           0 :   Int_t index[AliITSgeomTGeo::kNLayers]={0};
    5014             :   Int_t k;
    5015           0 :   for (k=0; k<AliITSgeomTGeo::GetNLayers(); k++) index[k]=-1;
    5016             :   //
    5017           0 :   for (k=0; k<AliITSgeomTGeo::GetNLayers(); k++) {
    5018           0 :     index[k]=clusters[k];
    5019             :   }
    5020             : 
    5021           0 :   if(!fPlaneEff)
    5022           0 :     {AliWarning("IsOKForPlaneEff: null pointer to AliITSPlaneEff"); return kFALSE;}
    5023           0 :   AliITSlayer &layer=fgLayers[ilayer];
    5024           0 :   Double_t r=layer.GetR();
    5025           0 :   AliITStrackMI tmp(*track);
    5026             : 
    5027             : // require a minimal number of cluster in other layers and eventually clusters in closest layers 
    5028             :   Int_t nclout=0; Int_t nclin=0;
    5029           0 :   for(Int_t lay=AliITSgeomTGeo::kNLayers-1;lay>ilayer;lay--) { // count n. of cluster in outermost layers
    5030           0 :  AliDebug(2,Form("trak=%d  lay=%d  ; index=%d ESD label= %d",tmp.GetLabel(),lay,
    5031             :                     tmp.GetClIndex(lay),((AliESDtrack*)tmp.GetESDtrack())->GetLabel())) ;
    5032             :    // if (tmp.GetClIndex(lay)>=0) nclout++;
    5033           0 : if(index[lay]>=0)nclout++;
    5034             :   }
    5035           0 :   for(Int_t lay=ilayer-1; lay>=0;lay--) { // count n. of cluster in innermost layers
    5036           0 :     AliDebug(2,Form("trak=%d  lay=%d  ; index=%d ESD label= %d",tmp.GetLabel(),lay,
    5037             :                     tmp.GetClIndex(lay),((AliESDtrack*)tmp.GetESDtrack())->GetLabel())) ;
    5038           0 :    if (index[lay]>=0) nclin++; 
    5039             :   }
    5040           0 :   Int_t ncl=nclout+nclin;
    5041             :   Bool_t nextout = kFALSE;
    5042           0 :   if(ilayer==AliITSgeomTGeo::kNLayers-1) nextout=kTRUE; // you are already on the outermost layer
    5043           0 :   else nextout = ((tmp.GetClIndex(ilayer+1)>=0)? kTRUE : kFALSE );
    5044             :   Bool_t nextin = kFALSE;
    5045           0 :   if(ilayer==0) nextin=kTRUE; // you are already on the innermost layer
    5046           0 :   else nextin = ((index[ilayer-1]>=0)? kTRUE : kFALSE );
    5047             :   // maximum number of missing clusters allowed in outermost layers
    5048           0 :   if(nclout<AliITSgeomTGeo::kNLayers-(ilayer+1)-AliITSReconstructor::GetRecoParam()->GetMaxMissingClustersOutPlaneEff()) 
    5049           0 :      return kFALSE; 
    5050             :   // maximum number of missing clusters allowed (both in innermost and in outermost layers)
    5051           0 :   if(ncl<AliITSgeomTGeo::kNLayers-1-AliITSReconstructor::GetRecoParam()->GetMaxMissingClustersPlaneEff()) 
    5052           0 :      return kFALSE; 
    5053           0 :   if(AliITSReconstructor::GetRecoParam()->GetRequireClusterInOuterLayerPlaneEff() && !nextout)  return kFALSE;
    5054           0 :   if(AliITSReconstructor::GetRecoParam()->GetRequireClusterInInnerLayerPlaneEff() && !nextin)   return kFALSE;
    5055           0 :   if(tmp.Pt() < AliITSReconstructor::GetRecoParam()->GetMinPtPlaneEff()) return kFALSE;
    5056             :  //  if(AliITSReconstructor::GetRecoParam()->GetOnlyConstraintPlaneEff()  && !tmp.GetConstrain()) return kFALSE;
    5057             : 
    5058             : // detector number
    5059           0 :   Double_t phi,z;
    5060           0 :   if (!tmp.GetPhiZat(r,phi,z)) return kFALSE;
    5061           0 :   Int_t idet=layer.FindDetectorIndex(phi,z);
    5062           0 :   if(idet<0) { AliInfo(Form("cannot find detector"));
    5063           0 :     return kFALSE;}
    5064             : 
    5065             :   // here check if it has good Chi Square.
    5066             : 
    5067             :   //propagate to the intersection with the detector plane
    5068           0 :   const AliITSdetector &det=layer.GetDetector(idet);
    5069           0 :   if (!tmp.Propagate(det.GetPhi(),det.GetR())) return kFALSE;
    5070             : 
    5071           0 :   Float_t locx; //
    5072           0 :   Float_t locz; //
    5073           0 :   if(!LocalModuleCoord(ilayer,idet,&tmp,locx,locz)) return kFALSE;
    5074           0 :   UInt_t key=fPlaneEff->GetKeyFromDetLocCoord(ilayer,idet,locx,locz);
    5075           0 :   if(key>fPlaneEff->Nblock()) return kFALSE;
    5076           0 :   Float_t blockXmn,blockXmx,blockZmn,blockZmx;
    5077           0 :   if (!fPlaneEff->GetBlockBoundaries(key,blockXmn,blockXmx,blockZmn,blockZmx)) return kFALSE;
    5078             :   //***************
    5079             :   // DEFINITION OF SEARCH ROAD FOR accepting a track
    5080             :   //
    5081           0 :   Double_t nsigx=AliITSReconstructor::GetRecoParam()->GetNSigXFromBoundaryPlaneEff();
    5082           0 :   Double_t nsigz=AliITSReconstructor::GetRecoParam()->GetNSigZFromBoundaryPlaneEff();
    5083           0 :   Double_t distx=AliITSReconstructor::GetRecoParam()->GetDistXFromBoundaryPlaneEff();
    5084           0 :   Double_t distz=AliITSReconstructor::GetRecoParam()->GetDistZFromBoundaryPlaneEff();
    5085           0 :   Double_t dx=nsigx*TMath::Sqrt(tmp.GetSigmaY2()) + distx;
    5086             :   // those are precisions in the tracking reference system
    5087           0 :   Double_t dz=nsigz*TMath::Sqrt(tmp.GetSigmaZ2()) + distz;
    5088             :   // Use it also for the module reference system, as it is done for RecPoints
    5089             : 
    5090           0 :   if(AliITSReconstructor::GetRecoParam()->GetSwitchOnMaxDistNSigFrmBndPlaneEff()){
    5091           0 :    if(nsigx*TMath::Sqrt(tmp.GetSigmaY2())<=distx) dx -= nsigx*TMath::Sqrt(tmp.GetSigmaY2());
    5092           0 :    else dx -= distx;
    5093             : 
    5094           0 :    if(nsigz*TMath::Sqrt(tmp.GetSigmaZ2())<=distz) dz -= nsigz*TMath::Sqrt(tmp.GetSigmaZ2());
    5095           0 :    else dz -= distz;
    5096             :   }
    5097             : 
    5098             :   // exclude tracks at boundary between detectors
    5099             :   //Double_t boundaryWidth=AliITSRecoParam::GetBoundaryWidthPlaneEff();
    5100             :   Double_t boundaryWidth=0; // for the time being hard-wired, later on from AliITSRecoParam
    5101           0 :   AliDebug(2,Form("Tracking: track impact x=%f, y=%f, z=%f",tmp.GetX(), tmp.GetY(), tmp.GetZ()));
    5102           0 :   AliDebug(2,Form("Local:    track impact x=%f, z=%f",locx,locz));
    5103           0 :   AliDebug(2,Form("Search Road. Tracking: dy=%f , dz=%f",dx,dz));
    5104           0 :   if ( (locx-dx < blockXmn+boundaryWidth) ||
    5105           0 :        (locx+dx > blockXmx-boundaryWidth) ||
    5106           0 :        (locz-dz < blockZmn+boundaryWidth) ||
    5107           0 :        (locz+dz > blockZmx-boundaryWidth) ) return kFALSE;
    5108             : 
    5109           0 :   if(ilayer==0){
    5110           0 :        const AliESDEvent *myesd = ((AliESDtrack*)tmp.GetESDtrack())->GetESDEvent();
    5111             :        //The beam pipe
    5112           0 :        if (CorrectForPipeMaterial(&tmp,"inward")) {
    5113           0 :           const AliESDVertex* vtx = myesd->GetVertex();
    5114           0 :           if(!vtx) return kFALSE;
    5115           0 :           Double_t ddz[2]={0},cov[3]={0};
    5116             :           Double_t maxD=3.;
    5117           0 :           if(!tmp.PropagateToDCA(vtx,AliTracker::GetBz(),maxD,ddz,cov)) return kFALSE;
    5118           0 :           if(TMath::Abs(ddz[0])>=AliITSReconstructor::GetRecoParam()->GetDCACutPlaneEff()) return kFALSE;
    5119             : 
    5120           0 :           Double_t covar[6]; vtx->GetCovMatrix(covar);
    5121           0 :           Double_t p[2]={tmp.GetParameter()[0]-ddz[0],tmp.GetParameter()[1]-ddz[1]};
    5122           0 :           Double_t c[3]={covar[2],0.,covar[5]};
    5123           0 :           Double_t chi2= ((AliESDtrack*)tmp.GetESDtrack())->GetPredictedChi2(p,c);
    5124           0 :           if (chi2>AliITSReconstructor::GetRecoParam()->GetVertexChi2CutPlaneEff()) return kFALSE;  // Use this to cut on chi^2
    5125             : 
    5126           0 :        } else return kFALSE;
    5127           0 :     }
    5128             : 
    5129             : 
    5130           0 :   return kTRUE;
    5131           0 : }
    5132             : //------------------------------------------------------------------------
    5133             : void AliITStrackerMI::UseTrackForPlaneEff(const AliITStrackMI* track, Int_t ilayer) {
    5134             : //
    5135             : // This Method has to be optimized! For the time-being it uses the same criteria
    5136             : // as those used in the search of extra clusters for overlapping modules.
    5137             : //
    5138             : // Method Purpose: estabilish whether a track has produced a recpoint or not
    5139             : //                 in the layer under study (For Plane efficiency)
    5140             : //
    5141             : // inputs: AliITStrackMI* track  (pointer to a usable track)
    5142             : // outputs: none
    5143             : // side effects: update (by 1 count) the Plane Efficiency statistics of the basic block
    5144             : //               traversed by this very track. In details:
    5145             : //               - if a cluster can be associated to the track then call
    5146             : //                  AliITSPlaneEff::UpDatePlaneEff(key,kTRUE);
    5147             : //               - if not, the AliITSPlaneEff::UpDatePlaneEff(key,kFALSE) is called
    5148             : //
    5149           0 :   if(!fPlaneEff)
    5150           0 :     {AliWarning("UseTrackForPlaneEff: null pointer to AliITSPlaneEff"); return;}
    5151           0 :   AliITSlayer &layer=fgLayers[ilayer];
    5152           0 :   Double_t r=layer.GetR();
    5153           0 :   AliITStrackMI tmp(*track);
    5154             : 
    5155             : // detector number
    5156           0 :   Double_t phi,z;
    5157           0 :   if (!tmp.GetPhiZat(r,phi,z)) return;
    5158           0 :   Int_t idet=layer.FindDetectorIndex(phi,z);
    5159             : 
    5160           0 :   if(idet<0) { AliInfo(Form("cannot find detector"));
    5161           0 :     return;}
    5162             : 
    5163             : 
    5164             : //propagate to the intersection with the detector plane
    5165           0 :   const AliITSdetector &det=layer.GetDetector(idet);
    5166           0 :   if (!tmp.Propagate(det.GetPhi(),det.GetR())) return;
    5167             : 
    5168             : 
    5169             : //***************
    5170             : // DEFINITION OF SEARCH ROAD FOR CLUSTERS SELECTION
    5171             : //
    5172           0 :   Double_t dz=AliITSReconstructor::GetRecoParam()->GetNSigmaRoadZ()*
    5173           0 :                     TMath::Sqrt(tmp.GetSigmaZ2() +
    5174           0 :                     AliITSReconstructor::GetRecoParam()->GetNSigmaZLayerForRoadZ()*
    5175           0 :                     AliITSReconstructor::GetRecoParam()->GetNSigmaZLayerForRoadZ()*
    5176           0 :                     AliITSReconstructor::GetRecoParam()->GetSigmaZ2(ilayer));
    5177           0 :   Double_t dy=AliITSReconstructor::GetRecoParam()->GetNSigmaRoadY()*
    5178           0 :                     TMath::Sqrt(tmp.GetSigmaY2() +
    5179           0 :                     AliITSReconstructor::GetRecoParam()->GetNSigmaYLayerForRoadY()*
    5180           0 :                     AliITSReconstructor::GetRecoParam()->GetNSigmaYLayerForRoadY()*
    5181           0 :                     AliITSReconstructor::GetRecoParam()->GetSigmaY2(ilayer));
    5182             : 
    5183             : // road in global (rphi,z) [i.e. in tracking ref. system]
    5184           0 :   Double_t zmin = tmp.GetZ() - dz;
    5185           0 :   Double_t zmax = tmp.GetZ() + dz;
    5186           0 :   Double_t ymin = tmp.GetY() + r*det.GetPhi() - dy;
    5187           0 :   Double_t ymax = tmp.GetY() + r*det.GetPhi() + dy;
    5188             : 
    5189             : // select clusters in road
    5190           0 :   layer.SelectClusters(zmin,zmax,ymin,ymax);
    5191             : 
    5192             : // Define criteria for track-cluster association
    5193           0 :   Double_t msz = tmp.GetSigmaZ2() +
    5194           0 :   AliITSReconstructor::GetRecoParam()->GetNSigmaZLayerForRoadZ()*
    5195           0 :   AliITSReconstructor::GetRecoParam()->GetNSigmaZLayerForRoadZ()*
    5196           0 :   AliITSReconstructor::GetRecoParam()->GetSigmaZ2(ilayer);
    5197           0 :   Double_t msy = tmp.GetSigmaY2() +
    5198           0 :   AliITSReconstructor::GetRecoParam()->GetNSigmaYLayerForRoadY()*
    5199           0 :   AliITSReconstructor::GetRecoParam()->GetNSigmaYLayerForRoadY()*
    5200           0 :   AliITSReconstructor::GetRecoParam()->GetSigmaY2(ilayer);
    5201           0 :   if (tmp.GetConstrain()) {
    5202           0 :     msz *= AliITSReconstructor::GetRecoParam()->GetNSigma2RoadZC();
    5203           0 :     msy *= AliITSReconstructor::GetRecoParam()->GetNSigma2RoadYC();
    5204           0 :   }  else {
    5205           0 :     msz *= AliITSReconstructor::GetRecoParam()->GetNSigma2RoadZNonC();
    5206           0 :     msy *= AliITSReconstructor::GetRecoParam()->GetNSigma2RoadYNonC();
    5207             :   }
    5208             : 
    5209           0 :   if(AliITSReconstructor::GetRecoParam()->GetSwitchOffStdSearchClusPlaneEff()){
    5210           0 :      Double_t nsigx=AliITSReconstructor::GetRecoParam()->GetNSigXSearchClusterPlaneEff();
    5211           0 :      Double_t nsigz=AliITSReconstructor::GetRecoParam()->GetNSigZSearchClusterPlaneEff();
    5212           0 :      Double_t distx=AliITSReconstructor::GetRecoParam()->GetDistXSearchClusterPlaneEff();
    5213           0 :      Double_t distz=AliITSReconstructor::GetRecoParam()->GetDistZSearchClusterPlaneEff();
    5214           0 :      msy = nsigx*TMath::Sqrt(tmp.GetSigmaY2()) + distx;
    5215           0 :      msz = nsigz*TMath::Sqrt(tmp.GetSigmaZ2()) + distz;
    5216             : 
    5217           0 :   if(AliITSReconstructor::GetRecoParam()->GetSwitchOnMaxDistNSigSrhClusPlaneEff()){
    5218           0 :      if(nsigx*TMath::Sqrt(tmp.GetSigmaY2())<=distx) msy -= nsigx*TMath::Sqrt(tmp.GetSigmaY2());
    5219           0 :      else msy -= distx;
    5220             : 
    5221           0 :      if(nsigz*TMath::Sqrt(tmp.GetSigmaZ2())<=distz) msz -= nsigz*TMath::Sqrt(tmp.GetSigmaZ2());
    5222           0 :      else msz -= distz;
    5223             :   }
    5224             : 
    5225           0 :   msy *= msy;
    5226           0 :   msz *= msz;
    5227             : 
    5228           0 :   }
    5229             : 
    5230           0 :   if(msz==0 || msy==0){AliWarning("UseTrackForPlaneEff: null search frame"); return;}
    5231             :     
    5232           0 :   msz = 1./msz; // 1/RoadZ^2
    5233           0 :   msy = 1./msy; // 1/RoadY^2
    5234             : 
    5235           0 :   const AliITSRecPoint *cl=0; Int_t clidx=-1, ci=-1;
    5236             :   Int_t idetc=-1;
    5237           0 :   Double_t chi2trkcl=1000.*AliITSReconstructor::GetRecoParam()->GetMaxChi2();
    5238             :   //Double_t  tolerance=0.2;
    5239             :   /*while ((cl=layer.GetNextCluster(clidx))!=0) {
    5240             :     idetc = cl->GetDetectorIndex();
    5241             :     if(idet!=idetc) continue;
    5242             :     //Int_t ilay = cl->GetLayer();
    5243             : 
    5244             :     if (TMath::Abs(tmp.GetZ() - cl->GetZ()) > tolerance) continue;
    5245             :     if (TMath::Abs(tmp.GetY() - cl->GetY()) > tolerance) continue;
    5246             : 
    5247             :     Double_t chi2=tmp.GetPredictedChi2(cl);
    5248             :     if (chi2<chi2trkcl) { chi2trkcl=chi2; ci=clidx; }
    5249             :   }*/
    5250           0 :   Float_t locx; //
    5251           0 :   Float_t locz; //
    5252           0 :   if(!LocalModuleCoord(ilayer,idet,&tmp,locx,locz)) return;
    5253             : //
    5254           0 :   AliDebug(2,Form("ilayer= %d, idet=%d, x= %f, z=%f",ilayer,idet,locx,locz));
    5255           0 :   UInt_t key=fPlaneEff->GetKeyFromDetLocCoord(ilayer,idet,locx,locz);
    5256           0 :   if(key>fPlaneEff->Nblock()) return;
    5257             :   Bool_t found=kFALSE;
    5258             :   //if (ci>=0) {
    5259             :   Double_t chi2;
    5260           0 :   while ((cl=layer.GetNextCluster(clidx))!=0) {
    5261           0 :     idetc = cl->GetDetectorIndex();
    5262           0 :     if(idet!=idetc) continue;
    5263             :     // here real control to see whether the cluster can be associated to the track.
    5264             :     // cluster not associated to track
    5265           0 :     if ( (tmp.GetZ()-cl->GetZ())*(tmp.GetZ()-cl->GetZ())*msz +
    5266           0 :          (tmp.GetY()-cl->GetY())*(tmp.GetY()-cl->GetY())*msy   > 1. ) continue;
    5267             :     // calculate track-clusters chi2
    5268           0 :     chi2 = GetPredictedChi2MI(&tmp,cl,ilayer); // note that this method change track tmp
    5269             :                                                // in particular, the error associated to the cluster 
    5270             :     //Double_t chi2 = tmp.GetPredictedChi(cl); // this method does not change track tmp
    5271             :     // chi2 cut
    5272           0 :     if (chi2 > AliITSReconstructor::GetRecoParam()->GetMaxChi2s(ilayer)) continue;
    5273             :     found=kTRUE;
    5274           0 :     if (chi2<chi2trkcl) { chi2trkcl=chi2; ci=clidx; } // this just to trace which cluster is selected
    5275             :    // track->SetExtraCluster(ilayer,(ilayer<<28)+ci);
    5276             :    // track->SetExtraModule(ilayer,idetExtra);
    5277             :   }
    5278           0 :   if(!fPlaneEff->UpDatePlaneEff(found,key))
    5279           0 :        AliWarning(Form("UseTrackForPlaneEff: cannot UpDate PlaneEff for key=%d",key));
    5280             : 
    5281             : // this for FO efficiency studies (only for SPD) // 
    5282             :    UInt_t keyFO=999999;
    5283             :    Bool_t foundFO=kFALSE;
    5284           0 :    if(ilayer<2){ //ONLY SPD layers for FastOr studies
    5285           0 :     TBits mapFO = fkDetTypeRec->GetFastOrFiredMap();
    5286           0 :     Int_t phase = (fEsd->GetBunchCrossNumber())%4;
    5287           0 :     if(!fSPDChipIntPlaneEff[key]){
    5288           0 :       AliITSPlaneEffSPD spd; 
    5289           0 :       keyFO = spd.SwitchChipKeyNumbering(key);
    5290           0 :       if(mapFO.TestBitNumber(keyFO))foundFO=kTRUE;
    5291           0 :        keyFO = key + (AliITSPlaneEffSPD::kNModule*AliITSPlaneEffSPD::kNChip)*(phase+1);
    5292           0 :        if(keyFO<AliITSPlaneEffSPD::kNModule*AliITSPlaneEffSPD::kNChip) {
    5293           0 :          AliWarning(Form("UseTrackForPlaneEff: too small keyF0 (= %d), setting it to 999999",keyFO));
    5294             :          keyFO=999999;
    5295           0 :        }
    5296           0 :        if(!fPlaneEff->UpDatePlaneEff(foundFO,keyFO))
    5297           0 :           AliWarning(Form("UseTrackForPlaneEff: cannot UpDate PlaneEff for FastOR for key=%d",keyFO));
    5298           0 :      }
    5299           0 :   }
    5300             :   
    5301             : 
    5302             : 
    5303           0 :   if(fPlaneEff->GetCreateHistos()&&  AliITSReconstructor::GetRecoParam()->GetHistoPlaneEff()) {
    5304           0 :     Float_t tr[4]={99999.,99999.,9999.,9999.};    // initialize to high values 
    5305           0 :     Float_t clu[4]={-99999.,-99999.,9999.,9999.}; // (in some cases GetCov fails) 
    5306           0 :     Int_t cltype[2]={-999,-999};
    5307             :                                                           // and the module
    5308             : 
    5309           0 :     Float_t angleModTrack[3]={99999.,99999.,99999.}; // angles (phi, z and "absolute angle") between the track and the mormal to the module (see below)
    5310             : 
    5311           0 :     tr[0]=locx;
    5312           0 :     tr[1]=locz;
    5313           0 :     tr[2]=TMath::Sqrt(tmp.GetSigmaY2());  // those are precisions in the tracking reference system
    5314           0 :     tr[3]=TMath::Sqrt(tmp.GetSigmaZ2());  // Use it also for the module reference system, as it is
    5315             : 
    5316           0 :     if (found){
    5317           0 :       clu[0]=layer.GetCluster(ci)->GetDetLocalX();
    5318           0 :       clu[1]=layer.GetCluster(ci)->GetDetLocalZ();
    5319           0 :       cltype[0]=layer.GetCluster(ci)->GetNy();
    5320           0 :       cltype[1]=layer.GetCluster(ci)->GetNz();
    5321             :      
    5322             :      // Without the following 6 lines you would retrieve the nominal error of a cluster (e.g. for the SPD:
    5323             :      //  X->50/sqrt(12)=14 micron   Z->450/sqrt(12)= 120 micron) 
    5324             :      // Within AliTrackerMI/AliTrackMI the error on the cluster is associated to the AliITStrackMI (fSigmaY,Z)
    5325             :      // It is computed properly by calling the method 
    5326             :      // AliITStrackerMI::GetPredictedChi2MI(AliITStrackMI* track, const AliITSRecPoint *cluster,Int_t layer)
    5327             :      // T
    5328             :      //Double_t x=0.5*(tmp.GetX()+layer.GetCluster(ci)->GetX()); // Take into account the mis-alignment
    5329             :       //if (tmp.PropagateTo(x,0.,0.)) {
    5330           0 :         chi2=GetPredictedChi2MI(&tmp,layer.GetCluster(ci),ilayer);
    5331           0 :         AliCluster c(*layer.GetCluster(ci));
    5332           0 :         c.SetSigmaY2(tmp.GetSigmaY(ilayer)*tmp.GetSigmaY(ilayer));
    5333           0 :         c.SetSigmaZ2(tmp.GetSigmaZ(ilayer)*tmp.GetSigmaZ(ilayer));
    5334             :         //if (layer.GetCluster(ci)->GetGlobalCov(cov))  // by using this, instead, you got nominal cluster errors
    5335           0 :         clu[2]=TMath::Sqrt(c.GetSigmaY2());
    5336           0 :         clu[3]=TMath::Sqrt(c.GetSigmaZ2());
    5337             :       //}
    5338           0 :     }
    5339             :   // Compute the angles between the track and the module
    5340             :       // compute the angle "in phi direction", i.e. the angle in the transverse plane 
    5341             :       // between the normal to the module and the projection (in the transverse plane) of the 
    5342             :       // track trajectory
    5343             :     // tgphi and tglambda of the track in tracking frame with alpha=det.GetPhi
    5344           0 :     Float_t tgl = tmp.GetTgl();
    5345           0 :     Float_t phitr   = tmp.GetSnp();
    5346           0 :     phitr = TMath::ASin(phitr);
    5347           0 :     Int_t volId = AliGeomManager::LayerToVolUIDSafe(ilayer+1 ,idet );
    5348             : 
    5349           0 :     Double_t tra[3]={0}; AliGeomManager::GetOrigTranslation(volId,tra);
    5350           0 :     Double_t rot[9]={0}; AliGeomManager::GetOrigRotation(volId,rot);
    5351             :    Double_t alpha =0.;
    5352           0 :     alpha = tmp.GetAlpha();
    5353           0 :     Double_t phiglob = alpha+phitr;
    5354             :     Double_t p[3]={0};
    5355           0 :     p[0] = TMath::Cos(phiglob);
    5356           0 :     p[1] = TMath::Sin(phiglob);
    5357           0 :     p[2] = tgl;
    5358           0 :     TVector3 pvec(p[0],p[1],p[2]);
    5359           0 :     TVector3 normvec(rot[1],rot[4],rot[7]);
    5360           0 :     Double_t angle = pvec.Angle(normvec);
    5361             : 
    5362           0 :     if(angle>0.5*TMath::Pi()) angle = (TMath::Pi()-angle);
    5363           0 :     angle *= 180./TMath::Pi();
    5364             : 
    5365             :     //Trasverse Plane
    5366           0 :     TVector3 pt(p[0],p[1],0);
    5367           0 :     TVector3 normt(rot[1],rot[4],0);
    5368           0 :     Double_t anglet = pt.Angle(normt);
    5369             : 
    5370           0 :     Double_t phiPt = TMath::ATan2(p[1],p[0]);
    5371           0 :     if(phiPt<0)phiPt+=2.*TMath::Pi();
    5372           0 :     Double_t phiNorm = TMath::ATan2(rot[4],rot[1]);
    5373           0 :     if(phiNorm<0) phiNorm+=2.*TMath::Pi();
    5374           0 :     if(anglet>0.5*TMath::Pi()) anglet = (TMath::Pi()-anglet);
    5375           0 :     if(phiNorm>phiPt) anglet*=-1.;// pt-->normt  clockwise: anglet>0
    5376           0 :     if((phiNorm-phiPt)>TMath::Pi()) anglet*=-1.;
    5377           0 :     anglet *= 180./TMath::Pi();
    5378             : 
    5379           0 :      angleModTrack[2]=(Float_t) angle;
    5380           0 :      angleModTrack[0]=(Float_t) anglet;
    5381             :      // now the "angle in z" (much easier, i.e. the angle between the z axis and the track momentum + 90)
    5382           0 :     angleModTrack[1]=TMath::ACos(tgl/TMath::Sqrt(tgl*tgl+1.));
    5383           0 :     angleModTrack[1]-=TMath::Pi()/2.; // range of angle is -pi/2 , pi/2
    5384           0 :     angleModTrack[1]*=180./TMath::Pi(); // in degree
    5385             : 
    5386           0 :     fPlaneEff->FillHistos(key,found,tr,clu,cltype,angleModTrack);
    5387             : 
    5388             :     // For FO efficiency studies of SPD 
    5389           0 :     if(ilayer<2 && !fSPDChipIntPlaneEff[key]) fPlaneEff->FillHistos(keyFO,foundFO,tr,clu,cltype,angleModTrack);
    5390           0 :   }
    5391           0 :   if(ilayer<2) fSPDChipIntPlaneEff[key]=kTRUE;
    5392             : return;
    5393           0 : }
    5394             : 
    5395             : Int_t AliITStrackerMI::FindClusterOfTrack(int label, int lr, int* store) const //RS
    5396             : {
    5397             :   // find the MC cluster for the label
    5398           0 :   return fgLayers[lr].FindClusterForLabel(label,store);
    5399             : }
    5400             : 
    5401             : /*
    5402             : Int_t AliITStrackerMI::GetPattern(const AliITStrackMI* track, char* patt)
    5403             : {
    5404             :   // creates pattarn of hits marking fake/corrects by f/c. Used for debugging (RS) 
    5405             :   strncpy(patt,"......",6); 
    5406             :   int tpcLabel = 0;
    5407             :   if (track->GetESDtrack()) tpcLabel = track->GetESDtrack()->GetTPCLabel();
    5408             :   //
    5409             :   int nwrong = 0;
    5410             :   for (Int_t i=0;i<track->GetNumberOfClusters();i++){
    5411             :     Int_t cindex = track->GetClusterIndex(i);
    5412             :     Int_t l=(cindex & 0xf0000000) >> 28;
    5413             :     AliITSRecPoint *cl = (AliITSRecPoint*)GetCluster(cindex);
    5414             :     Int_t isWrong=1;
    5415             :     for (Int_t ind=0;ind<3;ind++) if (cl->GetLabel(ind)==TMath::Abs(tpcLabel)) isWrong=0;
    5416             :     patt[l] = isWrong ? 'f':'c';
    5417             :     nwrong+=isWrong;
    5418             :   }
    5419             :   return nwrong;
    5420             : }
    5421             : */
    5422             : //------------------------------------------------------------------------
    5423             : Int_t AliITStrackerMI::AliITSlayer::FindClusterForLabel(Int_t label, Int_t *store) const
    5424             : { //RS
    5425             :   //--------------------------------------------------------------------
    5426             : 
    5427             :   int nfound = 0;
    5428           0 :   for (int ic=0;ic<fN;ic++) {
    5429           0 :     const AliITSRecPoint *cl = GetCluster(ic);
    5430           0 :     for (int i=0;i<3;i++) if (cl->GetLabel(i)==label) {
    5431           0 :         if (nfound<50) {
    5432           0 :           if (store) store[nfound] = ic;
    5433           0 :           nfound++;
    5434           0 :         }
    5435           0 :         break;
    5436             :       }
    5437             :   }
    5438           0 :   return nfound;
    5439             : }
    5440             : 

Generated by: LCOV version 1.11