#include "AliOmegaDalitz.h"
#include <TMath.h>
#include <AliLog.h>
#include <TH1.h>
#include <TPDGCode.h>
#include <TRandom.h>
#include <TParticle.h>
#include <TDatabasePDG.h>
#include <TLorentzVector.h>
#include <TClonesArray.h>
ClassImp(AliOmegaDalitz)
AliOmegaDalitz::AliOmegaDalitz():
AliDecayer(),
fEPMass(0),
fMPMass(0),
fInit(0)
{
}
void AliOmegaDalitz::Init()
{
Int_t idecay, ibin, nbins = 1000;
Double_t min, max, binwidth;
Double_t pmass, lmass, omass, emass, mmass;
Double_t epsilon, delta, mLL, q, kwHelp, krollWada, formFactor, weight;
emass = (TDatabasePDG::Instance()->GetParticle(kElectron))->Mass();
mmass = (TDatabasePDG::Instance()->GetParticle(kMuonPlus))->Mass();
pmass = (TDatabasePDG::Instance()->GetParticle(223)) ->Mass();
omass = (TDatabasePDG::Instance()->GetParticle(kPi0)) ->Mass();
for ( idecay = 1; idecay<=2; idecay++ )
{
if ( idecay == 1 )
lmass = emass;
else
lmass = mmass;
min = 2.0 * lmass;
max = pmass - omass;
binwidth = (max - min) / (Double_t)nbins;
if ( idecay == 1 )
fEPMass = new TH1F("fEPMass", "Dalitz electron pair", nbins, min, max);
else
fMPMass = new TH1F("fMPMass", "Dalitz muon pair", nbins, min, max);
epsilon = (lmass / pmass) * (lmass / pmass);
delta = (omass / pmass) * (omass / pmass);
for ( ibin = 1; ibin <= nbins; ibin++ )
{
mLL = min + (Double_t)(ibin - 1) * binwidth + binwidth / 2.0;
q = (mLL / pmass) * (mLL / pmass);
if ( q <= 4.0 * epsilon )
{
AliFatal("Error in calculating Dalitz mass histogram binning!");
}
kwHelp = (1.0 + q / (1.0 - delta)) * (1.0 + q / (1.0 - delta))
- 4.0 * q / ((1.0 - delta) * (1.0 - delta));
if ( kwHelp <= 0.0 )
{
AliFatal("Error in calculating Dalitz mass histogram binning!");
}
krollWada = (2.0 / mLL) * TMath::Exp(1.5 * TMath::Log(kwHelp))
* TMath::Sqrt(1.0 - 4.0 * epsilon / q)
* (1.0 + 2.0 * epsilon / q);
formFactor =
(TMath::Power(TMath::Power(0.6519,2),2))
/ (TMath::Power(TMath::Power(0.6519,2)-TMath::Power(mLL, 2), 2)
+ TMath::Power(0.04198, 2)*TMath::Power(0.6519, 2));
weight = krollWada * formFactor;
if ( idecay == 1 )
fEPMass->AddBinContent(ibin, weight);
else
fMPMass->AddBinContent(ibin, weight);
}
}
}
void AliOmegaDalitz::Decay(Int_t idlepton, TLorentzVector* pparent)
{
if (!fInit) {
Init();
fInit=1;
}
Double_t pmass, lmass, omass, lpmass;
Double_t e1, p1, e3, p3;
Double_t costheta, sintheta, cosphi, sinphi, phi;
lmass = (TDatabasePDG::Instance()->GetParticle(idlepton))->Mass();
pmass = pparent->M();
omass = (TDatabasePDG::Instance()->GetParticle(kPi0)) ->Mass();
for( ;; )
{
if ( idlepton == kElectron )
lpmass = fEPMass->GetRandom();
else
lpmass = fMPMass->GetRandom();
if ( pmass - omass > lpmass && lpmass / 2. > lmass ) break;
}
e1 = lpmass / 2.;
p1 = TMath::Sqrt((e1 + lmass) * (e1 - lmass));
costheta = (2.0 * gRandom->Rndm()) - 1.;
sintheta = TMath::Sqrt((1. + costheta) * (1. - costheta));
phi = 2.0 * TMath::ACos(-1.) * gRandom->Rndm();
sinphi = TMath::Sin(phi);
cosphi = TMath::Cos(phi);
Double_t pProd1[3] = {p1 * sintheta * cosphi,
p1 * sintheta * sinphi,
p1 * costheta};
Double_t pProd2[3] = {-1.0 * p1 * sintheta * cosphi,
-1.0 * p1 * sintheta * sinphi,
-1.0 * p1 * costheta};
e3 = (pmass * pmass + omass * omass - lpmass * lpmass)/(2. * pmass);
p3 = TMath::Sqrt((e3 + omass) * (e3 - omass));
costheta = (2.0 * gRandom->Rndm()) - 1.;
sintheta = TMath::Sqrt((1. + costheta) * (1. - costheta));
phi = 2.0 * TMath::ACos(-1.) * gRandom->Rndm();
sinphi = TMath::Sin(phi);
cosphi = TMath::Cos(phi);
fProducts[2].SetPx(p3 * sintheta * cosphi);
fProducts[2].SetPy(p3 * sintheta * sinphi);
fProducts[2].SetPz(p3 * costheta);
fProducts[2].SetE(e3);
Double_t pRot1[3] = {0.};
Rot(pProd1, pRot1, costheta, -sintheta, -cosphi, -sinphi);
Double_t pRot2[3] = {0.};
Rot(pProd2, pRot2, costheta, -sintheta, -cosphi, -sinphi);
fProducts[0].SetPx(pRot1[0]);
fProducts[0].SetPy(pRot1[1]);
fProducts[0].SetPz(pRot1[2]);
fProducts[0].SetE(e1);
fProducts[1].SetPx(pRot2[0]);
fProducts[1].SetPy(pRot2[1]);
fProducts[1].SetPz(pRot2[2]);
fProducts[1].SetE(e1);
Double_t eLPparent = TMath::Sqrt(p3 * p3 + lpmass * lpmass);
TVector3 boostPair( -1.0 * fProducts[2].Px() / eLPparent,
-1.0 * fProducts[2].Py() / eLPparent,
-1.0 * fProducts[2].Pz() / eLPparent);
fProducts[0].Boost(boostPair);
fProducts[1].Boost(boostPair);
TVector3 boostLab( pparent->Px() / pparent->E(),
pparent->Py() / pparent->E(),
pparent->Pz() / pparent->E());
fProducts[0].Boost(boostLab);
fProducts[1].Boost(boostLab);
fProducts[2].Boost(boostLab);
return;
}
Int_t AliOmegaDalitz::ImportParticles(TClonesArray *particles)
{
TClonesArray &clonesParticles = *particles;
Int_t pdg [3] = {kElectron, -kElectron, kPi0};
if ( fProducts[1].M() > 0.001 )
{
pdg[0] = kMuonPlus;
pdg[1] = -kMuonPlus;
}
Int_t parent[3] = {0, 0, -1};
Int_t d1 [3] = {-1, -1, 1};
Int_t d2 [3] = {-1, -1, 2};
for (Int_t i = 2; i > -1; i--) {
Double_t px = fProducts[i].Px();
Double_t py = fProducts[i].Py();
Double_t pz = fProducts[i].Pz();
Double_t e = fProducts[i].E();
new(clonesParticles[2 - i]) TParticle(pdg[i], 1, parent[i], -1, d1[i], d2[i], px, py, pz, e, 0., 0., 0., 0.);
}
return (3);
}
void AliOmegaDalitz::
Rot(Double_t pin[3], Double_t pout[3], Double_t costheta, Double_t sintheta,
Double_t cosphi, Double_t sinphi) const
{
pout[0] = pin[0]*costheta*cosphi-pin[1]*sinphi+pin[2]*sintheta*cosphi;
pout[1] = pin[0]*costheta*sinphi+pin[1]*cosphi+pin[2]*sintheta*sinphi;
pout[2] = -1.0 * pin[0] * sintheta + pin[2] * costheta;
return;
}
void AliOmegaDalitz::Decay(TClonesArray* array)
{
printf("-->Correcting Dalitz \n");
Int_t nt = array->GetEntriesFast();
TParticle* dp[3];
for (Int_t i = 0; i < nt; i++) {
TParticle* part = (TParticle*) (array->At(i));
if (part->GetPdgCode() != 223) continue;
Int_t fd = part->GetFirstDaughter() - 1;
Int_t ld = part->GetLastDaughter() - 1;
if (fd < 0) continue;
if ((ld - fd) != 2) continue;
for (Int_t j = 0; j < 3; j++) dp[j] = (TParticle*) (array->At(fd+j));
if ((dp[0]->GetPdgCode() != kPi0) ||
((TMath::Abs(dp[1]->GetPdgCode()) != kElectron) &&
(TMath::Abs(dp[1]->GetPdgCode()) != kMuonPlus))) continue;
TLorentzVector omega(part->Px(), part->Py(), part->Pz(), part->Energy());
if ( TMath::Abs(dp[1]->GetPdgCode()) == kElectron )
Decay(kElectron, &omega);
else
Decay(kMuonPlus, &omega);
for (Int_t j = 0; j < 3; j++) dp[j]->SetMomentum(fProducts[2-j]);
printf("original %13.3f %13.3f %13.3f %13.3f \n",
part->Px(), part->Py(), part->Pz(), part->Energy());
printf("new %13.3f %13.3f %13.3f %13.3f \n",
dp[0]->Px()+dp[1]->Px()+dp[2]->Px(),
dp[0]->Py()+dp[1]->Py()+dp[2]->Py(),
dp[0]->Pz()+dp[1]->Pz()+dp[2]->Pz(),
dp[0]->Energy()+dp[1]->Energy()+dp[2]->Energy());
}
}
AliOmegaDalitz& AliOmegaDalitz::operator=(const AliOmegaDalitz& rhs)
{
rhs.Copy(*this);
return *this;
}
void AliOmegaDalitz::Copy(TObject&) const
{
Fatal("Copy","Not implemented!\n");
}
AliOmegaDalitz::AliOmegaDalitz(const AliOmegaDalitz &dalitz)
: AliDecayer(),
fEPMass(0),
fMPMass(0),
fInit(0)
{
dalitz.Copy(*this);
}