+ Double_t * stof[kSPECIES] ;
+ Double_t * sdp [kSPECIES] ;
+ Double_t * scpv[kSPECIES] ;
+ Double_t * sw [kSPECIES] ;
+ //Info("MakePID","Begin MakePID");
+
+ for (Int_t i =0; i< kSPECIES; i++){
+ stof[i] = new Double_t[nparticles] ;
+ sdp [i] = new Double_t[nparticles] ;
+ scpv[i] = new Double_t[nparticles] ;
+ sw [i] = new Double_t[nparticles] ;
+ }
+
+
+ while ( (ts = (AliPHOSTrackSegment *)next()) ) {
+
+ //cout<<">>>>>> Bayesian Index "<<index<<endl;
+
+ AliPHOSEmcRecPoint * emc = 0 ;
+ if(ts->GetEmcIndex()>=0)
+ emc = (AliPHOSEmcRecPoint *) fEMCRecPoints->At(ts->GetEmcIndex()) ;
+
+// AliPHOSCpvRecPoint * cpv = 0 ;
+// if(ts->GetCpvIndex()>=0)
+// cpv = (AliPHOSCpvRecPoint *) cpvRecPoints->At(ts->GetCpvIndex()) ;
+//
+//// Int_t track = 0 ;
+//// track = ts->GetTrackIndex() ; //TPC tracks ?
+
+ if (!emc) {
+ AliFatal(Form("-> emc(%d) = %d", ts->GetEmcIndex(), emc )) ;
+ }
+
+
+ // ############Tof#############################
+
+ // Info("MakePID", "TOF");
+ Float_t en = emc->GetEnergy();
+ Double_t time = emc->GetTime() ;
+ // cout<<">>>>>>>Energy "<<en<<"Time "<<time<<endl;
+
+ // now get the signals probability
+ // s(pid) in the Bayesian formulation
+
+ stof[AliPID::kPhoton][index] = 1.;
+ stof[AliPID::kElectron][index] = 1.;
+ stof[AliPID::kEleCon][index] = 1.;
+ //We assing the same prob to charged hadrons, sum is 1
+ stof[AliPID::kPion][index] = 1./3.;
+ stof[AliPID::kKaon][index] = 1./3.;
+ stof[AliPID::kProton][index] = 1./3.;
+ //We assing the same prob to neutral hadrons, sum is 1
+ stof[AliPID::kNeutron][index] = 1./2.;
+ stof[AliPID::kKaon0][index] = 1./2.;
+ stof[AliPID::kMuon][index] = 1.;
+
+ if(en < fTOFEnThreshold) {
+
+ Double_t pTofPion = fTFpiong ->Eval(time) ; //gaus distribution
+ Double_t pTofKaon = 0;
+
+ if(time < fTkaonl[1])
+ pTofKaon = fTFkaong ->Eval(time) ; //gaus distribution
+ else
+ pTofKaon = fTFkaonl ->Eval(time) ; //landau distribution
+
+ Double_t pTofNucleon = 0;
+
+ if(time < fThhadronl[1])
+ pTofNucleon = fTFhhadrong ->Eval(time) ; //gaus distribution
+ else
+ pTofNucleon = fTFhhadronl ->Eval(time) ; //landau distribution
+ //We assing the same prob to neutral hadrons, sum is the average prob
+ Double_t pTofNeHadron = (pTofKaon + pTofNucleon)/2. ;
+ //We assing the same prob to charged hadrons, sum is the average prob
+ Double_t pTofChHadron = (pTofPion + pTofKaon + pTofNucleon)/3. ;
+
+ stof[AliPID::kPhoton][index] = fTFphoton ->Eval(time) ;
+ //gaus distribution
+ stof[AliPID::kEleCon][index] = stof[AliPID::kPhoton][index] ;
+ //a conversion electron has the photon ToF
+ stof[AliPID::kMuon][index] = stof[AliPID::kPhoton][index] ;
+
+ stof[AliPID::kElectron][index] = pTofPion ;
+
+ stof[AliPID::kPion][index] = pTofChHadron ;
+ stof[AliPID::kKaon][index] = pTofChHadron ;
+ stof[AliPID::kProton][index] = pTofChHadron ;
+
+ stof[AliPID::kKaon0][index] = pTofNeHadron ;
+ stof[AliPID::kNeutron][index] = pTofNeHadron ;
+ }
+
+ // Info("MakePID", "Dispersion");
+
+ // ###########Shower shape: Dispersion####################
+ Float_t dispersion = emc->GetDispersion();
+ //DP: Correct for non-perpendicular incidence
+ //DP: still to be done
+
+ //dispersion is not well defined if the cluster is only in few crystals
+
+ sdp[AliPID::kPhoton][index] = 1. ;
+ sdp[AliPID::kElectron][index] = 1. ;
+ sdp[AliPID::kPion][index] = 1. ;
+ sdp[AliPID::kKaon][index] = 1. ;
+ sdp[AliPID::kProton][index] = 1. ;
+ sdp[AliPID::kNeutron][index] = 1. ;
+ sdp[AliPID::kEleCon][index] = 1. ;
+ sdp[AliPID::kKaon0][index] = 1. ;
+ sdp[AliPID::kMuon][index] = 1. ;
+
+ if(en > fDispEnThreshold && emc->GetMultiplicity() > fDispMultThreshold){
+ sdp[AliPID::kPhoton][index] = GausF(en , dispersion, fDphoton) ;
+ sdp[AliPID::kElectron][index] = sdp[AliPID::kPhoton][index] ;
+ sdp[AliPID::kPion][index] = LandauF(en , dispersion, fDhadron ) ;
+ sdp[AliPID::kKaon][index] = sdp[AliPID::kPion][index] ;
+ sdp[AliPID::kProton][index] = sdp[AliPID::kPion][index] ;
+ sdp[AliPID::kNeutron][index] = sdp[AliPID::kPion][index] ;
+ sdp[AliPID::kEleCon][index] = sdp[AliPID::kPhoton][index];
+ sdp[AliPID::kKaon0][index] = sdp[AliPID::kPion][index] ;
+ sdp[AliPID::kMuon][index] = fDFmuon ->Eval(dispersion) ;
+ //landau distribution
+ }
+
+// Info("MakePID","multiplicity %d, dispersion %f", emc->GetMultiplicity(), dispersion);
+// Info("MakePID","ss: photon %f, hadron %f ", sdp[AliPID::kPhoton][index], sdp[AliPID::kPion][index]);
+// cout<<">>>>>multiplicity "<<emc->GetMultiplicity()<<", dispersion "<< dispersion<<endl ;
+// cout<<"<<<<<ss: photon "<<sdp[AliPID::kPhoton][index]<<", hadron "<<sdp[AliPID::kPion][index]<<endl;
+
+ //########## CPV-EMC Distance#######################
+ // Info("MakePID", "Distance");
+
+ Float_t x = TMath::Abs(ts->GetCpvDistance("X")) ;
+ Float_t z = ts->GetCpvDistance("Z") ;
+
+ Double_t pcpv = 0 ;
+ Double_t pcpvneutral = 0. ;
+
+ Double_t elprobx = GausF(en , x, fXelectron) ;
+ Double_t elprobz = GausF(en , z, fZelectron) ;
+ Double_t chprobx = GausF(en , x, fXcharged) ;
+ Double_t chprobz = GausF(en , z, fZcharged) ;
+ Double_t pcpvelectron = elprobx * elprobz;
+ Double_t pcpvcharged = chprobx * chprobz;
+
+// cout<<">>>>energy "<<en<<endl;
+// cout<<">>>>electron : x "<<x<<" xprob "<<elprobx<<" z "<<z<<" zprob "<<elprobz<<endl;
+// cout<<">>>>hadron : x "<<x<<" xprob "<<chprobx<<" z "<<z<<" zprob "<<chprobz<<endl;
+// cout<<">>>>electron : px*pz "<<pcpvelectron <<" hadron: px*pz "<<pcpvcharged<<endl;
+
+ // Is neutral or charged?
+ if(pcpvelectron >= pcpvcharged)
+ pcpv = pcpvelectron ;
+ else
+ pcpv = pcpvcharged ;
+
+ if(pcpv < fChargedNeutralThreshold)
+ {
+ pcpvneutral = 1. ;
+ pcpvcharged = 0. ;
+ pcpvelectron = 0. ;
+ }
+ // else
+ // cout<<">>>>>>>>>>>CHARGED>>>>>>>>>>>"<<endl;
+
+ scpv[AliPID::kPion][index] = pcpvcharged ;
+ scpv[AliPID::kKaon][index] = pcpvcharged ;
+ scpv[AliPID::kProton][index] = pcpvcharged ;
+
+ scpv[AliPID::kMuon][index] = pcpvelectron ;
+ scpv[AliPID::kElectron][index] = pcpvelectron ;
+ scpv[AliPID::kEleCon][index] = pcpvelectron ;
+
+ scpv[AliPID::kPhoton][index] = pcpvneutral ;
+ scpv[AliPID::kNeutron][index] = pcpvneutral ;
+ scpv[AliPID::kKaon0][index] = pcpvneutral ;
+
+
+ // Info("MakePID", "CPV passed");
+
+ //############## Pi0 #############################
+ stof[AliPID::kPi0][index] = 0. ;
+ scpv[AliPID::kPi0][index] = 0. ;
+ sdp [AliPID::kPi0][index] = 0. ;
+
+ if(en > 30.){
+ // pi0 are detected via decay photon
+ stof[AliPID::kPi0][index] = stof[AliPID::kPhoton][index];
+ scpv[AliPID::kPi0][index] = pcpvneutral ;
+ if(emc->GetMultiplicity() > fDispMultThreshold)
+ sdp [AliPID::kPi0][index] = GausF(en , dispersion, fDpi0) ;
+ //sdp [AliPID::kPi0][index] = GausPol2(en , dispersion, fDpi0) ;
+// cout<<"E = "<<en<<" GeV; disp = "<<dispersion<<"; mult = "
+// <<emc->GetMultiplicity()<<endl;
+// cout<<"PDF: photon = "<<sdp [AliPID::kPhoton][index]<<"; pi0 = "
+// <<sdp [AliPID::kPi0][index]<<endl;
+ }
+
+
+
+
+ //############## muon #############################
+
+ if(en > 0.5){
+ //Muons deposit few energy
+ scpv[AliPID::kMuon][index] = 0 ;
+ stof[AliPID::kMuon][index] = 0 ;
+ sdp [AliPID::kMuon][index] = 0 ;
+ }
+
+ //Weight to apply to hadrons due to energy reconstruction
+
+ Float_t weight = fERecWeight ->Eval(en) ;
+
+ sw[AliPID::kPhoton][index] = 1. ;
+ sw[AliPID::kElectron][index] = 1. ;
+ sw[AliPID::kPion][index] = weight ;
+ sw[AliPID::kKaon][index] = weight ;
+ sw[AliPID::kProton][index] = weight ;
+ sw[AliPID::kNeutron][index] = weight ;
+ sw[AliPID::kEleCon][index] = 1. ;
+ sw[AliPID::kKaon0][index] = weight ;
+ sw[AliPID::kMuon][index] = weight ;
+ sw[AliPID::kPi0][index] = 1. ;
+
+// if(en > 0.5){
+// cout<<"######################################################"<<endl;
+// //cout<<"MakePID: energy "<<en<<", tof "<<time<<", distance "<<distance<<", dispersion "<<dispersion<<endl ;
+// cout<<"MakePID: energy "<<en<<", tof "<<time<<", dispersion "<<dispersion<<", x "<<x<<", z "<<z<<endl ;
+// cout<<">>>>>multiplicity "<<emc->GetMultiplicity()<<endl;
+// cout<<">>>>electron : xprob "<<elprobx<<" zprob "<<elprobz<<endl;
+// cout<<">>>>hadron : xprob "<<chprobx<<" zprob "<<chprobz<<endl;
+// cout<<">>>>electron : px*pz "<<pcpvelectron <<" hadron: px*pz "<<pcpvcharged<<endl;
+
+// cout<<"Photon , pid "<< fInitPID[AliPID::kPhoton]<<" tof "<<stof[AliPID::kPhoton][index]
+// <<", cpv "<<scpv[AliPID::kPhoton][index]<<", ss "<<sdp[AliPID::kPhoton][index]<<endl;
+// cout<<"EleCon , pid "<< fInitPID[AliPID::kEleCon]<<", tof "<<stof[AliPID::kEleCon][index]
+// <<", cpv "<<scpv[AliPID::kEleCon][index]<<" ss "<<sdp[AliPID::kEleCon][index]<<endl;
+// cout<<"Electron , pid "<< fInitPID[AliPID::kElectron]<<", tof "<<stof[AliPID::kElectron][index]
+// <<", cpv "<<scpv[AliPID::kElectron][index]<<" ss "<<sdp[AliPID::kElectron][index]<<endl;
+// cout<<"Muon , pid "<< fInitPID[AliPID::kMuon]<<", tof "<<stof[AliPID::kMuon][index]
+// <<", cpv "<<scpv[AliPID::kMuon][index]<<" ss "<<sdp[AliPID::kMuon][index]<<endl;
+// cout<<"Pi0 , pid "<< fInitPID[AliPID::kPi0]<<", tof "<<stof[AliPID::kPi0][index]
+// <<", cpv "<<scpv[AliPID::kPi0][index]<<" ss "<<sdp[AliPID::kPi0][index]<<endl;
+// cout<<"Pion , pid "<< fInitPID[AliPID::kPion]<<", tof "<<stof[AliPID::kPion][index]
+// <<", cpv "<<scpv[AliPID::kPion][index]<<" ss "<<sdp[AliPID::kPion][index]<<endl;
+// cout<<"Kaon0 , pid "<< fInitPID[AliPID::kKaon0]<<", tof "<<stof[AliPID::kKaon0][index]
+// <<", cpv "<<scpv[AliPID::kKaon0][index]<<" ss "<<sdp[AliPID::kKaon0][index]<<endl;
+// cout<<"Kaon , pid "<< fInitPID[AliPID::kKaon]<<", tof "<<stof[AliPID::kKaon][index]
+// <<", cpv "<<scpv[AliPID::kKaon][index]<<" ss "<<sdp[AliPID::kKaon][index]<<endl;
+// cout<<"Neutron , pid "<< fInitPID[AliPID::kNeutron]<<", tof "<<stof[AliPID::kNeutron][index]
+// <<", cpv "<<scpv[AliPID::kNeutron][index]<<" ss "<<sdp[AliPID::kNeutron][index]<<endl;
+// cout<<"Proton , pid "<< fInitPID[AliPID::kProton]<<", tof "<<stof[AliPID::kProton][index]
+// <<", cpv "<<scpv[AliPID::kProton][index]<<" ss "<<sdp[AliPID::kProton][index]<<endl;
+// cout<<"######################################################"<<endl;
+// }
+ index++;
+ }
+
+ //for (index = 0 ; index < kSPECIES ; index++)
+ // pid[index] /= nparticles ;
+
+
+ // Info("MakePID", "Total Probability calculation");
+
+ for(index = 0 ; index < nparticles ; index ++) {
+
+ AliPHOSRecParticle * recpar = static_cast<AliPHOSRecParticle *>(fRecParticles->At(index));
+
+ //Conversion electron?
+
+ if(recpar->IsEleCon()){
+ fInitPID[AliPID::kEleCon] = 1. ;
+ fInitPID[AliPID::kPhoton] = 0. ;
+ fInitPID[AliPID::kElectron] = 0. ;
+ }
+ else{
+ fInitPID[AliPID::kEleCon] = 0. ;
+ fInitPID[AliPID::kPhoton] = 1. ;
+ fInitPID[AliPID::kElectron] = 1. ;
+ }
+ // fInitPID[AliPID::kEleCon] = 0. ;
+
+
+ // calculates the Bayesian weight
+
+ Int_t jndex ;
+ Double_t wn = 0.0 ;
+ for (jndex = 0 ; jndex < kSPECIES ; jndex++)
+ wn += stof[jndex][index] * sdp[jndex][index] * scpv[jndex][index] *
+ sw[jndex][index] * fInitPID[jndex] ;
+
+ // cout<<"*************wn "<<wn<<endl;
+ if (TMath::Abs(wn)>0)
+ for (jndex = 0 ; jndex < kSPECIES ; jndex++) {
+ //cout<<"jndex "<<jndex<<" wn "<<wn<<" SetPID * wn"
+ //<<stof[jndex][index] * sdp[jndex][index] * pid[jndex] << endl;
+ //cout<<" tof "<<stof[jndex][index] << " disp " <<sdp[jndex][index] << " pid "<< fInitPID[jndex] << endl;
+ // if(jndex == AliPID::kPi0 || jndex == AliPID::kPhoton){
+ // cout<<"Particle "<<jndex<<" final prob * wn "
+ // <<stof[jndex][index] * sdp[jndex][index] * scpv[jndex][index] *
+ // fInitPID[jndex] <<" wn "<< wn<<endl;
+ // cout<<"pid "<< fInitPID[jndex]<<", tof "<<stof[jndex][index]
+ // <<", cpv "<<scpv[jndex][index]<<" ss "<<sdp[jndex][index]<<endl;
+ // }
+ recpar->SetPID(jndex, stof[jndex][index] * sdp[jndex][index] *
+ sw[jndex][index] * scpv[jndex][index] *
+ fInitPID[jndex] / wn) ;
+ }
+ }
+ // Info("MakePID", "Delete");
+
+ for (Int_t i =0; i< kSPECIES; i++){
+ delete [] stof[i];
+ delete [] sdp [i];
+ delete [] scpv[i];
+ delete [] sw [i];
+ }
+ // Info("MakePID","End MakePID");