using namespace std;
#include <sstream>
#include <iostream>
#include <iomanip>
#include "PFermiMomentum.h"
#include "PDynamicData.h"
ClassImp(PFermiMomentum)
PFermiMomentum::PFermiMomentum() {
};
PFermiMomentum::PFermiMomentum(const Char_t *id, const Char_t *de, Int_t key) :
PChannelModel(id, de, key) {
beam = NULL;
target = NULL;
spectator = NULL;
parent = NULL;
p1 = NULL;
p2 = NULL;
composite = NULL;
SetNpx(500);
fXmin = 0.;
fXmax = 1.;
mesh = NULL;
spline = kFALSE;
g_spline = NULL;
mom = NULL;
didx_composite = -1;
composite_model = NULL;
tcross_key = makeStaticData()->MakeDirectoryEntry("modeldef", NMODEL_NAME, LMODEL_NAME, "tcross");
relative_warning = 0;
};
PDistribution *PFermiMomentum::Clone(const char *) const {
return new PFermiMomentum((const PFermiMomentum &)* this);
};
PFermiMomentum::~PFermiMomentum() {
if (mesh) delete mesh;
};
double PFermiMomentum::SampleFermi(double &px, double &py, double &pz) {
double p = this->GetRandom();
while (p>0.3)
p = this->GetRandom();
double theta = acos(1.-2.*PUtils::sampleFlat());
double phi = 2.*TMath::Pi()*PUtils::sampleFlat();
double sth = sin(theta);
px = p*cos(phi)*sth;
py = p*sin(phi)*sth;
pz = p*cos(theta);
return p;
};
Double_t PFermiMomentum::GetWeight(Double_t *mass, Int_t *) {
double p = mass[0];
double theta = acos(mass[1]);
double phi = 2.*TMath::Pi()*PUtils::sampleFlat();
double sth = sin(theta);
px = p*cos(phi)*sth;
py = p*sin(phi)*sth;
pz = p*cos(theta);
Double_t massS, eS, eP, ptot, t=-1., mdeut;
ptot = sqrt(px*px+py*py+pz*pz);
massS = spectator->M();
eS = sqrt(ptot*ptot + massS*massS);
mdeut = makeStaticData()->GetParticleMass("d");
t = pow(mdeut-massS,2) - 2.*mdeut*(eS-massS);
eP = sqrt(ptot*ptot + t);
TLorentzVector my_part(px,py,pz,eP);
TLorentzVector my_q = my_part + my_beam;
Double_t my_sqrt = my_q.M();
Double_t w = Eval(p);
if (composite_model && (!(composite_model->GetVersionFlag()) & VERSION_WEIGHTING)) {
w *= composite_model->GetWeight(&my_sqrt);
}
return w;
};
double PFermiMomentum::EvalPar(const double *x, const double *) {
return Eval(x[0]);
};
Double_t PFermiMomentum::Eval(Double_t x, Double_t, Double_t, Double_t) const {
double p = x;
double r = p/0.197;
if (mom) {
Double_t x = mom->Eval(r, g_spline, "");
if (x > 0) return r*r*x;
return 0;
}
const double sqrtpi2 = 0.79788456;
const double alpha = 0.23162461;
double m[13], m2[13];
for(int i=0; i<13; i++) {
m[i] = alpha + i;
m2[i] = m[i]*m[i];
}
double c[13] = {0.88688076e0, -0.34717093e0, -0.30502380e1, 0.56207766e2,
-0.74957334e3, 0.53365279e4, -0.22706863e5, 0.60434469e5,
-0.10292058e6, 0.11223357e6, -0.75925226e5, 0.29059715e5,
0.};
double d[13] = {0.23135193e-1, -0.85604572e0, 0.56068193e1, -0.69462922e2,
0.41631118e3, -0.12546621e4, 0.12387830e4, 0.33739172e4,
-0.13041151e5, 0.19512524e5, 0., 0., 0.};
c[12] = 0.;
for(int i=0; i<12; i++) c[12] -= c[i];
int n = 12, n1 = 11, n2 = 10;
double sum1 = 0.;
double sum2 = 0.;
double sum3 = 0.;
double rtemp;
for(int i=0; i<5; i++) {
rtemp = d[i*2]/m2[i*2] + d[i*2+1]/m2[i*2+1];
sum1 = sum1 + rtemp;
rtemp = d[i*2] + d[i*2+1];
sum2 = sum2 + rtemp;
rtemp = d[i*2]*m2[i*2] + d[i*2+1]*m2[i*2+1];
sum3 = sum3 + rtemp;
}
for(int i=0; i<3; i++) {
d[n2] = -m2[n1]*m2[n]*sum1 + (m2[n1]+m2[n])*sum2 - sum3;
d[n2] = d[n2] * m2[n2]/(m2[n]-m2[n2])/(m2[n1]-m2[n2]);
int cycle = n2;
n2 = n1;
n1 = n;
n = cycle;
}
double U = 0.;
double W = 0.;
for(int i=0; i<13; i++) {
U += c[i]/(r*r + m2[i]);
W += d[i]/(r*r + m2[i]);
}
U = sqrtpi2 * U;
W = sqrtpi2 * W;
return draw_scaling*r*r*(U*U + W*W);
};
Bool_t PFermiMomentum::IsNotRejected(void) {
return kTRUE;
};
Bool_t PFermiMomentum::Init(void) {
num_of_sampledevents = num_of_realevents = 0;
beam = GetParticle("beam");
target = GetParticle("target");
parent = GetParticle("parent");
if (!beam || !target) {
Warning("Init", "<%s> beam or target not found",GetIdentifier());
return kFALSE;
}
spectator = GetParticle("spectator");
p1 = GetParticle("p1");
p2 = GetParticle("p2");
composite = GetParticle("composite");
if (!composite) {
Warning("Init", "<%s> composite not found", GetIdentifier());
return kFALSE;
}
return kTRUE;
}
int PFermiMomentum::GetDepth(int) {
return 0;
}
void PFermiMomentum::SubPrint(Int_t) const {
if (composite_model) {cout << " {";cout << composite_model->GetIdentifier()<<"}";}
}
Bool_t PFermiMomentum::Prepare(void) {
if (composite) {
didx_composite = composite->GetDecayModeIndex(1);
if (didx_composite > 0) {
composite_model =
makeDynamicData()->GetDecayModelByKey(
makeStaticData()->GetDecayKey(didx_composite), tcross_key);
}
}
return kTRUE;
}
Bool_t PFermiMomentum::SampleMass(void) {
Int_t beam_breakup = 0;
if ((beam->ID() == makeStaticData()->GetParticleID("d")) && (
target->ID() != makeStaticData()->GetParticleID("d"))) {
beam_breakup = 1;
}
else if ((beam->ID() == makeStaticData()->GetParticleID("d")) && (
target->ID() == makeStaticData()->GetParticleID("d"))) {
Double_t is_breakup = 0;
if (beam->GetValue(IS_BREAKUP, &is_breakup))
beam_breakup = 1;
else if (!target->GetValue(IS_BREAKUP, &is_breakup)) {
beam_breakup=(PUtils::sampleFlat() < 0.5 ? 0 : 1);
}
}
PParticle participant;
if (spectator->ID() == 14) {
participant.SetID(13);
participant_mass = makeStaticData()->GetParticleMass("n");
} else {
participant.SetID(14);
participant_mass = makeStaticData()->GetParticleMass("p");
}
Int_t makeloop = kTRUE;
num_of_realevents++;
while (makeloop) {
num_of_sampledevents++;
exp_w_mean = (Double_t)num_of_realevents/(Double_t)num_of_sampledevents;
makeloop = kFALSE;
if (!composite_model || ((composite_model->GetVersionFlag()) & VERSION_WEIGHTING)) {
Double_t massS, eS, eP, ptot, px, py, pz, t=-1., mdeut;
while (t < 0.) {
ptot = SampleFermi(px,py,pz);
massS = spectator->M();
eS = sqrt(ptot*ptot + massS*massS);
mdeut = makeStaticData()->GetParticleMass("d");
t = pow(mdeut-massS,2) - 2.*mdeut*(eS-massS);
}
eP = sqrt(ptot*ptot + t);
participant.SetPxPyPzE(-px, -py, -pz, eP);
spectator->SetPxPyPzE(px, py, pz, eS);
} else {
if (beam_breakup) {
my_beam = *target;
my_beam.Boost(-beam->BoostVector());
} else {
my_beam = *beam;
my_beam.Boost(-target->BoostVector());
}
if (!mesh) {
debug_print = 0;
mesh = new PAdaptiveMeshN(0x3, 2, this, 1.);
mesh->SetRange(0, 0., 0.300);
mesh->SetRange(1, -1., +1.);
mesh->ReCalcYMax();
mesh->SetThreshold(1.5, 0.01);
mesh->SetMCPoints(1000);
mesh->Divide(5, 2);
}
debug_print = 1;
mesh->GetRandom();
Double_t massS, eS, eP, ptot, t=-1., mdeut;
ptot = sqrt(px*px+py*py+pz*pz);
massS = spectator->M();
eS = sqrt(ptot*ptot + massS*massS);
mdeut = makeStaticData()->GetParticleMass("d");
t = pow(mdeut-massS,2) - 2.*mdeut*(eS-massS);
eP = sqrt(ptot*ptot + t);
participant.SetPxPyPzE(px, py, pz, eP);
spectator->SetPxPyPzE(-px, -py, -pz, eS);
}
if (beam_breakup) {
participant.Boost(beam->BoostVector());
spectator->Boost(beam->BoostVector());
if (target->ID() == p1->ID()) {
*p1 = *target;
*p2 = participant;
} else {
*p2 = *target;
*p1 = participant;
}
} else {
participant.Boost(target->BoostVector());
spectator->Boost(target->BoostVector());
if (beam->ID() == p1->ID()) {
*p1 = *beam;
*p2 = participant;
} else {
*p2 = *beam;
*p1 = participant;
}
}
p1->Boost(-parent->BoostVector());
p2->Boost(-parent->BoostVector());
spectator->Boost(-parent->BoostVector());
composite->Reconstruct();
if (composite_model && ((composite_model->GetVersionFlag()) & VERSION_WEIGHTING)) {
if (composite_model->GetWeight(composite->M()) <= 0.) {
makeloop = kTRUE;
}
}
}
p1->Boost(parent->BoostVector());
p2->Boost(parent->BoostVector());
spectator->SetW(parent->W());
return kTRUE;
}
Bool_t PFermiMomentum:: SampleMomentum(void) {
return kTRUE;
}
void PFermiMomentum::Print(const Option_t *) const {
PDistribution::Print();
}