#include <TDatabasePDG.h>
#include <TVector3.h>
#include <TRandom.h>
#include <TRandom3.h>
#include <AliAODEvent.h>
#include <AliAODMCParticle.h>
#include "AliAODRecoDecay.h"
#include "AliAODRecoDecayHF.h"
#include "AliHFAfterBurner.h"
ClassImp(AliHFAfterBurner)
AliHFAfterBurner::AliHFAfterBurner():
fSigv2(0),
fBkgv2(0),
fUseNewton(kTRUE),
fPrecisionNewton(0),
fDecChannel(0),
fSignal(0),
fEventPlane(0.),
fMethodEP(0)
{
}
AliHFAfterBurner::AliHFAfterBurner(Int_t decChannel):
fSigv2(0.1),
fBkgv2(0.2),
fUseNewton(kTRUE),
fPrecisionNewton(0.0005),
fDecChannel(decChannel),
fSignal(0),
fEventPlane(0.),
fMethodEP(0)
{
}
AliHFAfterBurner::AliHFAfterBurner(const AliHFAfterBurner &source):
TObject(source),
fSigv2(source.fSigv2),
fBkgv2(source.fBkgv2),
fUseNewton(source.fUseNewton),
fPrecisionNewton(source.fPrecisionNewton),
fDecChannel(source.fDecChannel),
fSignal(source.fSignal),
fEventPlane(source.fEventPlane),
fMethodEP(source.fMethodEP)
{
}
AliHFAfterBurner &AliHFAfterBurner::operator=(const AliHFAfterBurner &source)
{
if(&source == this) return *this;
TObject::operator=(source);
fSigv2 = source.fSigv2;
fBkgv2=source.fBkgv2;
fUseNewton=source.fUseNewton;
fPrecisionNewton=source.fPrecisionNewton;
fDecChannel=source.fDecChannel;
fSignal=source.fSignal;
fEventPlane=source.fEventPlane;
fMethodEP=source.fMethodEP;
return *this;
}
AliHFAfterBurner::~AliHFAfterBurner(){
}
Double_t AliHFAfterBurner::GetNewAngle(AliAODRecoDecayHF *d,TClonesArray *mcArray){
Int_t lab=-1;
Int_t *pdgdaughters=0x0;
Int_t pdgmother=0;
Int_t nProngs=0;
switch(fDecChannel){
case 0:
nProngs=3;
pdgmother=411;
pdgdaughters=new Int_t[3];
pdgdaughters[0]=211;
pdgdaughters[1]=321;
pdgdaughters[2]=211;
break;
case 1:
nProngs=2;
pdgmother=421;
pdgdaughters=new Int_t[2];
pdgdaughters[0]=211;
pdgdaughters[1]=321;
break;
case 2:
nProngs=3;
pdgmother=413;
pdgdaughters=new Int_t[3];
pdgdaughters[1]=211;
pdgdaughters[0]=321;
pdgdaughters[2]=211;
break;
}
if(!pdgdaughters) return 0.;
lab = d->MatchToMC(pdgmother,mcArray,nProngs,pdgdaughters);
delete [] pdgdaughters;
Double_t phi=-999.;
if(lab>=0){
fSignal=kTRUE;
phi=GetPhi(d->Phi(),fSigv2);
}
else {
fSignal=kFALSE;
Float_t phidau[nProngs];
for(Int_t ipr=0;ipr<nProngs;ipr++){
phidau[ipr]=(Float_t)d->PhiProng(ipr);
Int_t labdau=(Int_t)d->GetProngID(ipr);
if(labdau<0)continue;
AliAODMCParticle *mcpart= (AliAODMCParticle*)mcArray->At(labdau);
if(!mcpart)continue;
Int_t laborig=TMath::Abs(CheckOrigin(mcpart,mcArray));
if(laborig>=0){
mcpart= (AliAODMCParticle*)mcArray->At(laborig);
if(mcpart)phidau[ipr]=GetPhi(mcpart->Phi(),fSigv2);
}else{
phidau[ipr]=GetPhi(phidau[ipr],fBkgv2);
}
}
Float_t py=0,px=0;
for(Int_t ipr=0;ipr<nProngs;ipr++){
py+=d->PtProng(ipr)*TMath::Sin(phidau[ipr]);
px+=d->PtProng(ipr)*TMath::Cos(phidau[ipr]);
}
phi=TMath::Pi()+TMath::ATan2(-py,-px);
}
return GetPhi02Pi(phi);
}
Double_t AliHFAfterBurner::GetPhi(Double_t phi,Float_t v2){
Double_t evplane = fEventPlane;
if(fUseNewton){
return NewtonMethodv2(phi,v2);
}else{
return phi-v2*TMath::Sin(2*(phi-evplane));
}
}
Double_t AliHFAfterBurner::NewtonMethodv2(Double_t phi,Double_t v2,Double_t phi0){
Double_t eventplane = fEventPlane;
Double_t phi1 = phi-(phi+v2*TMath::Sin(2.*(phi-eventplane))-phi0)/(1.+2.*v2*TMath::Cos(2.*(phi-eventplane)));
if(TMath::Abs(phi/phi1-1.)<fPrecisionNewton){
return phi1;
}else {
return NewtonMethodv2(phi1,v2,phi0);
}
}
void AliHFAfterBurner::SetMCv2(Float_t v2sig,Float_t v2bkg){
if(v2sig>=0)fSigv2=v2sig;
if(v2bkg>=0)fBkgv2=v2bkg;
}
Int_t AliHFAfterBurner::CheckOrigin(const AliAODMCParticle* mcPart,TClonesArray *arrayMC)const{
Float_t charmmother=kFALSE;
Int_t pdgGranma = 0;
Int_t mother = -1;
mother = mcPart->GetMother();
Int_t istep = 0;
while (mother >=0 ){
istep++;
AliAODMCParticle* mcGranma = dynamic_cast<AliAODMCParticle*>(arrayMC->At(mother));
if(!mcGranma) break;
pdgGranma = mcGranma->GetPdgCode();
Int_t abspdgGranma = TMath::Abs(pdgGranma);
if ((abspdgGranma > 400 && abspdgGranma < 500) || (abspdgGranma > 4000 && abspdgGranma < 5000)) {
charmmother=kTRUE;
}
mother = mcGranma->GetMother();
}
if(!charmmother)mother=-1;
return mother;
}
Float_t AliHFAfterBurner::GetPhi02Pi(Float_t phi){
Float_t result=phi;
while(result<0){
result=result+2.*TMath::Pi();
}
while(result>TMath::Pi()*2.){
result=result-2.*TMath::Pi();
}
return result;
}
void AliHFAfterBurner::SetDecChannel(Int_t decch){
if(decch>2){
AliWarning("Invalid decay channel");
return;
}
fDecChannel=decch;
}
void AliHFAfterBurner::SetEventPlaneMethod(Int_t method){
fMethodEP=method;
return;
}
void AliHFAfterBurner::SetEventPlane(){
TRandom3 *g = new TRandom3(0);
fEventPlane=g->Rndm()*TMath::Pi();
delete g;g=0x0;
return;
}