LCOV - code coverage report
Current view: top level - PHOS/PHOSbase - AliPHOSPIDv1.cxx (source / functions) Hit Total Coverage
Test: coverage.info Lines: 455 717 63.5 %
Date: 2016-06-14 17:26:59 Functions: 23 44 52.3 %

          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             : /* $Id$ */
      17             : 
      18             : /* History of cvs commits:
      19             :  *
      20             :  * $Log$
      21             :  * Revision 1.113  2007/08/07 14:12:03  kharlov
      22             :  * Quality assurance added (Yves Schutz)
      23             :  *
      24             :  * Revision 1.112  2007/07/11 13:43:30  hristov
      25             :  * New class AliESDEvent, backward compatibility with the old AliESD (Christian)
      26             :  *
      27             :  * Revision 1.111  2007/05/04 14:49:29  policheh
      28             :  * AliPHOSRecPoint inheritance from AliCluster
      29             :  *
      30             :  * Revision 1.110  2007/04/24 10:08:03  kharlov
      31             :  * Vertex extraction from GenHeader
      32             :  *
      33             :  * Revision 1.109  2007/04/18 09:34:05  kharlov
      34             :  * Geometry bug fixes
      35             :  *
      36             :  * Revision 1.108  2007/04/16 09:03:37  kharlov
      37             :  * Incedent angle correction fixed
      38             :  *
      39             :  * Revision 1.107  2007/04/02 15:00:16  cvetan
      40             :  * No more calls to gAlice in the reconstruction
      41             :  *
      42             :  * Revision 1.106  2007/04/01 15:40:15  kharlov
      43             :  * Correction for actual vertex position implemented
      44             :  *
      45             :  * Revision 1.105  2007/03/06 06:57:46  kharlov
      46             :  * DP:calculation of distance to CPV done in TSM
      47             :  *
      48             :  * Revision 1.104  2006/12/15 10:46:26  hristov
      49             :  * Using TMath::Abs instead of fabs
      50             :  *
      51             :  * Revision 1.103  2006/09/07 18:31:08  kharlov
      52             :  * Effective c++ corrections (T.Pocheptsov)
      53             :  *
      54             :  * Revision 1.102  2006/01/23 17:51:48  hristov
      55             :  * Using the recommended way of forward declarations for TVector and TMatrix (see v5-08-00 release notes). Additional clean-up
      56             :  *
      57             :  * Revision 1.101  2005/05/28 14:19:04  schutz
      58             :  * Compilation warnings fixed by T.P.
      59             :  *
      60             :  */
      61             : 
      62             : //_________________________________________________________________________
      63             : // Implementation version v1 of the PHOS particle identifier 
      64             : // Particle identification based on the 
      65             : //     - RCPV: distance from CPV recpoint to EMCA recpoint.
      66             : //     - TOF 
      67             : //     - PCA: Principal Components Analysis..
      68             : // The identified particle has an identification number corresponding 
      69             : // to a 9 bits number:
      70             : //     -Bit 0 to 2: bit set if RCPV > CpvEmcDistance (each bit corresponds
      71             : //      to a different efficiency-purity point of the photon identification) 
      72             : //     -Bit 3 to 5: bit set if TOF  < TimeGate (each bit corresponds
      73             : //      to a different efficiency-purity point of the photon identification) 
      74             : //     -Bit 6 to 9: bit set if Principal Components are 
      75             : //      inside an ellipse defined by the parameters a, b, c, x0 and y0.
      76             : //      (each bit corresponds to a different efficiency-purity point of the 
      77             : //      photon identification)
      78             : //      The PCA (Principal components analysis) needs a file that contains
      79             : //      a previous analysis of the correlations between the particles. This 
      80             : //      file is $ALICE_ROOT/PHOS/PCA8pa15_0.5-100.root. Analysis done for 
      81             : //      energies between 0.5 and 100 GeV.
      82             : //      A calibrated energy is calculated. The energy of the reconstructed
      83             : //      cluster is corrected with the formula A + B * E  + C * E^2, whose 
      84             : //      parameters where obtained through the study of the reconstructed 
      85             : //      energy distribution of monoenergetic photons. 
      86             : //
      87             : //      All the parameters (RCPV(2 rows-3 columns),TOF(1r-3c),PCA(5r-4c) 
      88             : //      and calibration(1r-3c))are stored in a file called 
      89             : //      $ALICE_ROOT/PHOS/Parameters.dat. Each time that AliPHOSPIDv1 is 
      90             : //      initialized, this parameters are copied to a Matrix (9,4), a 
      91             : //      TMatrixD object.  
      92             : //
      93             : // use case:
      94             : //  root [0] AliPHOSPIDv1 * p = new AliPHOSPIDv1("galice1.root")
      95             : //  Warning in <TDatabasePDG::TDatabasePDG>: object already instantiated
      96             : //          // reading headers from file galice1.root and create  RecParticles 
      97             :             // TrackSegments and RecPoints are used 
      98             : //          // set file name for the branch RecParticles
      99             : //  root [1] p->ExecuteTask("deb all time")
     100             : //          // available options
     101             : //          // "deb" - prints # of reconstructed particles
     102             : //          // "deb all" -  prints # and list of RecParticles
     103             : //          // "time" - prints benchmarking results
     104             : //                  
     105             : //  root [2] AliPHOSPIDv1 * p2 = new AliPHOSPIDv1("galice1.root","v1",kTRUE)
     106             : //  Warning in <TDatabasePDG::TDatabasePDG>: object already instantiated
     107             : //                //Split mode.  
     108             : //  root [3] p2->ExecuteTask()
     109             : //
     110             : 
     111             : 
     112             : //*-- Author: Yves Schutz (SUBATECH)  & Gines Martinez (SUBATECH) & 
     113             : //            Gustavo Conesa April 2002
     114             : //            PCA redesigned by Gustavo Conesa October 2002:
     115             : //            The way of using the PCA has changed. Instead of 2
     116             : //            files with the PCA, each one with different energy ranges 
     117             : //            of application, we use the wide one (0.5-100 GeV), and instead
     118             : //            of fixing 3 ellipses for different ranges of energy, it has been
     119             : //            studied the dependency of the ellipses parameters with the 
     120             : //            energy, and they are implemented in the code as a funtion 
     121             : //            of the energy. 
     122             : //
     123             : //
     124             : //
     125             : // --- ROOT system ---
     126             : 
     127             : 
     128             : // --- Standard library ---
     129             : #include <TMatrixF.h>
     130             : #include "TFormula.h"
     131             : #include "TBenchmark.h"
     132             : #include "TPrincipal.h"
     133             : #include "TFile.h" 
     134             : #include "TSystem.h"
     135             : 
     136             : // --- AliRoot header files ---
     137             :               //#include "AliLog.h"
     138             : #include "AliPHOS.h"
     139             : #include "AliPHOSPIDv1.h"
     140             : #include "AliESDEvent.h"
     141             : #include "AliESDVertex.h"
     142             : #include "AliPHOSTrackSegment.h"
     143             : #include "AliPHOSEmcRecPoint.h"
     144             : #include "AliPHOSRecParticle.h"
     145             : 
     146          22 : ClassImp( AliPHOSPIDv1) 
     147             : 
     148             : //____________________________________________________________________________
     149             : AliPHOSPIDv1::AliPHOSPIDv1() :
     150           0 :   AliPHOSPID(),
     151           0 :   fBayesian(kFALSE),
     152           0 :   fDefaultInit(kFALSE),
     153           0 :   fWrite(kFALSE),
     154           0 :   fFileNamePrincipalPhoton(),
     155           0 :   fFileNamePrincipalPi0(),
     156           0 :   fFileNameParameters(),
     157           0 :   fPrincipalPhoton(0),
     158           0 :   fPrincipalPi0(0),
     159           0 :   fX(0),
     160           0 :   fPPhoton(0),
     161           0 :   fPPi0(0),
     162           0 :   fParameters(0),
     163           0 :   fVtx(0.,0.,0.), 
     164           0 :   fTFphoton(0),
     165           0 :   fTFpiong(0),
     166           0 :   fTFkaong(0),
     167           0 :   fTFkaonl(0),
     168           0 :   fTFhhadrong(0),
     169           0 :   fTFhhadronl(0),
     170           0 :   fDFmuon(0),
     171           0 :   fERecWeight(0),
     172           0 :   fChargedNeutralThreshold(0.),
     173           0 :   fTOFEnThreshold(0),
     174           0 :   fDispEnThreshold(0),
     175           0 :   fDispMultThreshold(0)
     176           0 : { 
     177             :   // default ctor
     178             :  
     179           0 :   InitParameters() ; 
     180           0 :   fDefaultInit = kTRUE ; 
     181           0 : }
     182             : 
     183             : //____________________________________________________________________________
     184             : AliPHOSPIDv1::AliPHOSPIDv1(const AliPHOSPIDv1 & pid ) : 
     185           0 :   AliPHOSPID(pid),
     186           0 :   fBayesian(kFALSE),
     187           0 :   fDefaultInit(kFALSE),
     188           0 :   fWrite(kFALSE),
     189           0 :   fFileNamePrincipalPhoton(),
     190           0 :   fFileNamePrincipalPi0(),
     191           0 :   fFileNameParameters(),
     192           0 :   fPrincipalPhoton(0),
     193           0 :   fPrincipalPi0(0),
     194           0 :   fX(0),
     195           0 :   fPPhoton(0),
     196           0 :   fPPi0(0),
     197           0 :   fParameters(0),
     198           0 :   fVtx(0.,0.,0.), 
     199           0 :   fTFphoton(0),
     200           0 :   fTFpiong(0),
     201           0 :   fTFkaong(0),
     202           0 :   fTFkaonl(0),
     203           0 :   fTFhhadrong(0),
     204           0 :   fTFhhadronl(0),
     205           0 :   fDFmuon(0),
     206           0 :   fERecWeight(0),
     207           0 :   fChargedNeutralThreshold(0.),
     208           0 :   fTOFEnThreshold(0),
     209           0 :   fDispEnThreshold(0),
     210           0 :   fDispMultThreshold(0)
     211             : 
     212           0 : { 
     213             :   // ctor
     214           0 :   InitParameters() ; 
     215             : 
     216           0 : }
     217             : 
     218             : //____________________________________________________________________________
     219             : AliPHOSPIDv1::AliPHOSPIDv1(AliPHOSGeometry *geom):
     220           2 :   AliPHOSPID(geom),
     221           2 :   fBayesian(kFALSE),
     222           2 :   fDefaultInit(kFALSE),
     223           2 :   fWrite(kFALSE),
     224           2 :   fFileNamePrincipalPhoton(),
     225           2 :   fFileNamePrincipalPi0(),
     226           2 :   fFileNameParameters(),
     227           2 :   fPrincipalPhoton(0),
     228           2 :   fPrincipalPi0(0),
     229           2 :   fX(0),
     230           2 :   fPPhoton(0),
     231           2 :   fPPi0(0),
     232           2 :   fParameters(0),
     233           2 :   fVtx(0.,0.,0.), 
     234           2 :   fTFphoton(0),
     235           2 :   fTFpiong(0),
     236           2 :   fTFkaong(0),
     237           2 :   fTFkaonl(0),
     238           2 :   fTFhhadrong(0),
     239           2 :   fTFhhadronl(0),
     240           2 :   fDFmuon(0),
     241           2 :   fERecWeight(0),
     242           2 :   fChargedNeutralThreshold(0.),
     243           2 :   fTOFEnThreshold(0),
     244           2 :   fDispEnThreshold(0),
     245           2 :   fDispMultThreshold(0)
     246             : 
     247          10 : { 
     248             :   //ctor with the indication on where to look for the track segments
     249             :  
     250           2 :   InitParameters() ; 
     251           2 :   fDefaultInit = kFALSE ; 
     252           4 : }
     253             : 
     254             : //____________________________________________________________________________
     255             : AliPHOSPIDv1::~AliPHOSPIDv1()
     256          12 : { 
     257             :   // dtor
     258           2 :   fPrincipalPhoton = 0;
     259           2 :   fPrincipalPi0 = 0;
     260             : 
     261           4 :   delete [] fX ;       // Principal input 
     262           4 :   delete [] fPPhoton ; // Photon Principal components
     263           4 :   delete [] fPPi0 ;    // Pi0 Principal components
     264             : 
     265           4 :   delete fParameters;
     266           4 :   delete fTFphoton;
     267           4 :   delete fTFpiong;
     268           4 :   delete fTFkaong;
     269           4 :   delete fTFkaonl;
     270           4 :   delete fTFhhadrong;
     271           4 :   delete fTFhhadronl;
     272           4 :   delete fDFmuon;
     273           6 : }
     274             :  
     275             : //____________________________________________________________________________
     276             : void AliPHOSPIDv1::InitParameters()
     277             : {
     278             :   // Initialize PID parameters
     279           4 :   fWrite                   = kTRUE ;
     280           2 :   fBayesian          = kTRUE ;
     281           2 :   SetParameters() ; // fill the parameters matrix from parameters file
     282             : 
     283             :   // initialisation of response function parameters
     284             :   // Tof
     285             : 
     286             : //   // Photons
     287             : //   fTphoton[0] = 0.218    ;
     288             : //   fTphoton[1] = 1.55E-8  ; 
     289             : //   fTphoton[2] = 5.05E-10 ;
     290             : //   fTFphoton = new TFormula("ToF response to photons" , "gaus") ; 
     291             : //   fTFphoton->SetParameters( fTphoton[0], fTphoton[1], fTphoton[2]) ; 
     292             : 
     293             : //   // Pions
     294             : //   //Gaus (0 to max probability)
     295             : //   fTpiong[0] = 0.0971    ; 
     296             : //   fTpiong[1] = 1.58E-8  ; 
     297             : //   fTpiong[2] = 5.69E-10 ;
     298             : //   fTFpiong = new TFormula("ToF response to pions" , "gaus") ; 
     299             : //   fTFpiong->SetParameters( fTpiong[0], fTpiong[1], fTpiong[2]) ; 
     300             : 
     301             : //   // Kaons
     302             : //   //Gaus (0 to max probability)
     303             : //   fTkaong[0] = 0.0542  ; 
     304             : //   fTkaong[1] = 1.64E-8 ; 
     305             : //   fTkaong[2] = 6.07E-10 ;
     306             : //   fTFkaong = new TFormula("ToF response to kaon" , "gaus") ; 
     307             : //   fTFkaong->SetParameters( fTkaong[0], fTkaong[1], fTkaong[2]) ; 
     308             : //   //Landau (max probability to inf) 
     309             : //   fTkaonl[0] = 0.264   ;
     310             : //   fTkaonl[1] = 1.68E-8  ; 
     311             : //   fTkaonl[2] = 4.10E-10 ;
     312             : //   fTFkaonl = new TFormula("ToF response to kaon" , "landau") ; 
     313             : //   fTFkaonl->SetParameters( fTkaonl[0], fTkaonl[1], fTkaonl[2]) ; 
     314             : 
     315             : //   //Heavy Hadrons
     316             : //   //Gaus (0 to max probability)
     317             : //   fThhadrong[0] = 0.0302   ;  
     318             : //   fThhadrong[1] = 1.73E-8  ; 
     319             : //   fThhadrong[2] = 9.52E-10 ;
     320             : //   fTFhhadrong = new TFormula("ToF response to heavy hadrons" , "gaus") ; 
     321             : //   fTFhhadrong->SetParameters( fThhadrong[0], fThhadrong[1], fThhadrong[2]) ; 
     322             : //   //Landau (max probability to inf) 
     323             : //   fThhadronl[0] = 0.139    ;  
     324             : //   fThhadronl[1] = 1.745E-8  ; 
     325             : //   fThhadronl[2] = 1.00E-9  ;
     326             : //   fTFhhadronl = new TFormula("ToF response to heavy hadrons" , "landau") ; 
     327             : //   fTFhhadronl->SetParameters( fThhadronl[0], fThhadronl[1], fThhadronl[2]) ; 
     328             : 
     329             :   // Photons
     330           2 :   fTphoton[0] = 7.83E8   ;
     331           2 :   fTphoton[1] = 1.55E-8  ; 
     332           2 :   fTphoton[2] = 5.09E-10 ;
     333           4 :   fTFphoton = new TFormula("ToF response to photons" , "gaus") ; 
     334           2 :   fTFphoton->SetParameters( fTphoton[0], fTphoton[1], fTphoton[2]) ; 
     335             : 
     336             :   // Pions
     337             :   //Gaus (0 to max probability)
     338           2 :   fTpiong[0] = 6.73E8    ; 
     339           2 :   fTpiong[1] = 1.58E-8  ; 
     340           2 :   fTpiong[2] = 5.87E-10 ;
     341           4 :   fTFpiong = new TFormula("ToF response to pions" , "gaus") ; 
     342           2 :   fTFpiong->SetParameters( fTpiong[0], fTpiong[1], fTpiong[2]) ; 
     343             : 
     344             :   // Kaons
     345             :   //Gaus (0 to max probability)
     346           2 :   fTkaong[0] = 3.93E8  ; 
     347           2 :   fTkaong[1] = 1.64E-8 ; 
     348           2 :   fTkaong[2] = 6.07E-10 ;
     349           4 :   fTFkaong = new TFormula("ToF response to kaon" , "gaus") ; 
     350           2 :   fTFkaong->SetParameters( fTkaong[0], fTkaong[1], fTkaong[2]) ; 
     351             :   //Landau (max probability to inf) 
     352           2 :   fTkaonl[0] = 2.0E9    ;
     353           2 :   fTkaonl[1] = 1.68E-8  ; 
     354           2 :   fTkaonl[2] = 4.10E-10 ;
     355           4 :   fTFkaonl = new TFormula("ToF response to kaon" , "landau") ; 
     356           2 :   fTFkaonl->SetParameters( fTkaonl[0], fTkaonl[1], fTkaonl[2]) ; 
     357             : 
     358             :   //Heavy Hadrons
     359             :   //Gaus (0 to max probability)
     360           2 :   fThhadrong[0] = 2.02E8   ;  
     361           2 :   fThhadrong[1] = 1.73E-8  ; 
     362           2 :   fThhadrong[2] = 9.52E-10 ;
     363           4 :   fTFhhadrong = new TFormula("ToF response to heavy hadrons" , "gaus") ; 
     364           2 :   fTFhhadrong->SetParameters( fThhadrong[0], fThhadrong[1], fThhadrong[2]) ; 
     365             :   //Landau (max probability to inf) 
     366           2 :   fThhadronl[0] = 1.10E9    ;  
     367           2 :   fThhadronl[1] = 1.74E-8   ; 
     368           2 :   fThhadronl[2] = 1.00E-9   ;
     369           4 :   fTFhhadronl = new TFormula("ToF response to heavy hadrons" , "landau") ; 
     370           2 :   fTFhhadronl->SetParameters( fThhadronl[0], fThhadronl[1], fThhadronl[2]) ; 
     371             : 
     372             : 
     373             : 
     374             :   // Shower shape: dispersion gaussian parameters
     375             :   // Photons
     376             :   
     377             : //   fDphoton[0] = 4.62e-2;  fDphoton[1] = 1.39e-2 ; fDphoton[2] = -3.80e-2;//constant
     378             : //   fDphoton[3] = 1.53   ;  fDphoton[4] =-6.62e-2 ; fDphoton[5] = 0.339   ;//mean
     379             : //   fDphoton[6] = 6.89e-2;  fDphoton[7] =-6.59e-2 ; fDphoton[8] = 0.194   ;//sigma
     380             :   
     381             : //   fDpi0[0] = 0.0586  ;  fDpi0[1] = 1.06E-3 ; fDpi0[2] = 0.      ;//constant
     382             : //   fDpi0[3] = 2.67    ;  fDpi0[4] =-2.00E-2 ; fDpi0[5] = 9.37E-5 ;//mean
     383             : //   fDpi0[6] = 0.153   ;  fDpi0[7] = 9.34E-4 ; fDpi0[8] =-1.49E-5 ;//sigma
     384             :   
     385             : //   fDhadron[0] = 1.61E-2 ;  fDhadron[1] = 3.03E-3 ; fDhadron[2] = 1.01E-2 ;//constant
     386             : //   fDhadron[3] = 3.81    ;  fDhadron[4] = 0.232   ; fDhadron[5] =-1.25    ;//mean
     387             : //   fDhadron[6] = 0.897   ;  fDhadron[7] = 0.0987  ; fDhadron[8] =-0.534   ;//sigma
     388             :   
     389           2 :   fDphoton[0] = 1.5    ;  fDphoton[1] = 0.49    ; fDphoton[2] =-1.7E-2 ;//constant
     390           2 :   fDphoton[3] = 1.5    ;  fDphoton[4] = 4.0E-2  ; fDphoton[5] = 0.21   ;//mean
     391           2 :   fDphoton[6] = 4.8E-2 ;  fDphoton[7] =-0.12    ; fDphoton[8] = 0.27   ;//sigma
     392           2 :   fDphoton[9] = 16.; //for E>  fDphoton[9] parameters calculated at  fDphoton[9]
     393             : 
     394           2 :   fDpi0[0] = 0.25      ;  fDpi0[1] = 3.3E-2     ; fDpi0[2] =-1.0e-5    ;//constant
     395           2 :   fDpi0[3] = 1.50      ;  fDpi0[4] = 398.       ; fDpi0[5] = 12.       ;//mean
     396           2 :   fDpi0[6] =-7.0E-2    ;  fDpi0[7] =-524.       ; fDpi0[8] = 22.       ;//sigma
     397           2 :   fDpi0[9] = 110.; //for E>  fDpi0[9] parameters calculated at  fDpi0[9]
     398             : 
     399           2 :   fDhadron[0] = 6.5    ;  fDhadron[1] =-5.3     ; fDhadron[2] = 1.5    ;//constant
     400           2 :   fDhadron[3] = 3.8    ;  fDhadron[4] = 0.23    ; fDhadron[5] =-1.2    ;//mean
     401           2 :   fDhadron[6] = 0.88   ;  fDhadron[7] = 9.3E-2  ; fDhadron[8] =-0.51   ;//sigma
     402           2 :   fDhadron[9] = 2.; //for E>  fDhadron[9] parameters calculated at  fDhadron[9]
     403             : 
     404           2 :   fDmuon[0] = 0.0631 ;
     405           2 :   fDmuon[1] = 1.4    ; 
     406           2 :   fDmuon[2] = 0.0557 ;
     407           4 :   fDFmuon = new TFormula("Shower shape response to muons" , "landau") ; 
     408           2 :   fDFmuon->SetParameters( fDmuon[0], fDmuon[1], fDmuon[2]) ; 
     409             : 
     410             : 
     411             :   // x(CPV-EMC) distance gaussian parameters
     412             :   
     413             : //   fXelectron[0] = 8.06e-2 ;  fXelectron[1] = 1.00e-2; fXelectron[2] =-5.14e-2;//constant
     414             : //   fXelectron[3] = 0.202   ;  fXelectron[4] = 8.15e-3; fXelectron[5] = 4.55   ;//mean
     415             : //   fXelectron[6] = 0.334   ;  fXelectron[7] = 0.186  ; fXelectron[8] = 4.32e-2;//sigma
     416             :   
     417             : //   //charged hadrons gaus
     418             : //   fXcharged[0] = 6.43e-3 ;  fXcharged[1] =-4.19e-5; fXcharged[2] = 1.42e-3;//constant
     419             : //   fXcharged[3] = 2.75    ;  fXcharged[4] =-0.40   ; fXcharged[5] = 1.68   ;//mean
     420             : //   fXcharged[6] = 3.135   ;  fXcharged[7] =-9.41e-2; fXcharged[8] = 1.31e-2;//sigma
     421             :   
     422             : //   // z(CPV-EMC) distance gaussian parameters
     423             :   
     424             : //   fZelectron[0] = 8.22e-2 ;  fZelectron[1] = 5.11e-3; fZelectron[2] =-3.05e-2;//constant
     425             : //   fZelectron[3] = 3.09e-2 ;  fZelectron[4] = 5.87e-2; fZelectron[5] =-9.49e-2;//mean
     426             : //   fZelectron[6] = 0.263   ;  fZelectron[7] =-9.02e-3; fZelectron[8] = 0.151 ;//sigma
     427             :   
     428             : //   //charged hadrons gaus
     429             :   
     430             : //   fZcharged[0] = 1.00e-2 ;  fZcharged[1] = 2.82E-4 ; fZcharged[2] = 2.87E-3 ;//constant
     431             : //   fZcharged[3] =-4.68e-2 ;  fZcharged[4] =-9.21e-3 ; fZcharged[5] = 4.91e-2 ;//mean
     432             : //   fZcharged[6] = 1.425   ;  fZcharged[7] =-5.90e-2 ; fZcharged[8] = 5.07e-2 ;//sigma
     433             : 
     434             : 
     435           2 :   fXelectron[0] =-1.6E-2 ;  fXelectron[1] = 0.77  ; fXelectron[2] =-0.15 ;//constant
     436           2 :   fXelectron[3] = 0.35   ;  fXelectron[4] = 0.25  ; fXelectron[5] = 4.12 ;//mean
     437           2 :   fXelectron[6] = 0.30   ;  fXelectron[7] = 0.11  ; fXelectron[8] = 0.16 ;//sigma
     438           2 :   fXelectron[9] = 3.; //for E>  fXelectron[9] parameters calculated at  fXelectron[9]
     439             : 
     440             :   //charged hadrons gaus
     441           2 :   fXcharged[0] = 0.14    ;  fXcharged[1] =-3.0E-2 ; fXcharged[2] = 0     ;//constant
     442           2 :   fXcharged[3] = 1.4     ;  fXcharged[4] =-9.3E-2 ; fXcharged[5] = 1.4   ;//mean
     443           2 :   fXcharged[6] = 5.7     ;  fXcharged[7] = 0.27   ; fXcharged[8] =-1.8   ;//sigma
     444           2 :   fXcharged[9] = 1.2; //for E>  fXcharged[9] parameters calculated at  fXcharged[9]
     445             : 
     446             :   // z(CPV-EMC) distance gaussian parameters
     447             :   
     448           2 :   fZelectron[0] = 0.49   ;  fZelectron[1] = 0.53   ; fZelectron[2] =-9.8E-2 ;//constant
     449           2 :   fZelectron[3] = 2.8E-2 ;  fZelectron[4] = 5.0E-2 ; fZelectron[5] =-8.2E-2 ;//mean
     450           2 :   fZelectron[6] = 0.25   ;  fZelectron[7] =-1.7E-2 ; fZelectron[8] = 0.17   ;//sigma
     451           2 :   fZelectron[9] = 3.; //for E>  fZelectron[9] parameters calculated at  fZelectron[9]
     452             : 
     453             :   //charged hadrons gaus
     454             :   
     455           2 :   fZcharged[0] = 0.46    ;  fZcharged[1] =-0.65    ; fZcharged[2] = 0.52    ;//constant
     456           2 :   fZcharged[3] = 1.1E-2  ;  fZcharged[4] = 0.      ; fZcharged[5] = 0.      ;//mean
     457           2 :   fZcharged[6] = 0.60    ;  fZcharged[7] =-8.2E-2  ; fZcharged[8] = 0.45    ;//sigma
     458           2 :   fZcharged[9] = 1.2; //for E>  fXcharged[9] parameters calculated at  fXcharged[9]
     459             : 
     460             :   //Threshold to differentiate between charged and neutral
     461           2 :   fChargedNeutralThreshold = 1e-5;
     462           2 :   fTOFEnThreshold          = 2;          //Maximum energy to use TOF
     463           2 :   fDispEnThreshold         = 0.5;       //Minimum energy to use shower shape
     464           2 :   fDispMultThreshold       = 3;       //Minimum multiplicity to use shower shape
     465             : 
     466             :   //Weight to hadrons recontructed energy
     467             : 
     468           2 :   fERecWeightPar[0] = 0.32 ; 
     469           2 :   fERecWeightPar[1] = 3.8  ;
     470           2 :   fERecWeightPar[2] = 5.4E-3 ; 
     471           2 :   fERecWeightPar[3] = 5.6E-2 ;
     472           4 :   fERecWeight = new TFormula("Weight for hadrons" , "[0]*exp(-x*[1])+[2]*exp(-x*[3])") ; 
     473           2 :   fERecWeight ->SetParameters(fERecWeightPar[0],fERecWeightPar[1] ,fERecWeightPar[2] ,fERecWeightPar[3]) ; 
     474             : 
     475             : 
     476          60 :   for (Int_t i =0; i<  AliPID::kSPECIESCN ; i++)
     477          28 :     fInitPID[i] = 1.;
     478             :  
     479           2 : }
     480             : 
     481             : //________________________________________________________________________
     482             : void  AliPHOSPIDv1::TrackSegments2RecParticles(Option_t *option)
     483             : {
     484             :   // Steering method to perform particle reconstruction and identification
     485             :   // for the event range from fFirstEvent to fLastEvent.
     486             :   
     487          16 :   if(strstr(option,"tim"))
     488           0 :     gBenchmark->Start("PHOSPID");
     489             :   
     490           8 :   if(strstr(option,"print")) {
     491           0 :     Print() ; 
     492           0 :     return ; 
     493             :   }
     494             : 
     495          16 :   if(fTrackSegments && //Skip events, where no track segments made
     496           8 :      fTrackSegments->GetEntriesFast()) {
     497             : 
     498           8 :     GetVertex() ;
     499           8 :     MakeRecParticles() ;
     500             : 
     501           8 :     if(fBayesian)
     502           8 :       MakePID() ; 
     503             :       
     504           8 :     if(strstr(option,"deb"))
     505           0 :       PrintRecParticles(option) ;    
     506             :   }
     507             : 
     508           8 :   if(strstr(option,"deb"))
     509           0 :       PrintRecParticles(option);
     510           8 :   if(strstr(option,"tim")){
     511           0 :     gBenchmark->Stop("PHOSPID");
     512           0 :     AliInfo(Form("took %f seconds for PID", 
     513             :                  gBenchmark->GetCpuTime("PHOSPID")));  
     514           0 :   }
     515           8 : }
     516             : 
     517             : //________________________________________________________________________
     518             : Double_t  AliPHOSPIDv1::GausF(Double_t  x, Double_t  y, Double_t * par)
     519             : {
     520             :   //Given the energy x and the parameter y (tof, shower dispersion or cpv-emc distance), 
     521             :   //this method returns a density probability of this parameter, given by a gaussian 
     522             :   //function whose parameters depend with the energy  with a function: a/(x*x)+b/x+b
     523             :   //Float_t xorg = x;
     524         140 :   if (x > par[9]) x = par[9];
     525             :   
     526             :   //Double_t cnt    = par[1] / (x*x) + par[2] / x + par[0] ;
     527          50 :   Double_t cnt    = par[0] + par[1] * x + par[2] * x * x ;
     528          50 :   Double_t mean   = par[4] / (x*x) + par[5] / x + par[3] ;
     529          50 :   Double_t sigma  = par[7] / (x*x) + par[8] / x + par[6] ;
     530             :  
     531             : //   if(xorg > 30)
     532             : //     cout<<"En_in = "<<xorg<<"; En_out = "<<x<<"; cnt = "<<cnt
     533             : //      <<"; mean = "<<mean<<"; sigma = "<<sigma<<endl;
     534             :       
     535             :   //  Double_t arg    = - (y-mean) * (y-mean) / (2*sigma*sigma) ;
     536             :   //  return cnt * TMath::Exp(arg) ;
     537          50 :   if(TMath::Abs(sigma) > 1.e-10){
     538          50 :     return cnt*TMath::Gaus(y,mean,sigma);
     539             :   }
     540             :   else
     541           0 :     return 0.;
     542             :  
     543          50 : }
     544             : //________________________________________________________________________
     545             : Double_t  AliPHOSPIDv1::GausPol2(Double_t  x, Double_t y, Double_t * par)
     546             : {
     547             :   //Given the energy x and the parameter y (tof, shower dispersion or cpv-emc distance), 
     548             :   //this method returns a density probability of this parameter, given by a gaussian 
     549             :   //function whose parameters depend with the energy like second order polinomial
     550             : 
     551           0 :   Double_t cnt    = par[0] + par[1] * x + par[2] * x * x ;
     552           0 :   Double_t mean   = par[3] + par[4] * x + par[5] * x * x ;
     553           0 :   Double_t sigma  = par[6] + par[7] * x + par[8] * x * x ;
     554             : 
     555           0 :   if(TMath::Abs(sigma) > 1.e-10){
     556           0 :     return cnt*TMath::Gaus(y,mean,sigma);
     557             :   }
     558             :   else
     559           0 :     return 0.;
     560             :  
     561             : 
     562             : 
     563           0 : }
     564             : 
     565             : //____________________________________________________________________________
     566             : const TString AliPHOSPIDv1::GetFileNamePrincipal(TString particle) const
     567             : {
     568             :   //Get file name that contains the PCA for a particle ("photon or pi0")
     569           0 :   particle.ToLower();
     570           0 :   TString name;
     571           0 :   if      (particle=="photon") 
     572           0 :     name = fFileNamePrincipalPhoton ;
     573           0 :   else if (particle=="pi0"   ) 
     574           0 :     name = fFileNamePrincipalPi0    ;
     575             :   else    
     576           0 :     AliError(Form("Wrong particle name: %s (choose from pi0/photon)\n",
     577             :                   particle.Data()));
     578             :   return name;
     579           0 : }
     580             : 
     581             : //____________________________________________________________________________
     582             : Float_t  AliPHOSPIDv1::GetParameterCalibration(Int_t i) const 
     583             : {
     584             :   // Get the i-th parameter "Calibration"
     585             :   Float_t param = 0.;
     586           0 :   if (i>2 || i<0) { 
     587           0 :     AliError(Form("Invalid parameter number: %d",i));
     588           0 :   } else
     589           0 :     param = (*fParameters)(0,i);
     590           0 :   return param;
     591             : }
     592             : 
     593             : //____________________________________________________________________________
     594             : Float_t  AliPHOSPIDv1::GetParameterCpv2Emc(Int_t i, TString axis) const 
     595             : {
     596             :   // Get the i-th parameter "CPV-EMC distance" for the specified axis
     597             :   Float_t param = 0.;
     598         360 :   if(i>2 || i<0) {
     599           0 :     AliError(Form("Invalid parameter number: %d",i));
     600           0 :   } else {
     601         180 :     axis.ToLower();
     602         180 :     if      (axis == "x") 
     603          90 :       param = (*fParameters)(1,i);
     604          90 :     else if (axis == "z") 
     605          90 :       param = (*fParameters)(2,i);
     606             :     else { 
     607           0 :       AliError(Form("Invalid axis name: %s",axis.Data()));
     608             :     }
     609             :   }
     610         180 :   return  param;
     611             : }
     612             : 
     613             : //____________________________________________________________________________
     614             : Float_t  AliPHOSPIDv1::GetCpv2EmcDistanceCut(TString axis, Float_t e) const
     615             : {
     616             :   // Get CpvtoEmcDistance Cut depending on the cluster energy, axis and 
     617             :   // Purity-Efficiency point 
     618             : 
     619         120 :   axis.ToLower();
     620          60 :   Float_t p[]={0.,0.,0.};
     621         660 :   for (Int_t i=0; i<3; i++) p[i] = GetParameterCpv2Emc(i,axis);
     622          60 :   Float_t sig = p[0] + TMath::Exp(p[1] - p[2]*e);
     623          60 :   return sig;
     624          60 : }
     625             : 
     626             : //____________________________________________________________________________
     627             : Float_t  AliPHOSPIDv1::GetEllipseParameter(TString particle, TString param, Float_t e) const 
     628             : {
     629             :   // Calculates the parameter param of the ellipse
     630             : 
     631         600 :   particle.ToLower();
     632         300 :   param.   ToLower();
     633         300 :   Float_t p[4]={0.,0.,0.,0.};
     634             :   Float_t value = 0.0;
     635        5400 :   for (Int_t i=0; i<4; i++) p[i] = GetParameterToCalculateEllipse(particle,param,i);
     636         300 :   if (particle == "photon") {
     637         180 :     if      (param.Contains("a"))  e = TMath::Min((Double_t)e,70.);
     638         150 :     else if (param.Contains("b"))  e = TMath::Min((Double_t)e,70.);
     639         120 :     else if (param.Contains("x0")) e = TMath::Max((Double_t)e,1.1);
     640             :   }
     641             : 
     642         300 :  if (particle == "photon")
     643         150 :     value = p[0]/TMath::Sqrt(e) + p[1]*e + p[2]*e*e + p[3];
     644         150 :   else if (particle == "pi0")
     645         150 :     value = p[0] + p[1]*e + p[2]*e*e;
     646             : 
     647         300 :   return value;
     648         300 : }
     649             : 
     650             : //_____________________________________________________________________________
     651             : Float_t  AliPHOSPIDv1::GetParameterPhotonBoundary (Int_t i) const
     652             : { 
     653             :   // Get the parameter "i" to calculate the boundary on the moment M2x
     654             :   // for photons at high p_T
     655             :   Float_t param = 0;
     656           0 :   if (i>3 || i<0) {
     657           0 :     AliError(Form("Wrong parameter number: %d\n",i));
     658           0 :   } else
     659           0 :     param = (*fParameters)(14,i) ;
     660           0 :   return param;
     661             : }
     662             : 
     663             : //____________________________________________________________________________
     664             : Float_t  AliPHOSPIDv1::GetParameterPi0Boundary (Int_t i) const
     665             : { 
     666             :   // Get the parameter "i" to calculate the boundary on the moment M2x
     667             :   // for pi0 at high p_T
     668             :   Float_t param = 0;
     669           0 :   if (i>2 || i<0) {
     670           0 :     AliError(Form("Wrong parameter number: %d\n",i));
     671           0 :   } else
     672           0 :     param = (*fParameters)(15,i) ;
     673           0 :   return param;
     674             : }
     675             : 
     676             : //____________________________________________________________________________
     677             : Float_t  AliPHOSPIDv1::GetParameterTimeGate(Int_t i) const
     678             : {
     679             :   // Get TimeGate parameter depending on Purity-Efficiency i:
     680             :   // i=0 - Low purity, i=1 - Medium purity, i=2 - High purity
     681             :   Float_t param = 0.;
     682           0 :   if(i>2 || i<0) {
     683           0 :     AliError(Form("Invalid Efficiency-Purity choice %d",i));
     684           0 :   } else
     685           0 :     param = (*fParameters)(3,i) ; 
     686           0 :   return param;
     687             : }
     688             : 
     689             : //_____________________________________________________________________________
     690             : Float_t  AliPHOSPIDv1::GetParameterToCalculateEllipse(TString particle, TString param, Int_t i) const
     691             : { 
     692             :   // Get the parameter "i" that is needed to calculate the ellipse 
     693             :   // parameter "param" for the particle "particle" ("photon" or "pi0")
     694             : 
     695        2400 :   particle.ToLower();
     696        1200 :   param.   ToLower();
     697             :   Int_t offset = -1;
     698        1200 :   if      (particle == "photon") 
     699         600 :     offset=0;
     700         600 :   else if (particle == "pi0")    
     701         600 :     offset=5;
     702             :   else
     703           0 :     AliError(Form("Wrong particle name: %s (choose from pi0/photon)\n",
     704             :                   particle.Data()));
     705             : 
     706             :   Int_t p= -1;
     707             :   Float_t par = 0;
     708             : 
     709        1440 :   if     (param.Contains("a")) p=4+offset; 
     710        1200 :   else if(param.Contains("b")) p=5+offset; 
     711         960 :   else if(param.Contains("c")) p=6+offset; 
     712         720 :   else if(param.Contains("x0"))p=7+offset; 
     713         480 :   else if(param.Contains("y0"))p=8+offset;
     714             : 
     715        1200 :   if      (i>4 || i<0) {
     716           0 :     AliError(Form("No parameter with index %d", i)) ; 
     717        1200 :   } else if (p==-1) {
     718           0 :     AliError(Form("No parameter with name %s", param.Data() )) ; 
     719           0 :   } else
     720        1200 :     par = (*fParameters)(p,i) ;
     721             :   
     722        1200 :   return par;
     723             : }
     724             : //____________________________________________________________________________
     725             : Int_t  AliPHOSPIDv1::GetCPVBit(AliPHOSTrackSegment * ts, Int_t effPur, Float_t e) const
     726             : {
     727             :   //Calculates the pid bit for the CPV selection per each purity.
     728          60 :   if(effPur>2 || effPur<0)
     729           0 :     AliError(Form("Invalid Efficiency-Purity choice %d",effPur));
     730             : 
     731             : //DP  if(ts->GetCpvIndex()<0)
     732             : //DP    return 1 ; //no CPV cluster
     733             :   
     734          60 :   Float_t sigX = GetCpv2EmcDistanceCut("X",e);
     735          60 :   Float_t sigZ = GetCpv2EmcDistanceCut("Z",e);
     736             :   
     737          30 :   Float_t deltaX = TMath::Abs(ts->GetCpvDistance("X"));
     738          30 :   Float_t deltaZ = TMath::Abs(ts->GetCpvDistance("Z"));
     739             : //  Info("GetCPVBit"," xdist %f, sigx %f, zdist %f, sigz %f",deltaX, sigX, deltaZ,sigZ) ;
     740             :  
     741             :   //if(deltaX>sigX*(effPur+1))
     742             :   //if((deltaX>sigX*(effPur+1)) || (deltaZ>sigZ*(effPur+1)))
     743          50 :   if((deltaX>sigX*(effPur+1)) && (deltaZ>sigZ*(effPur+1)))
     744          18 :     return 1;//Neutral
     745             :   else
     746          12 :     return 0;//Charged
     747          30 : }
     748             : 
     749             : //____________________________________________________________________________
     750             : Int_t  AliPHOSPIDv1::GetPrincipalBit(TString particle, const Double_t* p, Int_t effPur, Float_t e)const
     751             : {
     752             :   //Is the particle inside de PCA ellipse?
     753             :   
     754         120 :   particle.ToLower();
     755             :   Int_t    prinbit  = 0 ;
     756         180 :   Float_t a  = GetEllipseParameter(particle,"a" , e); 
     757         180 :   Float_t b  = GetEllipseParameter(particle,"b" , e);
     758         180 :   Float_t c  = GetEllipseParameter(particle,"c" , e);
     759         180 :   Float_t x0 = GetEllipseParameter(particle,"x0", e); 
     760         180 :   Float_t y0 = GetEllipseParameter(particle,"y0", e);
     761             :   
     762         180 :   Float_t r = TMath::Power((p[0] - x0)/a,2) + 
     763         120 :               TMath::Power((p[1] - y0)/b,2) +
     764          60 :             c*(p[0] -  x0)*(p[1] - y0)/(a*b) ;
     765             :   //3 different ellipses defined
     766          88 :   if((effPur==2) && (r<1./2.)) prinbit= 1;
     767          90 :   if((effPur==1) && (r<2.   )) prinbit= 1;
     768          90 :   if((effPur==0) && (r<9./2.)) prinbit= 1;
     769             : 
     770          60 :   if(r<0)
     771           0 :     AliError("Negative square?") ;
     772             : 
     773          60 :   return prinbit;
     774             : 
     775           0 : }
     776             : //____________________________________________________________________________
     777             : Int_t  AliPHOSPIDv1::GetHardPhotonBit(AliPHOSEmcRecPoint * emc) const
     778             : {
     779             :   // Set bit for identified hard photons (E > 30 GeV)
     780             :   // if the second moment M2x is below the boundary
     781             : 
     782          20 :   Float_t e   = emc->GetEnergy();
     783          20 :   if (e < 30.0) return 0;
     784           0 :   Float_t m2x = emc->GetM2x();
     785           0 :   Float_t m2xBoundary = GetParameterPhotonBoundary(0) *
     786           0 :     TMath::Exp(-TMath::Power(e-GetParameterPhotonBoundary(1),2)/2.0/
     787           0 :                 TMath::Power(GetParameterPhotonBoundary(2),2)) +
     788           0 :     GetParameterPhotonBoundary(3);
     789           0 :   AliDebug(1, Form("E=%f, m2x=%f, boundary=%f", e,m2x,m2xBoundary));
     790           0 :   if (m2x < m2xBoundary)
     791           0 :     return 1;// A hard photon
     792             :   else
     793           0 :     return 0;// Not a hard photon
     794          10 : }
     795             : 
     796             : //____________________________________________________________________________
     797             : Int_t  AliPHOSPIDv1::GetHardPi0Bit(AliPHOSEmcRecPoint * emc) const
     798             : {
     799             :   // Set bit for identified hard pi0  (E > 30 GeV)
     800             :   // if the second moment M2x is above the boundary
     801             : 
     802          20 :   Float_t e   = emc->GetEnergy();
     803          20 :   if (e < 30.0) return 0;
     804           0 :   Float_t m2x = emc->GetM2x();
     805           0 :   Float_t m2xBoundary = GetParameterPi0Boundary(0) +
     806           0 :                     e * GetParameterPi0Boundary(1);
     807           0 :   AliDebug(1,Form("E=%f, m2x=%f, boundary=%f",e,m2x,m2xBoundary));
     808           0 :   if (m2x > m2xBoundary)
     809           0 :     return 1;// A hard pi0
     810             :   else
     811           0 :     return 0;// Not a hard pi0
     812          10 : }
     813             : 
     814             : //____________________________________________________________________________
     815             : TVector3 AliPHOSPIDv1::GetMomentumDirection(AliPHOSEmcRecPoint * emc, AliPHOSCpvRecPoint * )const 
     816             : { 
     817             :   // Calculates the momentum direction:
     818             :   //   1. if only a EMC RecPoint, direction is given by IP and this RecPoint
     819             :   //   2. if a EMC RecPoint and CPV RecPoint, direction is given by the line through the 2 recpoints 
     820             :   //  However because of the poor position resolution of PPSD the direction is always taken as if we were 
     821             :   //  in case 1.
     822             : 
     823          20 :   TVector3 local ; 
     824          10 :   emc->GetLocalPosition(local) ;
     825             : 
     826          10 :   AliPHOSGeometry * phosgeom = AliPHOSGeometry::GetInstance() ;
     827             :   //Correct for the non-perpendicular incidence
     828             :   // Correction for the depth of the shower starting point (TDR p 127)
     829             :   Float_t para = 0.925 ;
     830             :   Float_t parb = 6.52 ;
     831             :  
     832             :   //Remove Old correction (vertex at 0,0,0)
     833          10 :   TVector3 vtxOld(0.,0.,0.) ;
     834          10 :   TVector3 vInc ;
     835          10 :   Float_t x=local.X() ;
     836          10 :   Float_t z=local.Z() ;
     837          20 :   phosgeom->GetIncidentVector(vtxOld,emc->GetPHOSMod(),x,z,vInc) ;
     838             :   Float_t depthxOld = 0.;
     839             :   Float_t depthzOld = 0.;
     840          10 :   Float_t energy = emc->GetEnergy() ;
     841          20 :   if (energy > 0 && vInc.Y()!=0.) {
     842          10 :     depthxOld = ( para * TMath::Log(energy) + parb ) * vInc.X()/TMath::Abs(vInc.Y()) ;
     843          10 :     depthzOld = ( para * TMath::Log(energy) + parb ) * vInc.Z()/TMath::Abs(vInc.Y()) ;
     844          10 :   }
     845             :   else{
     846           0 :     AliError("Cluster with zero energy \n");
     847             :   }
     848             :   //Apply Real vertex
     849          20 :   phosgeom->GetIncidentVector(fVtx,emc->GetPHOSMod(),x,z,vInc) ;
     850             :   Float_t depthx = 0.;
     851             :   Float_t depthz = 0.;
     852          20 :   if (energy > 0 && vInc.Y()!=0.) {
     853          10 :     depthx = ( para * TMath::Log(energy) + parb ) * vInc.X()/TMath::Abs(vInc.Y()) ;
     854          10 :     depthz = ( para * TMath::Log(energy) + parb ) * vInc.Z()/TMath::Abs(vInc.Y()) ;
     855          10 :   }
     856             : 
     857             :   //Correct for the vertex position and shower depth
     858          10 :   Double_t xd=x+(depthxOld-depthx) ;
     859          10 :   Double_t zd=z+(depthzOld-depthz) ; 
     860          10 :   TVector3 dir(0,0,0) ; 
     861          20 :   phosgeom->Local2Global(emc->GetPHOSMod(),xd,zd,dir) ;
     862             : 
     863          10 :   dir-=fVtx ;
     864          10 :   dir.SetMag(1.) ;
     865             : 
     866             :   return dir ;  
     867          20 : }
     868             : 
     869             : //________________________________________________________________________
     870             : Double_t  AliPHOSPIDv1::LandauF(Double_t  x, Double_t y, Double_t * par)
     871             : {
     872             :   //Given the energy x and the parameter y (tof, shower dispersion or cpv-emc distance), 
     873             :   //this method returns a density probability of this parameter, given by a landau 
     874             :   //function whose parameters depend with the energy  with a function: a/(x*x)+b/x+b
     875             : 
     876          30 :   if (x > par[9]) x = par[9];
     877             : 
     878             :   //Double_t cnt    = par[1] / (x*x) + par[2] / x + par[0] ;
     879          10 :   Double_t cnt    = par[0] + par[1] * x + par[2] * x * x ;
     880          10 :   Double_t mean   = par[4] / (x*x) + par[5] / x + par[3] ;
     881          10 :   Double_t sigma  = par[7] / (x*x) + par[8] / x + par[6] ;
     882             : 
     883          10 :   if(TMath::Abs(sigma) > 1.e-10){
     884          10 :     return cnt*TMath::Landau(y,mean,sigma);
     885             :   }
     886             :   else
     887           0 :     return 0.;
     888             : 
     889          10 : }
     890             : //________________________________________________________________________
     891             : Double_t  AliPHOSPIDv1::LandauPol2(Double_t  x, Double_t y, Double_t * par)
     892             : {
     893             : 
     894             :   //Given the energy x and the parameter y (tof, shower dispersion or cpv-emc distance), 
     895             :   //this method returns a density probability of this parameter, given by a landau 
     896             :   //function whose parameters depend with the energy like second order polinomial
     897             : 
     898           0 :   Double_t cnt    = par[2] * (x*x) + par[1] * x + par[0] ;
     899           0 :   Double_t mean   = par[5] * (x*x) + par[4] * x + par[3] ;
     900           0 :   Double_t sigma  = par[8] * (x*x) + par[7] * x + par[6] ;
     901             : 
     902           0 :    if(TMath::Abs(sigma) > 1.e-10){
     903           0 :     return cnt*TMath::Landau(y,mean,sigma);
     904             :   }
     905             :   else
     906           0 :     return 0.;
     907             : 
     908             : 
     909           0 : }
     910             : // //________________________________________________________________________
     911             : // Double_t  AliPHOSPIDv1::ChargedHadronDistProb(Double_t  x, Double_t y, Double_t * parg, Double_t * parl)
     912             : // {
     913             : //   Double_t cnt   = 0.0 ;
     914             : //   Double_t mean  = 0.0 ;
     915             : //   Double_t sigma = 0.0 ;
     916             : //   Double_t arg   = 0.0 ;
     917             : //   if (y < parl[4] / (x*x) + parl[5] / x + parl[3]){
     918             : //     cnt    = parg[1] / (x*x) + parg[2] / x + parg[0] ;
     919             : //     mean   = parg[4] / (x*x) + parg[5] / x + parg[3] ;
     920             : //     sigma  = parg[7] / (x*x) + parg[8] / x + parg[6] ;
     921             : //     TF1 * f = new TF1("gaus","gaus",0.,100.);
     922             : //     f->SetParameters(cnt,mean,sigma);
     923             : //     arg  = f->Eval(y) ;
     924             : //   }
     925             : //   else{
     926             : //     cnt    = parl[1] / (x*x) + parl[2] / x + parl[0] ;
     927             : //     mean   = parl[4] / (x*x) + parl[5] / x + parl[3] ;
     928             : //     sigma  = parl[7] / (x*x) + parl[8] / x + parl[6] ;
     929             : //     TF1 * f = new TF1("landau","landau",0.,100.);
     930             : //     f->SetParameters(cnt,mean,sigma);
     931             : //     arg  = f->Eval(y) ;
     932             : //   }
     933             : //   //  Double_t mean   = par[3] + par[4] * x + par[5] * x * x ;
     934             : //   //   Double_t sigma  = par[6] + par[7] * x + par[8] * x * x ;
     935             :   
     936             : //   //Double_t arg    = -(y-mean)*(y-mean)/(2*sigma*sigma) ;
     937             : //   //return cnt * TMath::Exp(arg) ;
     938             :   
     939             : //   return arg;
     940             :   
     941             : // }
     942             : //____________________________________________________________________________
     943             : void  AliPHOSPIDv1::MakePID()
     944             : {
     945             :   // construct the PID weight from a Bayesian Method
     946             :   
     947             :   const Int_t kSPECIES = AliPID::kSPECIESCN ;
     948             :  
     949          16 :   Int_t nparticles = fRecParticles->GetEntriesFast() ;
     950             : 
     951          24 :   if ( !fEMCRecPoints || !fCPVRecPoints || !fTrackSegments ) {
     952           0 :     AliFatal("RecPoints or TrackSegments not found !") ;  
     953           0 :   }
     954             : 
     955           8 :   Double_t * stof[kSPECIES] ;
     956           8 :   Double_t * sdp [kSPECIES]  ;
     957           8 :   Double_t * scpv[kSPECIES] ;
     958           8 :   Double_t * sw  [kSPECIES] ;
     959             :   //Info("MakePID","Begin MakePID"); 
     960             :   
     961         240 :           for (Int_t i =0; i< kSPECIES; i++){
     962         112 :             stof[i] = new Double_t[nparticles] ;
     963         112 :     sdp [i] = new Double_t[nparticles] ;
     964         112 :     scpv[i] = new Double_t[nparticles] ;
     965         112 :     sw  [i] = new Double_t[nparticles] ;
     966             :   }
     967             :   
     968          36 :   for(Int_t index = 0 ; index < nparticles ; index ++) {
     969             : 
     970          10 :     AliPHOSTrackSegment * ts = (AliPHOSTrackSegment *)fTrackSegments->At(index);
     971             :     
     972             :     //cout<<">>>>>> Bayesian Index "<<index<<endl;
     973          10 :     if(ts->GetEmcIndex()<0)
     974           0 :       continue ; //Do not analyze CPV TS
     975             : 
     976          10 :     AliPHOSEmcRecPoint * emc = (AliPHOSEmcRecPoint *) fEMCRecPoints->At(ts->GetEmcIndex()) ;
     977             :     
     978             : //    AliPHOSCpvRecPoint * cpv = 0 ;
     979             : //    if(ts->GetCpvIndex()>=0)
     980             : //      cpv = (AliPHOSCpvRecPoint *) cpvRecPoints->At(ts->GetCpvIndex()) ;
     981             : //    
     982             : ////     Int_t track = 0 ; 
     983             : ////     track = ts->GetTrackIndex() ; //TPC tracks ?
     984             :     
     985          10 :     if (!emc) {
     986           0 :       AliFatal(Form("-> emc(%d)", ts->GetEmcIndex())) ;
     987           0 :     }
     988             : 
     989             : 
     990             :     // ############Tof#############################
     991             : 
     992             :     //    Info("MakePID", "TOF");
     993          10 :     Float_t  en   = emc->GetEnergy();    
     994          10 :     Double_t time = emc->GetTime() ;
     995             :     //      cout<<">>>>>>>Energy "<<en<<"Time "<<time<<endl;
     996             :    
     997             :     // now get the signals probability
     998             :     // s(pid) in the Bayesian formulation
     999             : 
    1000             :     //Initialize anused species
    1001         300 :     for(Int_t iii=0; iii<kSPECIES; iii++)stof[iii][index]=0. ;
    1002             :     
    1003          10 :     stof[AliPID::kPhoton][index]   = 1.; 
    1004          10 :     stof[AliPID::kElectron][index] = 1.;
    1005          10 :     stof[AliPID::kEleCon][index]   = 1.;
    1006             :     //We assing the same prob to charged hadrons, sum is 1
    1007          10 :     stof[AliPID::kPion][index]     = 1./3.; 
    1008          10 :     stof[AliPID::kKaon][index]     = 1./3.; 
    1009          10 :     stof[AliPID::kProton][index]   = 1./3.;
    1010             :     //We assing the same prob to neutral hadrons, sum is 1
    1011          10 :     stof[AliPID::kNeutron][index]  = 1./2.;
    1012          10 :     stof[AliPID::kKaon0][index]    = 1./2.;
    1013          10 :     stof[AliPID::kMuon][index]     = 1.; 
    1014             :  
    1015          10 :     if(en <  fTOFEnThreshold) {
    1016             : 
    1017           0 :       Double_t pTofPion = fTFpiong ->Eval(time) ; //gaus distribution
    1018             :       Double_t pTofKaon = 0;
    1019             : 
    1020           0 :       if(time < fTkaonl[1])
    1021           0 :         pTofKaon = fTFkaong  ->Eval(time) ; //gaus distribution
    1022             :       else 
    1023           0 :         pTofKaon = fTFkaonl  ->Eval(time) ; //landau distribution
    1024             : 
    1025             :       Double_t pTofNucleon = 0;
    1026             : 
    1027           0 :       if(time < fThhadronl[1])
    1028           0 :         pTofNucleon = fTFhhadrong   ->Eval(time) ; //gaus distribution
    1029             :       else
    1030           0 :         pTofNucleon = fTFhhadronl   ->Eval(time) ; //landau distribution
    1031             :       //We assing the same prob to neutral hadrons, sum is the average prob
    1032           0 :       Double_t pTofNeHadron =  (pTofKaon + pTofNucleon)/2. ;
    1033             :       //We assing the same prob to charged hadrons, sum is the average prob
    1034           0 :       Double_t pTofChHadron =  (pTofPion + pTofKaon + pTofNucleon)/3. ;
    1035             : 
    1036           0 :       stof[AliPID::kPhoton][index]   = fTFphoton     ->Eval(time) ; 
    1037             :       //gaus distribution
    1038           0 :       stof[AliPID::kEleCon][index]   = stof[AliPID::kPhoton][index] ; 
    1039             :       //a conversion electron has the photon ToF
    1040           0 :       stof[AliPID::kMuon][index]     = stof[AliPID::kPhoton][index] ;
    1041             :  
    1042           0 :       stof[AliPID::kElectron][index] = pTofPion  ;                             
    1043             : 
    1044           0 :       stof[AliPID::kPion][index]     =  pTofChHadron ; 
    1045           0 :       stof[AliPID::kKaon][index]     =  pTofChHadron ;
    1046           0 :       stof[AliPID::kProton][index]   =  pTofChHadron ;
    1047             : 
    1048           0 :       stof[AliPID::kKaon0][index]    =  pTofNeHadron ;     
    1049           0 :       stof[AliPID::kNeutron][index]  =  pTofNeHadron ;            
    1050           0 :     } 
    1051             :     
    1052             :     //    Info("MakePID", "Dispersion");
    1053             :     
    1054             :     // ###########Shower shape: Dispersion####################
    1055          10 :     Float_t dispersion = emc->GetDispersion();
    1056             :     //DP: Correct for non-perpendicular incidence
    1057             :     //DP: still to be done 
    1058             : 
    1059             :     //dispersion is not well defined if the cluster is only in few crystals
    1060             :     //Initialize anused species
    1061         300 :     for(Int_t iii=0; iii<kSPECIES; iii++)sdp[iii][index]=0. ;
    1062             :     
    1063          10 :     sdp[AliPID::kPhoton][index]   = 1. ;
    1064          10 :     sdp[AliPID::kElectron][index] = 1. ;
    1065          10 :     sdp[AliPID::kPion][index]     = 1. ; 
    1066          10 :     sdp[AliPID::kKaon][index]     = 1. ; 
    1067          10 :     sdp[AliPID::kProton][index]   = 1. ;
    1068          10 :     sdp[AliPID::kNeutron][index]  = 1. ;
    1069          10 :     sdp[AliPID::kEleCon][index]   = 1. ; 
    1070          10 :     sdp[AliPID::kKaon0][index]    = 1. ; 
    1071          10 :     sdp[AliPID::kMuon][index]     = 1. ; 
    1072             :     
    1073          20 :     if(en > fDispEnThreshold && emc->GetMultiplicity() >  fDispMultThreshold){
    1074          10 :       sdp[AliPID::kPhoton][index]   = GausF(en , dispersion, fDphoton) ;
    1075          10 :       sdp[AliPID::kElectron][index] = sdp[AliPID::kPhoton][index] ;
    1076          10 :       sdp[AliPID::kPion][index]     = LandauF(en , dispersion, fDhadron ) ; 
    1077          10 :       sdp[AliPID::kKaon][index]     = sdp[AliPID::kPion][index]  ; 
    1078          10 :       sdp[AliPID::kProton][index]   = sdp[AliPID::kPion][index]  ;
    1079          10 :       sdp[AliPID::kNeutron][index]  = sdp[AliPID::kPion][index]  ;
    1080          10 :       sdp[AliPID::kEleCon][index]   = sdp[AliPID::kPhoton][index]; 
    1081          10 :       sdp[AliPID::kKaon0][index]    = sdp[AliPID::kPion][index]  ; 
    1082          10 :       sdp[AliPID::kMuon][index]     = fDFmuon ->Eval(dispersion) ; 
    1083             :       //landau distribution
    1084          10 :     }
    1085             :     
    1086             : //      Info("MakePID","multiplicity %d, dispersion %f", emc->GetMultiplicity(), dispersion);
    1087             : //      Info("MakePID","ss: photon %f, hadron %f ",  sdp[AliPID::kPhoton][index],  sdp[AliPID::kPion][index]);
    1088             : //       cout<<">>>>>multiplicity "<<emc->GetMultiplicity()<<", dispersion "<< dispersion<<endl ;
    1089             : //       cout<<"<<<<<ss: photon   "<<sdp[AliPID::kPhoton][index]<<", hadron    "<<sdp[AliPID::kPion][index]<<endl;
    1090             : 
    1091             :     //########## CPV-EMC  Distance#######################
    1092             :     //     Info("MakePID", "Distance");
    1093             : 
    1094          10 :     Float_t x             = TMath::Abs(ts->GetCpvDistance("X")) ;
    1095          10 :     Float_t z             = ts->GetCpvDistance("Z") ;
    1096             :    
    1097             :     Double_t pcpv         = 0 ;
    1098             :     Double_t pcpvneutral  = 0. ;
    1099             :    
    1100          10 :     Double_t elprobx      = GausF(en , x, fXelectron) ;
    1101          10 :     Double_t elprobz      = GausF(en , z, fZelectron) ;
    1102          10 :     Double_t chprobx      = GausF(en , x, fXcharged)  ;
    1103          10 :     Double_t chprobz      = GausF(en , z, fZcharged)  ;
    1104          10 :     Double_t pcpvelectron = elprobx * elprobz;
    1105          10 :     Double_t pcpvcharged  = chprobx * chprobz;
    1106             :   
    1107             : //     cout<<">>>>energy "<<en<<endl;
    1108             : //     cout<<">>>>electron : x "<<x<<" xprob "<<elprobx<<" z "<<z<<" zprob "<<elprobz<<endl;
    1109             : //     cout<<">>>>hadron   : x "<<x<<" xprob "<<chprobx<<" z "<<z<<" zprob "<<chprobz<<endl;
    1110             : //     cout<<">>>>electron : px*pz "<<pcpvelectron <<" hadron: px*pz "<<pcpvcharged<<endl;  
    1111             : 
    1112             :     // Is neutral or charged?
    1113          10 :     if(pcpvelectron >= pcpvcharged)  
    1114           8 :       pcpv = pcpvelectron ;
    1115             :     else
    1116             :       pcpv = pcpvcharged ;
    1117             :     
    1118          10 :     if(pcpv < fChargedNeutralThreshold)
    1119             :       {
    1120             :         pcpvneutral  = 1. ;
    1121             :         pcpvcharged  = 0. ;
    1122             :         pcpvelectron = 0. ;
    1123           6 :       }
    1124             :     //    else
    1125             :     //      cout<<">>>>>>>>>>>CHARGED>>>>>>>>>>>"<<endl;
    1126             :     //Initialize anused species
    1127         300 :     for(Int_t iii=0; iii<kSPECIES; iii++)scpv[iii][index]=0. ;
    1128             :     
    1129          10 :     scpv[AliPID::kPion][index]     =  pcpvcharged  ; 
    1130          10 :     scpv[AliPID::kKaon][index]     =  pcpvcharged  ; 
    1131          10 :     scpv[AliPID::kProton][index]   =  pcpvcharged  ;
    1132             : 
    1133          10 :     scpv[AliPID::kMuon][index]     =  pcpvelectron ; 
    1134          10 :     scpv[AliPID::kElectron][index] =  pcpvelectron ;
    1135          10 :     scpv[AliPID::kEleCon][index]   =  pcpvelectron ; 
    1136             : 
    1137          10 :     scpv[AliPID::kPhoton][index]   =  pcpvneutral  ;
    1138          10 :     scpv[AliPID::kNeutron][index]  =  pcpvneutral  ; 
    1139          10 :     scpv[AliPID::kKaon0][index]    =  pcpvneutral  ; 
    1140             : 
    1141             :     
    1142             :     //   Info("MakePID", "CPV passed");
    1143             : 
    1144             :     //############## Pi0 #############################
    1145          10 :     stof[AliPID::kPi0][index]      = 0. ;  
    1146          10 :     scpv[AliPID::kPi0][index]      = 0. ;
    1147          10 :     sdp [AliPID::kPi0][index]      = 0. ;
    1148             : 
    1149          10 :     if(en > 30.){
    1150             :       // pi0 are detected via decay photon
    1151           0 :       stof[AliPID::kPi0][index]  =   stof[AliPID::kPhoton][index];
    1152           0 :       scpv[AliPID::kPi0][index]  = pcpvneutral  ;
    1153           0 :       if(emc->GetMultiplicity() >  fDispMultThreshold)
    1154           0 :         sdp [AliPID::kPi0][index]  = GausF(en , dispersion, fDpi0) ;
    1155             :         //sdp [AliPID::kPi0][index]  = GausPol2(en , dispersion, fDpi0) ;
    1156             : //       cout<<"E = "<<en<<" GeV; disp = "<<dispersion<<"; mult = "
    1157             : //        <<emc->GetMultiplicity()<<endl;
    1158             : //       cout<<"PDF: photon = "<<sdp [AliPID::kPhoton][index]<<"; pi0 = "
    1159             : //        <<sdp [AliPID::kPi0][index]<<endl;
    1160             :     }
    1161             :     
    1162             :   
    1163             : 
    1164             :     
    1165             :     //############## muon #############################
    1166             : 
    1167          10 :     if(en > 0.5){
    1168             :       //Muons deposit few energy
    1169          10 :       scpv[AliPID::kMuon][index]     =  0 ;
    1170          10 :       stof[AliPID::kMuon][index]     =  0 ;
    1171          10 :       sdp [AliPID::kMuon][index]     =  0 ;
    1172          10 :     }
    1173             : 
    1174             :     //Weight to apply to hadrons due to energy reconstruction
    1175             :     //Initialize anused species
    1176         300 :     for(Int_t iii=0; iii<kSPECIES; iii++)sw[iii][index]=1. ;
    1177             : 
    1178          10 :     Float_t weight = fERecWeight ->Eval(en) ;
    1179             :  
    1180          10 :     sw[AliPID::kPhoton][index]   = 1. ;
    1181          10 :     sw[AliPID::kElectron][index] = 1. ;
    1182          10 :     sw[AliPID::kPion][index]     = weight ; 
    1183          10 :     sw[AliPID::kKaon][index]     = weight ; 
    1184          10 :     sw[AliPID::kProton][index]   = weight ;
    1185          10 :     sw[AliPID::kNeutron][index]  = weight ;
    1186          10 :     sw[AliPID::kEleCon][index]   = 1. ; 
    1187          10 :     sw[AliPID::kKaon0][index]    = weight ; 
    1188          10 :     sw[AliPID::kMuon][index]     = weight ; 
    1189          10 :     sw[AliPID::kPi0][index]      = 1. ;
    1190             : 
    1191             : //     if(en > 0.5){
    1192             : //       cout<<"######################################################"<<endl;
    1193             : //       //cout<<"MakePID: energy "<<en<<", tof "<<time<<", distance "<<distance<<", dispersion "<<dispersion<<endl ;
    1194             : //       cout<<"MakePID: energy "<<en<<", tof "<<time<<", dispersion "<<dispersion<<", x "<<x<<", z "<<z<<endl ;
    1195             : //       cout<<">>>>>multiplicity "<<emc->GetMultiplicity()<<endl;
    1196             : //       cout<<">>>>electron : xprob "<<elprobx<<" zprob "<<elprobz<<endl;
    1197             : //       cout<<">>>>hadron   : xprob "<<chprobx<<" zprob "<<chprobz<<endl;
    1198             : //       cout<<">>>>electron : px*pz "<<pcpvelectron <<" hadron: px*pz "<<pcpvcharged<<endl;  
    1199             :       
    1200             : //        cout<<"Photon   , pid "<< fInitPID[AliPID::kPhoton]<<" tof "<<stof[AliPID::kPhoton][index]
    1201             : //        <<", cpv "<<scpv[AliPID::kPhoton][index]<<", ss "<<sdp[AliPID::kPhoton][index]<<endl;
    1202             : //       cout<<"EleCon   , pid "<< fInitPID[AliPID::kEleCon]<<", tof "<<stof[AliPID::kEleCon][index]
    1203             : //        <<", cpv "<<scpv[AliPID::kEleCon][index]<<" ss "<<sdp[AliPID::kEleCon][index]<<endl;
    1204             : //       cout<<"Electron , pid "<< fInitPID[AliPID::kElectron]<<", tof "<<stof[AliPID::kElectron][index]
    1205             : //        <<", cpv "<<scpv[AliPID::kElectron][index]<<" ss "<<sdp[AliPID::kElectron][index]<<endl;
    1206             : //       cout<<"Muon     , pid "<< fInitPID[AliPID::kMuon]<<", tof "<<stof[AliPID::kMuon][index]
    1207             : //        <<", cpv "<<scpv[AliPID::kMuon][index]<<" ss "<<sdp[AliPID::kMuon][index]<<endl;
    1208             : //        cout<<"Pi0      , pid "<< fInitPID[AliPID::kPi0]<<", tof "<<stof[AliPID::kPi0][index]
    1209             : //        <<", cpv "<<scpv[AliPID::kPi0][index]<<" ss "<<sdp[AliPID::kPi0][index]<<endl;
    1210             : //       cout<<"Pion     , pid "<< fInitPID[AliPID::kPion]<<", tof "<<stof[AliPID::kPion][index]
    1211             : //        <<", cpv "<<scpv[AliPID::kPion][index]<<" ss "<<sdp[AliPID::kPion][index]<<endl;
    1212             : //       cout<<"Kaon0    , pid "<< fInitPID[AliPID::kKaon0]<<", tof "<<stof[AliPID::kKaon0][index]
    1213             : //        <<", cpv "<<scpv[AliPID::kKaon0][index]<<" ss "<<sdp[AliPID::kKaon0][index]<<endl;
    1214             : //       cout<<"Kaon     , pid "<< fInitPID[AliPID::kKaon]<<", tof "<<stof[AliPID::kKaon][index]
    1215             : //        <<", cpv "<<scpv[AliPID::kKaon][index]<<" ss "<<sdp[AliPID::kKaon][index]<<endl;
    1216             : //       cout<<"Neutron  , pid "<< fInitPID[AliPID::kNeutron]<<", tof "<<stof[AliPID::kNeutron][index]
    1217             : //        <<", cpv "<<scpv[AliPID::kNeutron][index]<<" ss "<<sdp[AliPID::kNeutron][index]<<endl;
    1218             : //       cout<<"Proton   , pid "<< fInitPID[AliPID::kProton]<<", tof "<<stof[AliPID::kProton][index]
    1219             : //        <<", cpv "<<scpv[AliPID::kProton][index]<<" ss "<<sdp[AliPID::kProton][index]<<endl;
    1220             : //       cout<<"######################################################"<<endl;
    1221             : //     }
    1222          10 :   }
    1223             :   
    1224             :   
    1225          36 :   for(Int_t index = 0 ; index < nparticles ; index ++) {
    1226             :     
    1227          10 :     AliPHOSRecParticle * recpar = static_cast<AliPHOSRecParticle *>(fRecParticles->At(index));
    1228             :     
    1229             :     //Conversion electron?
    1230             :     
    1231          30 :     if(recpar->IsEleCon()){
    1232          10 :       fInitPID[AliPID::kEleCon]   = 1. ;
    1233           0 :       fInitPID[AliPID::kPhoton]   = 0. ;
    1234           0 :       fInitPID[AliPID::kElectron] = 0. ;
    1235           0 :     }
    1236             :     else{
    1237          10 :       fInitPID[AliPID::kEleCon]   = 0. ;
    1238          10 :       fInitPID[AliPID::kPhoton]   = 1. ;
    1239          10 :       fInitPID[AliPID::kElectron] = 1. ;
    1240             :     }
    1241             :     //  fInitPID[AliPID::kEleCon]   = 0. ;
    1242             :     
    1243             :     
    1244             :     // calculates the Bayesian weight
    1245             :     
    1246             :     Int_t jndex ;
    1247             :     Double_t wn = 0.0 ; 
    1248         300 :     for (jndex = 0 ; jndex < kSPECIES ; jndex++) 
    1249         420 :       wn += stof[jndex][index] * sdp[jndex][index]  * scpv[jndex][index] * 
    1250         280 :         sw[jndex][index] * fInitPID[jndex] ;
    1251             :     
    1252             :     //    cout<<"*************wn "<<wn<<endl;
    1253          10 :     if (TMath::Abs(wn)>0)
    1254         300 :       for (jndex = 0 ; jndex < kSPECIES ; jndex++) {
    1255             :         //cout<<"jndex "<<jndex<<" wn "<<wn<<" SetPID * wn"
    1256             :         //<<stof[jndex][index] * sdp[jndex][index] * pid[jndex]  << endl;
    1257             :         //cout<<" tof "<<stof[jndex][index] << " disp " <<sdp[jndex][index] << " pid "<< fInitPID[jndex] << endl;
    1258             :         //      if(jndex ==  AliPID::kPi0 || jndex ==  AliPID::kPhoton){
    1259             :         //        cout<<"Particle "<<jndex<<"  final prob * wn   "
    1260             :         //            <<stof[jndex][index] * sdp[jndex][index] * scpv[jndex][index] * 
    1261             :         //          fInitPID[jndex] <<"  wn  "<< wn<<endl;
    1262             :         //        cout<<"pid "<< fInitPID[jndex]<<", tof "<<stof[jndex][index]
    1263             :         //            <<", cpv "<<scpv[jndex][index]<<" ss "<<sdp[jndex][index]<<endl;
    1264             :         //      }
    1265         420 :         recpar->SetPID(jndex, stof[jndex][index] * sdp[jndex][index] * 
    1266         420 :                        sw[jndex][index] * scpv[jndex][index] * 
    1267         280 :                        fInitPID[jndex] / wn) ; 
    1268             :       }
    1269             :   }
    1270             :   //  Info("MakePID", "Delete");
    1271             :   
    1272         240 :   for (Int_t i =0; i< kSPECIES; i++){
    1273         224 :     delete [] stof[i];
    1274         224 :     delete [] sdp [i];
    1275         224 :     delete [] scpv[i];
    1276         224 :     delete [] sw  [i];
    1277             :   }
    1278             :   //  Info("MakePID","End MakePID"); 
    1279           8 : }
    1280             : 
    1281             : //____________________________________________________________________________
    1282             : void  AliPHOSPIDv1::MakeRecParticles()
    1283             : {
    1284             :   // Makes a RecParticle out of a TrackSegment
    1285             :   
    1286          32 :   if ( !fEMCRecPoints || !fCPVRecPoints || !fTrackSegments ) {
    1287           0 :     AliFatal("RecPoints or TrackSegments not found !") ;  
    1288           0 :   }
    1289           8 :   fRecParticles->Clear();
    1290             : 
    1291           8 :   Int_t nEmcRP=fEMCRecPoints->GetEntriesFast() ;
    1292          36 :   for(Int_t index=0; index<nEmcRP; index++){
    1293          10 :     AliPHOSRecParticle * rp = new( (*fRecParticles)[index] ) AliPHOSRecParticle() ;
    1294          10 :     rp->SetTrackSegment(index) ;
    1295          10 :     rp->SetIndexInList(index) ;
    1296             :         
    1297          10 :     AliPHOSEmcRecPoint * emc = static_cast<AliPHOSEmcRecPoint *>(fEMCRecPoints->At(index)) ;
    1298          10 :     AliPHOSTrackSegment * ts = static_cast<AliPHOSTrackSegment*>(fTrackSegments->At(index)) ;
    1299             :     AliPHOSCpvRecPoint * cpv = 0 ;
    1300          10 :     if(ts->GetCpvIndex()>=0)
    1301           0 :       cpv = (AliPHOSCpvRecPoint*) fCPVRecPoints->At(ts->GetCpvIndex()) ;
    1302             :     
    1303          10 :     Int_t track = ts->GetTrackIndex() ; 
    1304             :           
    1305          10 :     if (!emc) {
    1306           0 :       AliFatal(Form("-> emc(%d)", ts->GetEmcIndex())) ;
    1307           0 :     }
    1308             : 
    1309          10 :     Float_t e = emc->GetEnergy() ;   
    1310             :     
    1311          10 :     Float_t  lambda[2]={0.,0.} ;
    1312          10 :     emc->GetElipsAxis(lambda) ;
    1313             :  
    1314          20 :     if((lambda[0]>0.01) && (lambda[1]>0.01)){
    1315             :       // Looking PCA. Define and calculate the data (X),
    1316             :       // introduce in the function X2P that gives the components (P).  
    1317             : 
    1318             :       Float_t  spher = 0. ;
    1319             :       Float_t  emaxdtotal = 0. ; 
    1320             :       
    1321          10 :       if((lambda[0]+lambda[1])!=0) 
    1322          10 :         spher=TMath::Abs(lambda[0]-lambda[1])/(lambda[0]+lambda[1]); 
    1323             :       
    1324          10 :       emaxdtotal=emc->GetMaximalEnergy()/emc->GetEnergy(); 
    1325             :       
    1326          10 :       fX[0] = lambda[0] ;  
    1327          10 :       fX[1] = lambda[1] ; 
    1328          10 :       fX[2] = emc->GetDispersion() ; 
    1329          10 :       fX[3] = spher ; 
    1330          10 :       fX[4] = emc->GetMultiplicity() ;  
    1331          10 :       fX[5] = emaxdtotal ;  
    1332          10 :       fX[6] = emc->GetCoreEnergy() ;  
    1333             :       
    1334          10 :       fPrincipalPhoton->X2P(fX,fPPhoton);
    1335          10 :       fPrincipalPi0   ->X2P(fX,fPPi0);
    1336             : 
    1337          10 :     }
    1338             :     else{
    1339           0 :       fPPhoton[0]=-100.0;  //We do not accept clusters with 
    1340           0 :       fPPhoton[1]=-100.0;  //one cell as a photon-like
    1341           0 :       fPPi0[0]   =-100.0;
    1342           0 :       fPPi0[1]   =-100.0;
    1343             :     }
    1344             :     
    1345          10 :     Float_t time = emc->GetTime() ;
    1346          10 :     rp->SetTof(time) ; 
    1347             :     
    1348             :     // Loop of Efficiency-Purity (the 3 points of purity or efficiency 
    1349             :     // are taken into account to set the particle identification)
    1350          80 :     for(Int_t effPur = 0; effPur < 3 ; effPur++){
    1351             :       
    1352             :       // Looking at the CPV detector. If RCPV greater than CpvEmcDistance, 
    1353             :       // 1st,2nd or 3rd bit (depending on the efficiency-purity point )
    1354             :       // is set to 1
    1355          30 :       if(GetCPVBit(ts, effPur,e) == 1 ){  
    1356          18 :         rp->SetPIDBit(effPur) ;
    1357             :         //cout<<"CPV bit "<<effPur<<endl;
    1358          18 :       }
    1359             :       // Looking the TOF. If TOF smaller than gate,  4th, 5th or 6th 
    1360             :       // bit (depending on the efficiency-purity point )is set to 1             
    1361          30 :       if(time< (*fParameters)(3,effPur)) 
    1362          30 :         rp->SetPIDBit(effPur+3) ;                
    1363             :   
    1364             :       //Photon PCA
    1365             :       //If we are inside the ellipse, 7th, 8th or 9th 
    1366             :       // bit (depending on the efficiency-purity point )is set to 1 
    1367          60 :       if(GetPrincipalBit("photon",fPPhoton,effPur,e) == 1) 
    1368          28 :         rp->SetPIDBit(effPur+6) ;
    1369             : 
    1370             :       //Pi0 PCA
    1371             :       //If we are inside the ellipse, 10th, 11th or 12th 
    1372             :       // bit (depending on the efficiency-purity point )is set to 1 
    1373          60 :       if(GetPrincipalBit("pi0"   ,fPPi0   ,effPur,e) == 1) 
    1374           0 :         rp->SetPIDBit(effPur+9) ;
    1375             :     }
    1376          10 :     if(GetHardPhotonBit(emc))
    1377           0 :       rp->SetPIDBit(12) ;
    1378          10 :     if(GetHardPi0Bit   (emc))
    1379           0 :       rp->SetPIDBit(13) ;
    1380             :     
    1381          10 :     if(track >= 0) 
    1382           4 :       rp->SetPIDBit(14) ; 
    1383             : 
    1384             :     //Set momentum, energy and other parameters 
    1385          10 :     TVector3 dir   = GetMomentumDirection(emc,cpv) ; 
    1386          10 :     dir.SetMag(e) ;
    1387          10 :     rp->SetMomentum(dir.X(),dir.Y(),dir.Z(),e) ;
    1388          10 :     rp->SetCalcMass(0);
    1389          20 :     rp->Name(); //If photon sets the particle pdg name to gamma
    1390          10 :     rp->SetProductionVertex(fVtx.X(),fVtx.Y(),fVtx.Z(),0);
    1391          10 :     rp->SetFirstMother(-1);
    1392          10 :     rp->SetLastMother(-1);
    1393          10 :     rp->SetFirstDaughter(-1);
    1394          10 :     rp->SetLastDaughter(-1);
    1395          10 :     rp->SetPolarisation(0,0,0);
    1396             :     //Set the position in global coordinate system from the RecPoint
    1397          10 :     TVector3 pos ; 
    1398          10 :     fGeom->GetGlobalPHOS(emc, pos) ; 
    1399          30 :     rp->SetPos(pos);
    1400          10 :   }
    1401           8 : }
    1402             :   
    1403             : //____________________________________________________________________________
    1404             : void  AliPHOSPIDv1::Print(const Option_t *) const
    1405             : {
    1406             :   // Print the parameters used for the particle type identification
    1407             : 
    1408           0 :     AliInfo("=============== AliPHOSPIDv1 ================") ;
    1409           0 :     printf("Making PID\n") ;
    1410           0 :     printf("    Pricipal analysis file from 0.5 to 100 %s\n", fFileNamePrincipalPhoton.Data() )   ; 
    1411           0 :     printf("    Name of parameters file     %s\n", fFileNameParameters.Data() )  ;
    1412           0 :     printf("    Matrix of Parameters: 14x4\n") ;
    1413           0 :     printf("        Energy Calibration  1x3 [3 parametres to calibrate energy: A + B* E + C * E^2]\n") ;
    1414           0 :     printf("        RCPV 2x3 rows x and z, columns function cut parameters\n") ;
    1415           0 :     printf("        TOF  1x3 [High Eff-Low Pur,Medium Eff-Pur, Low Eff-High Pur]\n") ;
    1416           0 :     printf("        PCA  5x4 [5 ellipse parametres and 4 parametres to calculate them: A/Sqrt(E) + B* E + C * E^2 + D]\n") ;
    1417           0 :     printf("    Pi0 PCA  5x3 [5 ellipse parametres and 3 parametres to calculate them: A + B* E + C * E^2]\n") ;
    1418           0 :     fParameters->Print() ;
    1419           0 : }
    1420             : 
    1421             : 
    1422             : 
    1423             : //____________________________________________________________________________
    1424             : void AliPHOSPIDv1::PrintRecParticles(Option_t * option)
    1425             : {
    1426             :   // Print table of reconstructed particles
    1427             : 
    1428           0 :   TString message ; 
    1429           0 :   message  = "       found " ; 
    1430           0 :   message += fRecParticles->GetEntriesFast(); 
    1431           0 :   message += " RecParticles\n" ; 
    1432             : 
    1433           0 :   if(strstr(option,"all")) {  // printing found TS
    1434           0 :     message += "\n  PARTICLE         Index    \n" ; 
    1435             :     
    1436             :     Int_t index ;
    1437           0 :     for (index = 0 ; index < fRecParticles->GetEntries() ; index++) {
    1438           0 :       AliPHOSRecParticle * rp = (AliPHOSRecParticle * ) fRecParticles->At(index) ;       
    1439           0 :       message += "\n" ;
    1440           0 :       message += rp->Name().Data() ;  
    1441           0 :       message += " " ;
    1442           0 :       message += rp->GetIndexInList() ;  
    1443           0 :       message += " " ;
    1444           0 :       message += rp->GetType()  ;
    1445             :     }
    1446           0 :   }
    1447           0 :   AliInfo(message.Data() ) ; 
    1448           0 : }
    1449             : 
    1450             : //____________________________________________________________________________
    1451             : void  AliPHOSPIDv1::SetParameters() 
    1452             : {
    1453             :   // PCA : To do the Principal Components Analysis it is necessary 
    1454             :   // the Principal file, which is opened here
    1455           4 :   fX       = new double[7]; // Data for the PCA 
    1456           2 :   fPPhoton = new double[7]; // Eigenvalues of the PCA
    1457           2 :   fPPi0    = new double[7]; // Eigenvalues of the Pi0 PCA
    1458             : 
    1459             :   // Read photon principals from the photon file
    1460             :   
    1461           2 :   fFileNamePrincipalPhoton = "$ALICE_ROOT/PHOS/PCA8pa15_0.5-100.root" ; 
    1462           2 :   TFile f( fFileNamePrincipalPhoton.Data(), "read" ) ;
    1463           8 :   fPrincipalPhoton = dynamic_cast<TPrincipal*> (f.Get("principal")) ; 
    1464           2 :   f.Close() ; 
    1465             : 
    1466             :   // Read pi0 principals from the pi0 file
    1467             : 
    1468           2 :   fFileNamePrincipalPi0    = "$ALICE_ROOT/PHOS/PCA_pi0_40-120.root" ;
    1469           4 :   TFile fPi0( fFileNamePrincipalPi0.Data(), "read" ) ;
    1470           8 :   fPrincipalPi0    = dynamic_cast<TPrincipal*> (fPi0.Get("principal")) ; 
    1471           2 :   fPi0.Close() ;
    1472             : 
    1473             :   // Open parameters file and initialization of the Parameters matrix. 
    1474             :   // In the File Parameters.dat are all the parameters. These are introduced 
    1475             :   // in a matrix of 16x4  
    1476             :   // 
    1477             :   // All the parameters defined in this file are, in order of row: 
    1478             :   // line   0   : calibration 
    1479             :   // lines  1,2 : CPV rectangular cat for X and Z
    1480             :   // line   3   : TOF cut
    1481             :   // lines  4-8 : parameters to calculate photon PCA ellipse
    1482             :   // lines  9-13: parameters to calculate pi0 PCA ellipse
    1483             :   // lines 14-15: parameters to calculate border for high-pt photons and pi0
    1484             : 
    1485           4 :   fFileNameParameters = gSystem->ExpandPathName("$ALICE_ROOT/PHOS/Parameters.dat");
    1486           6 :   fParameters = new TMatrixF(16,4) ;
    1487             :   const Int_t kMaxLeng=255;
    1488           2 :   char string[kMaxLeng];
    1489             : 
    1490             :   // Open a text file with PID parameters
    1491           4 :   FILE *fd = fopen(fFileNameParameters.Data(),"r");
    1492           2 :   if (!fd)
    1493           0 :     AliFatal(Form("File %s with a PID parameters cannot be opened\n",
    1494             :           fFileNameParameters.Data()));
    1495             : 
    1496             :   Int_t i=0;
    1497             :   // Read parameter file line-by-line and skip empty line and comments
    1498         158 :   while (fgets(string,kMaxLeng,fd) != NULL) {
    1499          76 :     if (string[0] == '\n' ) continue;
    1500          64 :     if (string[0] == '!'  ) continue;
    1501          32 :     sscanf(string, "%f %f %f %f",
    1502          64 :            &(*fParameters)(i,0), &(*fParameters)(i,1), 
    1503          64 :            &(*fParameters)(i,2), &(*fParameters)(i,3));
    1504          32 :     i++;
    1505         160 :     AliDebug(1, Form("Line %d: %s",i,string));
    1506             :   }
    1507           2 :   fclose(fd);
    1508           2 : }
    1509             : 
    1510             : //____________________________________________________________________________
    1511             : void  AliPHOSPIDv1::SetParameterCalibration(Int_t i,Float_t param) 
    1512             : {
    1513             :   // Set parameter "Calibration" i to a value param
    1514           0 :   if(i>2 || i<0) {
    1515           0 :     AliError(Form("Invalid parameter number: %d",i));
    1516           0 :   } else
    1517           0 :     (*fParameters)(0,i) = param ;
    1518           0 : }
    1519             : 
    1520             : //____________________________________________________________________________
    1521             : void  AliPHOSPIDv1::SetParameterCpv2Emc(Int_t i, TString axis, Float_t cut) 
    1522             : {
    1523             :   // Set the parameters to calculate Cpv-to-Emc Distance Cut depending on 
    1524             :   // Purity-Efficiency point i
    1525             : 
    1526           0 :   if(i>2 || i<0) {
    1527           0 :     AliError(Form("Invalid parameter number: %d",i));
    1528           0 :   } else {
    1529           0 :     axis.ToLower();
    1530           0 :     if      (axis == "x") (*fParameters)(1,i) = cut;
    1531           0 :     else if (axis == "z") (*fParameters)(2,i) = cut;
    1532             :     else { 
    1533           0 :       AliError(Form("Invalid axis name: %s",axis.Data()));
    1534             :     }
    1535             :   }
    1536           0 : }
    1537             : 
    1538             : //____________________________________________________________________________
    1539             : void  AliPHOSPIDv1::SetParameterPhotonBoundary(Int_t i,Float_t param) 
    1540             : {
    1541             :   // Set parameter "Hard photon boundary" i to a value param
    1542           0 :   if(i>4 || i<0) {
    1543           0 :     AliError(Form("Invalid parameter number: %d",i));
    1544           0 :   } else
    1545           0 :     (*fParameters)(14,i) = param ;
    1546           0 : }
    1547             : 
    1548             : //____________________________________________________________________________
    1549             : void  AliPHOSPIDv1::SetParameterPi0Boundary(Int_t i,Float_t param) 
    1550             : {
    1551             :   // Set parameter "Hard pi0 boundary" i to a value param
    1552           0 :   if(i>1 || i<0) {
    1553           0 :     AliError(Form("Invalid parameter number: %d",i));
    1554           0 :   } else
    1555           0 :     (*fParameters)(15,i) = param ;
    1556           0 : }
    1557             : 
    1558             : //_____________________________________________________________________________
    1559             : void  AliPHOSPIDv1::SetParameterTimeGate(Int_t i, Float_t gate) 
    1560             : {
    1561             :   // Set the parameter TimeGate depending on Purity-Efficiency point i 
    1562           0 :   if (i>2 || i<0) {
    1563           0 :     AliError(Form("Invalid Efficiency-Purity choice %d",i));
    1564           0 :   } else
    1565           0 :     (*fParameters)(3,i)= gate ; 
    1566           0 : } 
    1567             : 
    1568             : //_____________________________________________________________________________
    1569             : void  AliPHOSPIDv1::SetParameterToCalculateEllipse(TString particle, TString param, Int_t i, Float_t par) 
    1570             : {  
    1571             :   // Set the parameter "i" that is needed to calculate the ellipse 
    1572             :   // parameter "param" for a particle "particle"
    1573             :   
    1574           0 :   particle.ToLower();
    1575           0 :   param.   ToLower();
    1576             :   Int_t p= -1;
    1577             :   Int_t offset=0;
    1578             : 
    1579           0 :   if      (particle == "photon") offset=0;
    1580           0 :   else if (particle == "pi0")    offset=5;
    1581             :   else
    1582           0 :     AliError(Form("Wrong particle name: %s (choose from pi0/photon)\n",
    1583             :                   particle.Data()));
    1584             : 
    1585           0 :   if     (param.Contains("a")) p=4+offset; 
    1586           0 :   else if(param.Contains("b")) p=5+offset; 
    1587           0 :   else if(param.Contains("c")) p=6+offset; 
    1588           0 :   else if(param.Contains("x0"))p=7+offset; 
    1589           0 :   else if(param.Contains("y0"))p=8+offset;
    1590           0 :   if((i>4)||(i<0)) {
    1591           0 :     AliError(Form("No parameter with index %d", i)) ; 
    1592           0 :   } else if(p==-1) {
    1593           0 :     AliError(Form("No parameter with name %s", param.Data() )) ; 
    1594           0 :   } else
    1595           0 :     (*fParameters)(p,i) = par ;
    1596           0 : } 
    1597             : 
    1598             : //____________________________________________________________________________
    1599             : void AliPHOSPIDv1::GetVertex(void)
    1600             : { //extract vertex either using ESD or generator
    1601             :  
    1602             :   //Try to extract vertex from data
    1603          16 :   if(fESD){
    1604           8 :     const AliESDVertex *esdVtx = fESD->GetVertex() ;
    1605          16 :     if(esdVtx && esdVtx->GetChi2()!=0.){
    1606           8 :       fVtx.SetXYZ(esdVtx->GetX(),esdVtx->GetY(),esdVtx->GetZ()) ;
    1607           8 :       return ;
    1608             :     }
    1609           0 :   }
    1610             : 
    1611             :   // Use vertex diamond from CDB GRP folder if the one from ESD is missing
    1612             :   // PLEASE FIX IT 
    1613             : //  AliWarning("Can not read vertex from data, use fixed \n") ;
    1614           0 :   fVtx.SetXYZ(0.,0.,0.) ;
    1615             :  
    1616           8 : }
    1617             : //_______________________________________________________________________
    1618             : void AliPHOSPIDv1::SetInitPID(const Double_t *p) {
    1619             :   // Sets values for the initial population of each particle type 
    1620           0 :   for (Int_t i=0; i<AliPID::kSPECIESCN; i++) fInitPID[i] = p[i];
    1621           0 : }
    1622             : //_______________________________________________________________________
    1623             : void AliPHOSPIDv1::GetInitPID(Double_t *p) const {
    1624             :   // Gets values for the initial population of each particle type 
    1625           0 :   for (Int_t i=0; i<AliPID::kSPECIESCN; i++) p[i] = fInitPID[i];
    1626           0 : }

Generated by: LCOV version 1.11