LCOV - code coverage report
Current view: top level - HMPID/HMPIDrec - AliHMPIDReconHTA.cxx (source / functions) Hit Total Coverage
Test: coverage.info Lines: 0 438 0.0 %
Date: 2016-06-14 17:26:59 Functions: 0 22 0.0 %

          Line data    Source code
       1             : /**************************************************************************
       2             :  * Copyright(c) 1998-1999, 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             : 
      16             : //////////////////////////////////////////////////////////////////////////
      17             : //                                                                      //
      18             : // AliHMPIDReconHTA                                                         //
      19             : //                                                                      //
      20             : // HMPID class to perfom pattern recognition based on Hough transfrom    //
      21             : // for single chamber                                                   //
      22             : //////////////////////////////////////////////////////////////////////////
      23             : 
      24             : #include "AliHMPIDReconHTA.h"//class header
      25             : #include "AliHMPIDCluster.h" //CkovHiddenTrk()
      26             : #include "AliHMPIDRecon.h"   //FunMinPhot()
      27             : #include <TFile.h>           //Database()
      28             : #include <TMinuit.h>         //FitFree()
      29             : #include <TClonesArray.h>    //CkovHiddenTrk()
      30             : #include <AliESDtrack.h>     //CkovHiddenTrk()
      31             : #include <TH2F.h>            //InitDatabase()
      32             : #include <TGraph.h>          //ShapeModel()
      33             : #include <TSpline.h>         //ShapeModel()
      34             : #include <TCanvas.h>         //ShapeModel()
      35             : #include "TStopwatch.h"      //
      36             : 
      37             : Int_t AliHMPIDReconHTA::fgDB[500][150]={{75000*0}};
      38             : //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
      39             : AliHMPIDReconHTA::AliHMPIDReconHTA():
      40           0 :   TNamed("RichRec","RichPat"),
      41           0 :   fMipX(-999),
      42           0 :   fMipY(-999),
      43           0 :   fMipQ(-999),
      44           0 :   fRadX(-999),
      45           0 :   fRadY(-999),
      46           0 :   fIdxMip(0),
      47           0 :   fNClu(0),
      48           0 :   fXClu(0),
      49           0 :   fYClu(0),
      50           0 :   fPhiPhot(0),
      51           0 :   fThetaPhot(0),
      52           0 :   fClCk(0),
      53           0 :   fThTrkIn(-999),
      54           0 :   fPhTrkIn(-999),
      55           0 :   fThTrkFit(-999),
      56           0 :   fPhTrkFit(-999),
      57           0 :   fCkovFit(-999),
      58           0 :   fNCluFit(0),
      59           0 :   fCkovSig2(0),
      60           0 :   fFitStatus(0),
      61           0 :   fParam(AliHMPIDParam::Instance())
      62           0 : {
      63             : //..
      64             : //hidden algorithm
      65             : //..
      66           0 :   fParam->SetRefIdx(fParam->MeanIdxRad()); // initialization of ref index to a default one
      67           0 :   InitDatabase();
      68           0 : }
      69             : //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
      70             : AliHMPIDReconHTA::~AliHMPIDReconHTA()
      71           0 : {
      72           0 :   DeleteVars();
      73           0 : }
      74             : //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
      75             : void AliHMPIDReconHTA::InitVars(Int_t n)
      76             : {
      77             : //..
      78             : //Init some variables
      79             : //..
      80           0 :   fXClu = new Double_t[n];
      81           0 :   fYClu = new Double_t[n];
      82           0 :   fPhiPhot = new Double_t[n];
      83           0 :   fThetaPhot = new Double_t[n];
      84           0 :   fClCk = new Bool_t[n];
      85           0 :   for(Int_t i=0;i<n;i++) fClCk[i] = kTRUE;
      86             : //
      87           0 : }
      88             : //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
      89             : void AliHMPIDReconHTA::DeleteVars()const
      90             : {
      91             : //..
      92             : //Delete variables
      93             : //..
      94           0 :   if(fXClu) delete [] fXClu;
      95           0 :   if(fYClu) delete [] fYClu;
      96           0 :   if(fPhiPhot) delete [] fPhiPhot;
      97           0 :   if(fThetaPhot) delete [] fThetaPhot;
      98           0 :   if(fClCk) delete [] fClCk;
      99           0 : }
     100             : //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
     101             : Bool_t AliHMPIDReconHTA::CkovHiddenTrk(AliESDtrack *pTrk,TClonesArray *pCluLst,Int_t index, Double_t nmean)
     102             : {
     103             : // Pattern recognition method without any infos from tracking:HTA (Hidden Track Algorithm)...
     104             : // The method finds in the chmuber the cluster with the highest charge
     105             : // compatibile with a MIP, then the strategy is applied
     106             : // Arguments:  pTrk     - pointer to ESD track
     107             : //             pCluLs   - list of clusters for a given chamber 
     108             : //             pNmean   - pointer to ref. index
     109             : //             pQthre   - pointer to qthre
     110             : //   Returns:           - 0=ok,1=not fitted 
     111             :   
     112           0 :   AliHMPIDParam *pParam = AliHMPIDParam::Instance(); 
     113             : 
     114           0 :   if(!CluPreFilter(pCluLst)) return kFALSE;
     115             : 
     116             :   Int_t nCh=0;
     117             :   Int_t sizeClu=0;
     118             :   
     119           0 :   fNClu = pCluLst->GetEntriesFast();
     120             :     
     121           0 :   for (Int_t iClu=0;iClu<fNClu;iClu++){                                                       //clusters loop
     122           0 :     AliHMPIDCluster *pClu=(AliHMPIDCluster*)pCluLst->UncheckedAt(iClu);                       //get pointer to current cluster    
     123           0 :     fXClu[iClu] = pClu->X();fYClu[iClu] = pClu->Y();                                          //store x,y for fitting procedure
     124           0 :     fClCk[iClu] = kTRUE;                                                                      //all cluster are accepted at this stage to be reconstructed
     125             :     
     126           0 :     if(iClu == index) {
     127             : 
     128           0 :       fMipX = pClu->X();
     129           0 :       fMipY = pClu->Y();
     130           0 :       fMipQ = pClu->Q();
     131           0 :       sizeClu = pClu->Size();
     132           0 :       nCh = pClu->Ch();
     133           0 :       fClCk[index] = kFALSE;
     134           0 :       fIdxMip = index;
     135           0 :       AliDebug(1,Form(" MIP n. %i x %f y %f Q %f",iClu,pClu->X(),pClu->Y(),pClu->Q()));
     136             :     }
     137             :   }//clusters loop
     138             :   
     139           0 :   pParam->SetRefIdx(nmean);
     140             :   
     141             :   //
     142           0 :   Float_t xra,yra,th,ph; pTrk->GetHMPIDtrk(xra,yra,th,ph);
     143           0 :   AliDebug(1,Form(" simulated phiTRK %6.2f thetaTRK %6.2f",ph*TMath::RadToDeg(),th*TMath::RadToDeg()));
     144             :   //
     145             :   
     146           0 :   if(!DoRecHiddenTrk()) {
     147           0 :     pTrk->SetHMPIDsignal(pParam->kNoPhotAccept);
     148           0 :     return kFALSE;
     149             :   }                                                                           //Do track and ring reconstruction,if problems returns 1
     150           0 :   AliDebug(1,Form("    fitted phi %6.2f ",fPhTrkFit*TMath::RadToDeg()));
     151             :   
     152           0 :   pTrk->SetHMPIDtrk(fRadX,fRadY,fThTrkFit,fPhTrkFit);                                        //store track intersection info
     153           0 :   pTrk->SetHMPIDmip(fMipX,fMipY,(Int_t)fMipQ,NCluFit());                                     //store mip info + n. phots of the ring 
     154           0 :   pTrk->SetHMPIDcluIdx(nCh,fIdxMip+1000*sizeClu);                                            //set cham number, index of cluster + cluster size
     155           0 :   pTrk->SetHMPIDsignal(fCkovFit);                                                            //find best Theta ckov for ring i.e. track
     156           0 :   pTrk->SetHMPIDchi2(fCkovSig2);                                                             //errors squared
     157           0 :   AliDebug(1,Form(" n clusters tot %i fitted to ring %i",fNClu,NCluFit()));
     158           0 :   for(Int_t i=0;i<fNClu;i++) {
     159           0 :     AliDebug(1,Form(" n.%3i  ThetaCer %8.3f PhiCer %8.3f check %i",i,fThetaPhot[i],fPhiPhot[i],fClCk[i]));
     160             :   }
     161           0 :   AliDebug(1,Form("CkovHiddenTrk: thetaC %f th %f ph %f",fCkovFit,fThTrkFit*TMath::RadToDeg(),fPhTrkFit*TMath::RadToDeg()));
     162             :   
     163           0 :   return kTRUE;
     164             :   
     165           0 : }//CkovHiddenTrk()
     166             : //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
     167             : Bool_t AliHMPIDReconHTA::DoRecHiddenTrk()
     168             : {
     169             : // Pattern recognition method without any infos from tracking...
     170             : // First a preclustering filter to avoid part of the noise
     171             : // Then only ellipsed-rings are fitted (no possibility, 
     172             : // for the moment, to reconstruct very inclined tracks)
     173             : // Finally a fitting with (th,ph) free, starting by very close values
     174             : // previously evaluated.
     175             : // Arguments:   none
     176             : //   Returns:   none
     177           0 :   Double_t thTrkRec,phiTrkRec,thetaCRec;
     178             :   
     179           0 :   if(!FindShape(thTrkRec,phiTrkRec,thetaCRec)) {
     180           0 :     AliDebug(1,Form(" FindShape failed...!"));
     181           0 :     return kFALSE;
     182             :   }
     183           0 :   AliDebug(1,Form(" FindShape accepted...!"));
     184             : 
     185           0 :   if(!FitRing(thTrkRec,phiTrkRec)) {
     186           0 :     AliDebug(1,Form(" FitRing failed...!"));
     187           0 :     return kFALSE;
     188             :   }
     189           0 :   AliDebug(1,Form(" FitRing accepted...!"));
     190             :   
     191           0 :   if(!UniformDistrib()) {
     192           0 :     AliDebug(1,Form(" UniformDistrib failed...!"));
     193           0 :     return kFALSE;
     194             :   }
     195           0 :   AliDebug(1,Form(" UniformDistrib accepted...!"));
     196             : 
     197           0 :   return kTRUE;
     198           0 : }//DoRecHiddenTrk()
     199             : //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
     200             : Bool_t AliHMPIDReconHTA::CluPreFilter(TClonesArray *pCluLst)
     201             : {
     202             : // Pre-filter of bkg clusters
     203             : // Arguments:    pSluLst  -  List of the clusters for a given chamber
     204             : //   Returns:    status   -  TRUE if filtering leaves enough photons, FALSE if not
     205             : //
     206           0 :   Int_t nClusTot = pCluLst->GetEntriesFast();
     207           0 :   if(nClusTot<4||nClusTot>100) {
     208           0 :     return kFALSE; 
     209             :   } else { 
     210           0 :     InitVars(nClusTot);
     211           0 :     return kTRUE;
     212             :   }
     213           0 : }
     214             : //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
     215             : Bool_t AliHMPIDReconHTA::FindShape(Double_t &thTrkRec,Double_t &phiTrkRec,Double_t &thetaCRec)
     216             : {
     217             : // Finds the estimates for phi and theta of the track and the ThetaCerenkov
     218             : // by using a database of the shapes of the rings
     219             : // Arguments:   none  
     220             : //   Returns:   thTrkRec  - estimate of theta track
     221             : //              phiTrkRec - estimate of phi   track
     222             : //              thetaCRec - estimate of ThetaCerenkov
     223             : //              status    - TRUE if a good solution is found, FALSE if not
     224             : 
     225           0 :   Double_t phiphot[1000];  
     226           0 :   Double_t    dist[1000];  
     227           0 :   Int_t     indphi[1000];  
     228             : 
     229             :   Bool_t status;
     230             :     
     231           0 :   if(fNClu>1000) return kFALSE;  // too many clusters....
     232             :   
     233             : // Sort in phi angle...
     234           0 :   for(Int_t i=0;i<fNClu;i++) {
     235           0 :     if(!fClCk[i]) {
     236           0 :       AliDebug(1,Form(" n.%3i  xMIP    %8.3f yMIP %8.3f check %i",i,fMipX,fMipY,fClCk[i]));
     237           0 :       phiphot[i] = 999.;
     238           0 :       dist[i]    = 999.;
     239           0 :       continue;
     240             :     }
     241           0 :     phiphot[i] = (TMath::ATan2(fMipY-fYClu[i],fMipX-fXClu[i])+TMath::Pi())*TMath::RadToDeg();
     242           0 :     dist[i]=TMath::Sqrt((fMipX-fXClu[i])*(fMipX-fXClu[i])+(fMipY-fYClu[i])*(fMipY-fYClu[i]));
     243           0 :     AliDebug(1,Form(" n.%3i  phiphot %8.3f dist %8.3f check %i",i,phiphot[i],dist[i],fClCk[i]));
     244             :   }
     245             :   
     246           0 :   TMath::Sort(fNClu,phiphot,indphi,kFALSE);
     247             :   
     248             : // Purify with a truncated mean;
     249             :   Int_t np=0;
     250             :   Double_t dMean  = 0;
     251             :   Double_t dMean2 = 0;
     252           0 :   for(Int_t i=0;i<fNClu;i++) {
     253           0 :     if(!fClCk[indphi[i]]) continue;                                                  // Check if a good photon candidate or not
     254           0 :     dMean +=dist[indphi[i]];
     255           0 :     dMean2+=dist[indphi[i]]*dist[indphi[i]];
     256           0 :     np++;
     257           0 :   }
     258             :  
     259           0 :   if(np>0){    
     260           0 :    dMean  /=(Double_t)np;
     261           0 :    dMean2 /=(Double_t)np;}
     262           0 :   Double_t rms = TMath::Sqrt(dMean2 - dMean*dMean);
     263             :   
     264           0 :   for(Int_t i=0;i<fNClu;i++) {
     265           0 :     if(!fClCk[indphi[i]]) continue;                                                  // Check if a good photon candidate or not
     266           0 :     if(TMath::Abs(dMean-dist[indphi[i]]) > 1.5*rms) {
     267           0 :       fClCk[indphi[i]] = kFALSE;
     268           0 :       continue;
     269             :     }
     270             :   }
     271             : 
     272           0 :   AliDebug(1,"Purification of photons...");
     273             : //
     274             : //  purify vectors for good photon candidates
     275             : //
     276             :   Int_t npeff=0;
     277           0 :   Double_t *phiphotP = new Double_t[fNClu+1];  
     278           0 :   Double_t *distP    = new Double_t[fNClu+1];  
     279           0 :   for(Int_t i=0;i<fNClu;i++) {
     280           0 :     AliDebug(1,Form(" n. %3i phiphot %8.3f dist %8.3f check %i",i,phiphot[indphi[i]],dist[indphi[i]],fClCk[indphi[i]]));
     281           0 :     if(!fClCk[indphi[i]]) continue;                                                  // Check if a good photon candidate or not
     282           0 :     phiphotP[npeff] = phiphot[indphi[i]];
     283           0 :     distP[npeff]    = dist[indphi[i]];
     284           0 :     npeff++;
     285           0 :   }
     286             :   
     287           0 :   if(npeff<3) {
     288           0 :     AliDebug(1,Form("FindShape failed: no enough photons = %i...",npeff));
     289           0 :     delete [] phiphotP;
     290           0 :     delete [] distP;
     291           0 :     return kFALSE;
     292             :   }
     293             : 
     294           0 :   Double_t xA,xB;
     295             :   status = kFALSE;
     296             :   
     297           0 :   if(!ShapeModel(npeff,phiphotP,distP,xA,xB,phiTrkRec)) {AliDebug(1,Form("ShapeModel failed            ")); return kFALSE;}
     298             :    
     299             : //  if(xA > 50 || xB > 15)                                {AliDebug(1,Form("xA and xB failed out of range")); return kFALSE;}
     300             : 
     301           0 :   Int_t binxDB,binyDB;
     302             :   Int_t compactDB=-1;
     303             :   
     304           0 :   if(xA > xB)  {                                        //geometrically not possible, try to recover on a mean values...
     305             : 
     306           0 :     FindBinDB(xA,xA,binxDB,binyDB);
     307           0 :     if(binxDB<0 || binyDB<0)                              {AliDebug(1,Form("bin < 0 ! failed             ")); return kFALSE;}
     308           0 :     Int_t compactDB1 = CompactDB(binxDB,binyDB);
     309           0 :     FindBinDB(xB,xB,binxDB,binyDB);
     310           0 :     if(binxDB<0 || binyDB<0)                              {AliDebug(1,Form("bin < 0 ! failed             ")); return kFALSE;}
     311           0 :     Int_t compactDB2 = CompactDB(binxDB,binyDB);
     312           0 :     Double_t thetaCRec1 =  (Double_t)(compactDB1%1000);
     313           0 :     Double_t thetaCRec2 =  (Double_t)(compactDB2%1000);
     314           0 :     Double_t thTrkRec1  =  (Double_t)(compactDB1/1000);
     315           0 :     Double_t thTrkRec2  =  (Double_t)(compactDB2/1000);
     316           0 :     thetaCRec = 0.5*(thetaCRec1+thetaCRec2);
     317           0 :     thTrkRec  = 0.5*( thTrkRec1+ thTrkRec2);
     318             :     
     319           0 :   } else {
     320             :       
     321           0 :     FindBinDB(xA,xB,binxDB,binyDB);
     322           0 :     if(binxDB<0 || binyDB<0) {AliDebug(1,Form("bin < 0 ! failed             ")); return kFALSE;}
     323             : 
     324           0 :     compactDB = CompactDB(binxDB,binyDB);
     325             : 
     326           0 :     if(compactDB<0)                                       {AliDebug(1,Form("compact< 0! failed           ")); return kFALSE;} 
     327             :     //
     328             :     //
     329           0 :     thetaCRec =  (Double_t)(compactDB%1000);
     330           0 :     thTrkRec  =  (Double_t)(compactDB/1000);
     331             : 
     332             :   }
     333             : 
     334           0 :   AliDebug(1,Form(" CompactDB %i thTrkRec %8.3f thetaCRec %8.3f ",compactDB,thTrkRec,thetaCRec));
     335             :     
     336           0 :   phiTrkRec *= TMath::DegToRad();
     337           0 :   thTrkRec  *= TMath::DegToRad(); 
     338           0 :   thetaCRec *= TMath::DegToRad();
     339             : 
     340             :   status = kTRUE;
     341             : 
     342           0 :   delete [] phiphotP;
     343           0 :   delete [] distP;
     344             :   
     345           0 :   return status;
     346           0 : }
     347             : //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
     348             : Bool_t AliHMPIDReconHTA::ShapeModel(Int_t np,Double_t *phiphot,Double_t *dist,Double_t &xA,Double_t &xB,Double_t &phiStart)
     349             : {
     350             : // Find a Spline curve to define dist. vs. phi angle
     351             : // in order to estimate the phi of the track
     352             : // Arguments:   np     - # points corresponding to # photon candidates
     353             : //             dist    - distance of each photon from MIP
     354             : //             phiphot - phi of the photon in the DRS
     355             : //   Returns:  xA      - min. distance from MIP
     356             : //             xB      - dist. from mip perpedicular to the major axis 
     357             : //             phiStart- estimate of the track phi
     358             : 
     359           0 :   TGraph *phigr = new TGraph(np,phiphot,dist);
     360           0 :   phiStart = FindSimmPhi();   
     361             :   
     362             :   Double_t phiStart1 = phiStart;
     363           0 :   if(phiStart1 > 360) phiStart1 -= 360;
     364           0 :   Double_t phiStart2 = phiStart+90;
     365           0 :   if(phiStart2 > 360) phiStart2 -= 360;
     366           0 :   xA = phigr->Eval(phiStart1);
     367           0 :   xB = phigr->Eval(phiStart2);
     368             :   //---
     369           0 :   AliDebug(1,Form("phiStart %f phiStart1 %f phiStart2 %f ",phiStart,phiStart1,phiStart2));
     370           0 :   AliDebug(1,Form("xA  %f xB  %f",xA,xB));
     371             : 
     372           0 :   phiStart += 180;  
     373           0 :   if(phiStart>360) phiStart-=360;
     374             :   
     375           0 :   return kTRUE;
     376           0 : }
     377             : //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
     378             : Double_t AliHMPIDReconHTA::VertParab(Double_t x1,Double_t y1,Double_t x2, Double_t y2, Double_t x3, Double_t y3)const
     379             : {
     380             : // It uses parabola from 3 points to evaluate the x-coord of the parab 
     381             : // Arguments:    xi,yi - points
     382             : //   Returns:    x-coord of the vertex 
     383             :   
     384           0 :   Double_t a = ((x1-x3)*(y1-y2)-(x1-x2)*(y1-y3))/((x1*x1-x2*x2)*(x1-x3)-(x1*x1-x3*x3)*(x1-x2));
     385           0 :   Double_t b = (y1-y2 - a*(x1*x1-x2*x2))/(x1-x2);
     386             : //  Double_t c = y1 - a*x1*x1-b*x1;
     387           0 :   return -0.5*b/a;
     388             : }
     389             : //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
     390             : Bool_t AliHMPIDReconHTA::FitRing(Double_t thTrkRec,Double_t phiTrkRec)
     391             : {
     392             :   Double_t th = thTrkRec;
     393             :   Double_t ph = phiTrkRec;
     394             :   
     395           0 :   FitFree(th,ph);
     396           0 :   while(FitStatus()) {
     397           0 :     th = fThTrkFit;
     398           0 :     ph = fPhTrkFit;
     399           0 :     FitFree(th,ph);
     400             :   }
     401           0 :   return kTRUE;
     402             : }
     403             : //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
     404             : Bool_t AliHMPIDReconHTA::FitFree(Double_t thTrkRec,Double_t phiTrkRec)
     405             : {
     406             : // Fit performed by minimizing RMS/sqrt(n) of the
     407             : // photons reconstructed. First phi is fixed and theta
     408             : // is fouond, then (th,ph) of the track
     409             : // as free parameters
     410             : // Arguments:    PhiRec phi of the track
     411             : //   Returns:    none
     412             :   
     413           0 :   TMinuit *pMinuit = new TMinuit(2);
     414           0 :   pMinuit->mncler();
     415           0 :   gMinuit->SetObjectFit((TObject*)this);  gMinuit->SetFCN(AliHMPIDReconHTA::FunMinPhot);  //set fit function
     416           0 :   Double_t aArg=-1,parStep,parLow,parHigh;     Int_t iErrFlg;                 //tmp vars for TMinuit
     417           0 :   Double_t d1,d2,d3;
     418           0 :   TString sName;
     419           0 :   Double_t th,ph;
     420             :   
     421           0 :   pMinuit->mnexcm("SET PRI",&aArg,1,iErrFlg);                                          //suspend all printout from TMinuit
     422           0 :   pMinuit->mnexcm("SET NOW",&aArg,0,iErrFlg);
     423             : 
     424           0 :   if(thTrkRec==0) thTrkRec = 3.*TMath::DegToRad();    // not to start from the edge...
     425             :   
     426           0 :   AliDebug(1,Form(" Minimization STARTED with phiTRK %6.2f thetaTRK %6.2f",phiTrkRec,thTrkRec));
     427             : 
     428           0 :   pMinuit->mnparm(0," thTrk  ",thTrkRec ,parStep=0.01,parLow=0,parHigh=TMath::PiOver4(),iErrFlg);
     429           0 :   pMinuit->mnparm(1," phiTrk ",phiTrkRec,parStep=0.01,parLow=0,parHigh=TMath::TwoPi(),iErrFlg);
     430             :   
     431           0 :   pMinuit->FixParameter(1);
     432           0 :   pMinuit->mnexcm("SIMPLEX" ,&aArg,0,iErrFlg);   
     433           0 :   pMinuit->mnexcm("MIGRAD"  ,&aArg,0,iErrFlg);
     434           0 :   pMinuit->Release(1);  
     435           0 :   pMinuit->mnexcm("MIGRAD"  ,&aArg,0,iErrFlg);
     436             :   
     437           0 :   pMinuit->mnpout(0,sName,th,d1,d2,d3,iErrFlg);
     438           0 :   pMinuit->mnpout(1,sName,ph,d1,d2,d3,iErrFlg);   
     439             :   
     440           0 :   Double_t f,par[2];
     441             :   Double_t *grad=0x0;
     442           0 :   par[0] = th;par[1] = ph;
     443           0 :   pMinuit->Eval(2,grad,f,par,3);
     444             : 
     445           0 :   SetTrkFit(th,ph);
     446             :   return kTRUE;
     447           0 : }
     448             : //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
     449             : void AliHMPIDReconHTA::FunMinPhot(Int_t &/* */,Double_t* /* */,Double_t &f,Double_t *par,Int_t iflag)
     450             : {
     451             : // Minimization function to find best track and thetaC parameters
     452             : // Arguments:    f = function value to minimize
     453             : //             par = list of parameter to find
     454             : //           iflag = flag status. See Minuit instructions
     455             : //   Returns:    none
     456             : //
     457             : // Note: it is necessary to call an instance of AlihMPIDParam. Not possible to use fParam
     458             : // because of the static instantiation of the function in Minuit
     459             :   
     460           0 :   AliHMPIDParam *pParam=AliHMPIDParam::Instance();
     461           0 :   AliHMPIDReconHTA *pRecHTA=(AliHMPIDReconHTA*)gMinuit->GetObjectFit();
     462           0 :   AliHMPIDRecon pRec;
     463           0 :   Double_t sizeCh = 0.5*pParam->RadThick()+pParam->WinThick()+pParam->GapThick();
     464           0 :   Double_t thTrk = par[0]; 
     465           0 :   Double_t phTrk = par[1];
     466           0 :   Double_t xrad = pRecHTA->MipX() - sizeCh*TMath::Tan(thTrk)*TMath::Cos(phTrk);
     467           0 :   Double_t yrad = pRecHTA->MipY() - sizeCh*TMath::Tan(thTrk)*TMath::Sin(phTrk);
     468           0 :   pRecHTA->SetRadXY(xrad,yrad);
     469           0 :   pRec.SetTrack(xrad,yrad,thTrk,phTrk);
     470             : 
     471             :   Double_t meanCkov =0;
     472             :   Double_t meanCkov2=0;
     473           0 :   Double_t thetaCer,phiCer;
     474             :   Int_t nClAcc = 0;
     475           0 :   Int_t nClTot=pRecHTA->NClu();
     476             : 
     477           0 :   for(Int_t i=0;i<nClTot;i++) {
     478             :     
     479           0 :     if(pRecHTA->IdxMip() == i) {
     480           0 :       pRecHTA->SetPhotAngles(i,999.,999.);
     481           0 :       continue;
     482             :     }
     483             :     
     484           0 :     if(!(pRecHTA->ClCk(i))) continue;
     485             :     
     486           0 :     Bool_t status = pRec.FindPhotCkov(pRecHTA->XClu(i),pRecHTA->YClu(i),thetaCer,phiCer);
     487           0 :     if(!status) {
     488           0 :       pRecHTA->SetPhotAngles(i,999.,999.);
     489           0 :       continue;
     490             :     }
     491           0 :     pRecHTA->SetPhotAngles(i,thetaCer,phiCer);
     492           0 :     meanCkov  += thetaCer;
     493           0 :     meanCkov2 += thetaCer*thetaCer;
     494           0 :     nClAcc++;
     495           0 :   }
     496             :   
     497           0 :   if(nClAcc==0) {f=999;return;}
     498           0 :   meanCkov  /=(Double_t)nClAcc;
     499           0 :   meanCkov2 /=(Double_t)nClAcc;
     500           0 :   Double_t rms = TMath::Sqrt(TMath::Abs(meanCkov2 - meanCkov*meanCkov));
     501           0 :   f = rms/TMath::Sqrt((Double_t)nClAcc);
     502             :   
     503           0 :   if(iflag==3) {
     504             :     Int_t nClAccStep1 = nClAcc;
     505             :     nClAcc = 0;
     506             :     Double_t meanCkov1=0;
     507             :     Double_t meanCkov3=0;
     508           0 :     for(Int_t i=0;i<nClTot;i++) {
     509             :       
     510           0 :       if(!(pRecHTA->ClCk(i))) continue;
     511           0 :       thetaCer = pRecHTA->PhotTheta(i);
     512           0 :       if(TMath::Abs(thetaCer-meanCkov)<2*rms) {
     513           0 :         meanCkov1 += thetaCer;
     514           0 :         meanCkov3 += thetaCer*thetaCer;
     515           0 :         nClAcc++;
     516           0 :       } else pRecHTA->SetClCk(i,kFALSE);
     517             :     }
     518             :     
     519           0 :     if(nClAcc<3) {
     520           0 :       pRecHTA->SetFitStatus(kFALSE);
     521           0 :       pRecHTA->SetCkovFit(meanCkov);
     522           0 :       pRecHTA->SetCkovSig2(rms*rms);
     523           0 :       pRecHTA->SetNCluFit(nClAccStep1);
     524           0 :       return;
     525             :     }
     526             :       
     527           0 :     meanCkov1/=nClAcc;
     528           0 :     Double_t rms2 = (meanCkov3 - meanCkov*meanCkov*nClAcc)/nClAcc;
     529             :     
     530             :     // get a logger instance
     531             :     // what for??
     532             :     //AliLog::GetRootLogger();
     533             : 
     534           0 :     if(nClAcc!=nClAccStep1) pRecHTA->SetFitStatus(kTRUE); else pRecHTA->SetFitStatus(kFALSE);
     535             :     
     536           0 :     pRecHTA->SetCkovFit(meanCkov1);
     537           0 :     pRecHTA->SetCkovSig2(rms2);
     538           0 :     pRecHTA->SetNCluFit(nClAcc);
     539           0 :   }
     540           0 : }//FunMinPhot()
     541             : //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
     542             : void AliHMPIDReconHTA::InitDatabase()
     543             : {
     544             : // Construction a database of ring shapes on fly
     545             : //   Arguments: none
     546             : //   Returns  : none
     547             : //  N.B. fgDB is the distance with x-min from MIP
     548             : //                                 y-dist from the ring of the MIP perpendicular to major axis
     549             : //        The content is the packed info of track theta and thetaC in degrees
     550             : //                        thetaC+1000*thTrk
     551             : //
     552             : //  TFile *pout = new TFile("./database.root","recreate");
     553             : 
     554             :   static Bool_t isDone = kFALSE;
     555             :   
     556           0 :   TStopwatch timer;
     557             :   
     558           0 :   if(isDone) {
     559           0 :    return;
     560             :   }
     561             :   
     562           0 :   if(!isDone) {
     563           0 :     timer.Start();
     564             :   }
     565             :  
     566           0 :   AliInfo(Form("database HTA is being built.Please, wait..."));
     567             : //  
     568             :   Double_t x[3]={0,0,0},y[3];
     569             : 
     570           0 :   AliHMPIDRecon rec;
     571             : 
     572           0 :   if(!fParam) fParam=AliHMPIDParam::Instance();
     573           0 :   Double_t thetaMax = TMath::ACos(1./fParam->MeanIdxRad());
     574           0 :   Double_t thTrkMax = 1./TMath::ASin(fParam->MeanIdxRad());    
     575             : 
     576             :   Int_t nstepx = 1000;
     577             :   Int_t nstepy = 1000;
     578             : 
     579             :   //
     580             :   Double_t xrad = 0;
     581             :   Double_t yrad = 0;
     582             :   Double_t phTrk = 0;
     583             : 
     584           0 :   for(Int_t i=0;i<nstepx;i++) {     //loop on thetaC
     585           0 :     for(Int_t j=0;j<nstepy;j++) {   //loop on theta particle
     586           0 :       Double_t thetaC = thetaMax/nstepx*((Double_t)i+0.5);
     587           0 :       Double_t thTrk  = thTrkMax/nstepy*((Double_t)j+0.5);
     588             :       //
     589             :       //mip position
     590             :       //
     591           0 :       Double_t sizeCh = 0.5*fParam->RadThick()+fParam->WinThick()+fParam->GapThick();
     592           0 :       Double_t xmip = xrad + sizeCh*TMath::Tan(thTrk)*TMath::Cos(phTrk);
     593           0 :       Double_t ymip = yrad + sizeCh*TMath::Tan(thTrk)*TMath::Sin(phTrk);
     594             : 
     595             :       Double_t dist2;
     596             :       //
     597             :       //first point at phi=0
     598             :       //
     599           0 :       rec.SetTrack(xrad,yrad,thTrk,phTrk);
     600           0 :       TVector2 pos;
     601           0 :       pos=rec.TracePhot(thetaC,0);
     602             : 
     603             :       /*if(pos.X()==-999) {
     604             :         dist1 = 0;            //open ring...only the distance btw mip and point at 180 will be considered
     605             :       } else {
     606             :         x[0] = pos.X(); y[0] = pos.Y();
     607             :         dist1   = TMath::Sqrt((x[0]-xmip)*(x[0]-xmip)+(y[0]-ymip)*(y[0]-ymip));
     608             :       }*/
     609             :       
     610           0 :       if(pos.X()!=-999) {x[0] = pos.X(); y[0] = pos.Y();}
     611             :       
     612             :       //
     613             :       //second point at phi=180
     614             :       //
     615           0 :       rec.SetTrack(xrad,yrad,thTrk,phTrk);
     616           0 :       pos=rec.TracePhot(thetaC,TMath::Pi());
     617             : 
     618           0 :       if(pos.X()==-999) {AliDebug(1,Form("it should not happens!Bye"));return;}
     619           0 :       x[1] = pos.X(); y[1] = pos.Y();
     620           0 :       if((x[1]-xmip)*(x[0]-xmip)>0) continue; // to avoid circles out mips (for very low ThetaC)
     621           0 :       dist2   = TMath::Sqrt((x[1]-xmip)*(x[1]-xmip)+(y[1]-ymip)*(y[1]-ymip));
     622             : 
     623             : //      Double_t distA = dist1+dist2;
     624             :       Double_t distA = dist2;     // only the minimum: problem of acceptance
     625             :       //
     626             :       //second point at phi=90
     627             :       //
     628           0 :       rec.SetTrack(xrad,yrad,thTrk,phTrk);
     629           0 :       pos=rec.TracePhot(thetaC,TMath::PiOver2());
     630             : 
     631           0 :       if(pos.X()==-999) continue;
     632           0 :       x[2] = pos.X(); y[2] = pos.Y();
     633           0 :       Double_t distB   = TMath::Sqrt((x[2]-xmip)*(x[2]-xmip)+(y[2]-ymip)*(y[2]-ymip));
     634             : // compact the infos...      
     635           0 :       Int_t compact = (Int_t)(thetaC*TMath::RadToDeg())+1000*(Int_t)(thTrk*TMath::RadToDeg());
     636           0 :       Int_t binxDB,binyDB;
     637           0 :       FindBinDB(distA,distB,binxDB,binyDB);
     638           0 :       if(fgDB[binxDB][binyDB]==0) fgDB[binxDB][binyDB] = compact;
     639           0 :     }
     640             :   }
     641             : 
     642           0 :   FillZeroChan();
     643             : 
     644           0 :   if(!isDone) {
     645           0 :     timer.Stop();
     646           0 :     Double_t nSecs = timer.CpuTime();  
     647           0 :     AliInfo(Form("database HTA successfully open in %3.1f sec.(CPU). Reconstruction is started.",nSecs));
     648           0 :     isDone = kTRUE;
     649           0 :   }
     650             :   
     651             : //  pout->Write();
     652             : //  pout->Close();
     653             :   
     654           0 : }//InitDatabase()
     655             : //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
     656             : void AliHMPIDReconHTA::FillZeroChan()const
     657             : {
     658             :   //If fills eventually channel without entries
     659             :   //inthe histo "database" jyst interpolating the neighboring cells
     660             :   // Arguments: histogram pointer of the database
     661             :   //   Returns: none
     662             :   //
     663             :   const Int_t nxDB = 500;
     664             :   const Int_t nyDB = 150;
     665             : 
     666           0 :   for(Int_t i = 0;i<nxDB;i++) {
     667           0 :     for(Int_t j = 0;j<nyDB;j++) {
     668           0 :       if(fgDB[i][j] == 0) {
     669           0 :         fgDB[i][j] = -1;
     670           0 :         Int_t nXmin = i-1; Int_t nXmax=i+1;
     671           0 :         Int_t nYmin = j-1; Int_t nYmax=j+1;
     672             :         Int_t nc = 0;
     673             :         Double_t meanC =0;
     674             :         Double_t meanTrk =0;
     675           0 :         for(Int_t ix=nXmin;ix<=nXmax;ix++) {
     676           0 :           if(ix<0||ix>=nxDB) continue;
     677           0 :           for(Int_t iy=nYmin;iy<=nYmax;iy++) {
     678           0 :             if(iy<0||iy>=nyDB) continue;
     679           0 :             meanC  +=  (Int_t)(fgDB[ix][iy]%1000);
     680           0 :             meanTrk+=  (Int_t)(fgDB[ix][iy]/1000);
     681           0 :             nc++;
     682           0 :           }
     683           0 :           meanC/=nc; meanTrk/=nc;
     684           0 :           Int_t compact = (Int_t)meanC+1000*(Int_t)meanTrk;
     685           0 :           if(compact>0)fgDB[i][j] = compact;
     686           0 :         }
     687           0 :       }
     688             :     }
     689             :   }
     690           0 : }//FillZeroChan()
     691             : //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
     692             : Int_t AliHMPIDReconHTA::r2(Double_t *coef, Double_t &x1, Double_t &x2)
     693             : {
     694             :   //2nd deg. equation
     695             :   //solution
     696             :   // Arguments: coef 2 1 0: ax^2+bx+c=0
     697             :   //   Returns: n. of solutions
     698             :   //            x1= 1st sol
     699             :   //            x2= 2nd sol
     700             :   Double_t a,b,c;
     701           0 :   a = coef[2];
     702           0 :   b = coef[1];
     703           0 :   c = coef[0];
     704           0 :   Double_t delta = b*b-4*a*c;
     705           0 :   if(delta<0) {return 0;}
     706           0 :   if(delta==0) {
     707           0 :     x1=x2=-b/(2*a);
     708           0 :     return 1;
     709             :   }
     710           0 :   if(a==0) {
     711           0 :     x1 = -c/b;
     712           0 :     return 1;
     713             :   }
     714             :   // delta>0
     715           0 :   x1 = (-b+TMath::Sqrt(delta))/(2*a);
     716           0 :   x2 = (-b-TMath::Sqrt(delta))/(2*a);
     717           0 :   return 2;
     718           0 : }//r2()
     719             : //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
     720             : 
     721             : Double_t AliHMPIDReconHTA::FindSimmPhi() 
     722             : {     
     723             : //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
     724             : // Reconstruction of phiTRK angle with two methods (in switching)
     725             : // 
     726             : // - least square method (for closed rings)
     727             : // - by minimum distance mip-photon (for open rings)
     728             :   
     729             :   Float_t coeff1ord=0;     Float_t coeff2ord=0;     Float_t coeff0ord=0;  
     730             :   Float_t xrotsumm =0;     Float_t yrotsumm =0;     Float_t xx =0;           
     731             :   Float_t yy =0;           Float_t xy =0;
     732             :   Double_t xmin=0;
     733             :   Double_t ymin=0;
     734             : 
     735             :   Int_t np=0;    
     736             :     
     737             :   Double_t distMin = 999.;
     738             :   
     739           0 :   for(Int_t i=0;i<fNClu;i++) {
     740           0 :     if(!fClCk[i]) continue;
     741           0 :     np++;
     742           0 :     xrotsumm+=fXClu[i];         // summ xi
     743           0 :     yrotsumm+=fYClu[i];         // summ yi
     744           0 :     xx+=fXClu[i]*fXClu[i];      // summ xixi     
     745           0 :     yy+=fYClu[i]*fYClu[i];      // summ yiyi
     746           0 :     xy+=fXClu[i]*fYClu[i];      // summ yixi     
     747           0 :     Double_t dist2= (fXClu[i]-fMipX)*(fXClu[i]-fMipX)+(fYClu[i]-fMipY)*(fYClu[i]-fMipY);
     748           0 :     if(dist2<distMin) {
     749             :       distMin = dist2;
     750             :       xmin = fXClu[i];
     751             :       ymin = fYClu[i];
     752           0 :     }
     753           0 :   }
     754             : 
     755           0 :   Double_t AngM = TMath::ATan2(ymin-fMipY,(xmin-fMipX))*TMath::RadToDeg();
     756           0 :   if (AngM<0) AngM+=360;
     757             :   
     758           0 :   AliDebug(1,Form(" Simple angle prediction with MIN phi = %f",AngM));
     759             :   
     760             :   //_____calc. met min quadr using effective distance _________________________________________________
     761             :   
     762           0 :   if(np>0){ 
     763           0 :     coeff2ord = xy-xrotsumm*yrotsumm/np;    
     764           0 :     coeff1ord = yrotsumm*yrotsumm/np - xrotsumm*xrotsumm/np - yy + xx;
     765           0 :   }
     766           0 :   coeff0ord = -coeff2ord;
     767             :   
     768           0 :   AliDebug(1,Form(" a = %f b = %f c = %f",coeff2ord,coeff1ord,coeff0ord));
     769             :   
     770           0 :   Double_t m1=0, m2=0;  Double_t n1=0, n2=0;
     771             :                             // c           // b         // a
     772           0 :   Double_t coeff[3]={coeff0ord,coeff1ord,coeff2ord};    
     773             :   
     774           0 :   r2(coeff,m1,m2);
     775             :   
     776           0 :   if(np>0){ 
     777           0 :     n1=(yrotsumm-m1*xrotsumm)/np;                         
     778           0 :     n2=(yrotsumm-m2*xrotsumm)/np;}
     779             :   // 2 solutions.................
     780             :   
     781             :   // negative angles solved...
     782             :   
     783           0 :   Double_t d1 =(1/(m1*m1+1))*(yy+m1*m1*xx+np*n1*n1-2*m1*xy-2*n1*yrotsumm+2*m1*n1*xrotsumm);
     784           0 :   Double_t d2 =(1/(m2*m2+1))*(yy+m2*m2*xx+np*n2*n2-2*m2*xy-2*n2*yrotsumm+2*m2*n2*xrotsumm);
     785             : 
     786           0 :   AliDebug(1,Form(" predicted distance d1 %f for angle %6.2f d2 %f for angle %6.2f",d1,TMath::ATan(m1)*TMath::RadToDeg(),
     787             :                                                                                     d2,TMath::ATan(m2)*TMath::RadToDeg()));
     788             :   Double_t mMin;
     789           0 :   if(d1 > d2) mMin = m2; else mMin = m1;
     790             :   
     791             :   Double_t phiTrk=0;
     792             :   // 
     793           0 :   if(ymin <  fMipY && xmin >  fMipX)  {phiTrk  =  TMath::ATan(mMin)*TMath::RadToDeg()+180;}
     794           0 :   if(ymin >  fMipY && xmin <  fMipX)  {phiTrk  =  TMath::ATan(mMin)*TMath::RadToDeg()+360;}
     795           0 :   if(ymin >  fMipY && xmin >  fMipX)  {phiTrk  =  TMath::ATan(mMin)*TMath::RadToDeg()+180;}
     796           0 :   if(ymin <  fMipY && xmin <  fMipX)  {phiTrk  =  TMath::ATan(mMin)*TMath::RadToDeg();}
     797           0 :   if(ymin == fMipY && xmin >  fMipX)  {phiTrk  =  TMath::ATan(mMin)*TMath::RadToDeg()+180;}
     798           0 :   if(ymin == fMipY && xmin <  fMipX)  {phiTrk  =  TMath::ATan(mMin)*TMath::RadToDeg();}
     799           0 :   if(ymin <  fMipY && xmin == fMipX)  {phiTrk  =   90;}
     800           0 :   if(ymin >  fMipY && xmin == fMipX)  {phiTrk  =  270;}
     801             :   
     802             :   //  ------------------------- choose the best-----------------------
     803             :   
     804             :   
     805           0 :   if( AngM-40 <=  phiTrk  &&  AngM+40 >= phiTrk)   return phiTrk;  else return AngM;
     806           0 : }
     807             : //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
     808             : void AliHMPIDReconHTA::FindBinDB(Double_t x,Double_t y,Int_t &binX,Int_t &binY)
     809             : {
     810             :   const Int_t nxDB = 500;
     811             :   const Int_t nyDB = 150;
     812             :   const Double_t xlowDB =  0;   
     813             :   const Double_t xhigDB = 50;   
     814             :   const Double_t ylowDB =  0;
     815             :   const Double_t yhigDB = 30;
     816             : 
     817           0 :   binX = -1;
     818           0 :   binY = -1;
     819           0 :   if(x<xlowDB && x>xhigDB &&
     820           0 :      y<ylowDB && y>yhigDB)    return;
     821           0 :   binX = Int_t((x-xlowDB)/(xhigDB-xlowDB)*nxDB);
     822           0 :   binY = Int_t((y-ylowDB)/(yhigDB-ylowDB)*nyDB);
     823           0 :   if(binX>=nxDB || binY>=nyDB) {
     824           0 :     binX = -1;
     825           0 :     binY = -1;
     826           0 :   }
     827             :   
     828           0 : }
     829             : //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
     830             : Bool_t AliHMPIDReconHTA::UniformDistrib() 
     831             : {
     832           0 :   AliHMPIDParam *pParam=AliHMPIDParam::Instance();
     833           0 :   AliHMPIDRecon pRec;
     834             : 
     835           0 :   Double_t sizeCh = 0.5*pParam->RadThick()+pParam->WinThick()+pParam->GapThick();
     836           0 :   Double_t xrad = MipX() - sizeCh*TMath::Tan(fThTrkFit)*TMath::Cos(fPhTrkFit);
     837           0 :   Double_t yrad = MipY() - sizeCh*TMath::Tan(fThTrkFit)*TMath::Sin(fPhTrkFit);
     838             :   
     839           0 :   pRec.SetTrack(xrad,yrad,fThTrkFit,fPhTrkFit);
     840             :     
     841             :   Int_t npeff=0;
     842             :   Int_t nPhotPerBin = 4;
     843           0 :   for(Int_t i=0;i<fNClu;i++) {  
     844           0 :     if(!ClCk(i)) continue;
     845           0 :     npeff++;
     846           0 :   }
     847             :   
     848           0 :   Int_t nPhiBins = npeff/nPhotPerBin+1;
     849           0 :   if(nPhiBins<=1) nPhiBins = 2;
     850             : 
     851             :   Double_t *iPhiBin;
     852           0 :   iPhiBin = new Double_t[nPhiBins];
     853             :   
     854           0 :   for(Int_t i=0;i<nPhiBins;i++) iPhiBin[i] =0;
     855             : 
     856           0 :   for(Int_t i=0;i<fNClu;i++) { 
     857           0 :     if(!ClCk(i)) continue;
     858           0 :     Double_t phiCer = PhotPhi(i);
     859             :     
     860           0 :     Double_t PhiProva = phiCer*TMath::RadToDeg();
     861           0 :     if(PhiProva<0) PhiProva+= 360;
     862           0 :     Int_t index = (Int_t)((Float_t)nPhiBins*PhiProva/360.);
     863           0 :     iPhiBin[index]++;
     864           0 :    }
     865             : 
     866             :    Double_t chi2 = 0;
     867           0 :    for(Int_t i=0;i<nPhiBins;i++) {
     868           0 :      Double_t theo = (Double_t)npeff/(Double_t)nPhiBins;
     869           0 :      if(theo==0) continue;
     870           0 :      chi2+= (iPhiBin[i] - theo)*(iPhiBin[i] - theo)/theo;
     871           0 :    }
     872             :    
     873           0 :     delete [] iPhiBin;
     874             :     
     875           0 :     Double_t prob = TMath::Prob(chi2, nPhiBins-1);
     876           0 :     AliDebug(1,Form(" Probability for uniform distrib: %6f.3 %s",prob,(prob<0.05) ? "rejected" : "accepted"));
     877           0 :     if(prob<0.05) return kFALSE;
     878           0 :     return kTRUE;
     879             :     
     880           0 :  }
     881             : //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Generated by: LCOV version 1.11