Page Menu
Home
HEPForge
Search
Configure Global Search
Log In
Files
F9501462
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Award Token
Flag For Later
Size
15 KB
Subscribers
None
View Options
diff --git a/FixedOrderGen/src/PhaseSpacePoint.cc b/FixedOrderGen/src/PhaseSpacePoint.cc
index fe55268..1f618b0 100644
--- a/FixedOrderGen/src/PhaseSpacePoint.cc
+++ b/FixedOrderGen/src/PhaseSpacePoint.cc
@@ -1,464 +1,459 @@
#include "PhaseSpacePoint.hh"
#include <random>
// #include "RHEJ/resummation_jet_momenta.hh"
// #include "RHEJ/Jacobian.hh"
// #include "RHEJ/RNGWrapper.hh"
// #include "RHEJ/uno.hh"
#include "RHEJ/debug.hh"
#include "RHEJ/kinematics.hh"
#include "RHEJ/utility.hh"
#include "Process.hh"
using namespace RHEJ;
namespace HEJFOG{
static_assert(
std::numeric_limits<double>::has_quiet_NaN,
"no quiet NaN for double"
);
constexpr double NaN = std::numeric_limits<double>::quiet_NaN();
RHEJ::UnclusteredEvent to_UnclusteredEvent(PhaseSpacePoint const & psp){
RHEJ::UnclusteredEvent result;
result.incoming = psp.incoming();
std::sort(
begin(result.incoming), end(result.incoming),
[](Sparticle o1, Sparticle o2){return o1.p.pz()<o2.p.pz();}
);
assert(result.incoming.size() == 2);
result.outgoing = psp.outgoing();
assert(
std::is_sorted(
begin(result.outgoing), end(result.outgoing),
RHEJ::rapidity_less{}
)
);
assert(result.outgoing.size() >= 2);
result.central.mur = NaN;
result.central.muf = NaN;
result.central.weight = psp.weight();
return result;
}
namespace{
//generate Ranlux64Engine with fixed, predefined state
/*
* some (all?) of the Ranlux64Engine constructors leave fields
* uninitialised, invoking undefined behaviour. This can be
* circumvented by restoring the state from a file
*/
CLHEP::Ranlux64Engine gen_Ranlux64Engine(){
static const std::string state =
"9876\n"
"0.91280703978419097666\n"
"0.41606065829518357191\n"
"0.99156342622341142601\n"
"0.030922955274050423213\n"
"0.16206278421638486975\n"
"0.76151768001958330956\n"
"0.43765760066092695979\n"
"0.42904698253748563275\n"
"0.11476317525663759511\n"
"0.026620053590963976831\n"
"0.65953715764414511114\n"
"0.30136722624439826745\n"
"3.5527136788005009294e-15 4\n"
"1 202\n";
const std::string file = std::tmpnam(nullptr);
{
std::ofstream out{file};
out << state;
}
CLHEP::Ranlux64Engine result;
result.restoreStatus(file.c_str());
return result;
}
}
CLHEP::Ranlux64Engine PhaseSpacePoint::ran_{gen_Ranlux64Engine()};
void PhaseSpacePoint::reset_ranlux(std::string const & init_file){
reset_ranlux(init_file.c_str());
}
void PhaseSpacePoint::reset_ranlux(char const * init_file){
ran_.restoreStatus(init_file);
}
PhaseSpacePoint::PhaseSpacePoint(
Process const & proc,
fastjet::JetDefinition jet_def,double jetptmin, double rapmax,RHEJ::PDF & pdf
):
unob_(false),
unof_(false),
jetptmin_{jetptmin},
jet_def_{jet_def}
{
const int nj = proc.njets;
status_ = 0;
weight_ = 1;
weight_ /= std::tgamma(nj + 1);
{
outgoing_.reserve(nj + 1); // one slot for possible A, W, Z, H
{
// sqrt(s)/2 is the maximum pt
std::vector<fastjet::PseudoJet> out_partons = gen_LO_partons(nj , jetptmin_,13000./2.,rapmax);
- if (status_==0) {
- if (out_partons.empty())
- return;
- // define flavour and incoming states
-
- // Make them all gluons
- for(auto & p: out_partons){
- outgoing_.emplace_back(Sparticle{pid::gluon, std::move(p)});
- }
-
+ // Make them all gluons
+ for(auto & p: out_partons){
+ outgoing_.emplace_back(Sparticle{pid::gluon, std::move(p)});
}
+ }
+ if(status_ != 0) return;
- if(proc.boson && *proc.boson == pid::Higgs){
- // The Higgs
- auto Hparticle=gen_boson(pid::higgs);
- auto pos=std::upper_bound(
- begin(outgoing_),end(outgoing_),Hparticle,rapidity_less{}
- );
- outgoing_.insert(pos,Hparticle);
- }
+ if(proc.boson && *proc.boson == pid::Higgs){
+ // The Higgs
+ auto Hparticle=gen_boson(pid::higgs);
+ auto pos=std::upper_bound(
+ begin(outgoing_),end(outgoing_),Hparticle,rapidity_less{}
+ );
+ outgoing_.insert(pos,Hparticle);
}
+
weight_ /= (256.*pow(M_PI,5));
// call to pdfs and determination of flavour IDs missing here
reconstruct_incoming(pdf);
if(status_ != 0) return;
// set outgoing states
most_backward_FKL(outgoing_).type = incoming_[0].type;
most_forward_FKL(outgoing_).type = incoming_[1].type;
}
}
std::vector<fastjet::PseudoJet> PhaseSpacePoint::gen_LO_partons(
int np , double ptmin, double ptmax, double rapmax
){
if (np<2) throw std::invalid_argument{"Not enough partons in gen_LO_partons"};
// heuristic parameters for pt sampling
const double ptpar = ptmin + np/5.;
const double temp1 = atan((ptmax - ptmin)/ptpar);
weight_ /= std::tgamma(np + 1)*pow(16.*pow(M_PI,3),np-2);
std::vector<fastjet::PseudoJet> partons(np);
// Generate PTs:
for(size_t i = 0; i < (size_t) np; ++i){
const double r1 = ran_.flat();
const double pt = ptmin + ptpar*tan(r1*temp1);
const double temp2 = cos(r1*temp1);
const double phi = 2*M_PI*ran_.flat();
weight_ *= 2.0*M_PI*pt*ptpar*temp1/(temp2*temp2);
// we don't know the allowed rapidity span yet,
// set a random value to be rescaled later on
const double y = ran_.flat();
partons[i].reset_PtYPhiM(pt, y, phi);
partons[i].set_user_index(i + 1);
assert(ptmin-1e-5 <= partons[i].pt() && partons[i].pt() <= ptmax+1e-5);
}
// Generate rapidities:
{
// generate ymin, ymax;
double ycenter=-rapmax/2;
double ymin,Dy;
// ymin :
{
double lninvr1,r1,r2,temp;
constexpr double a=2.;
r1=ran_.flat();
r2=ran_.flat();
lninvr1=-log(r1);
temp=a*sqrt(2.*lninvr1)*cos(2.*M_PI*r2);
ymin=(temp-ycenter);
weight_*=(exp(temp*temp/2./a/a))*sqrt(2.*M_PI)*a;
}
// Dy :
{
//Better do binomial distribution - still with a expected length increasing with np
//Exponential decay on Dy?
// should reflect a linear increase in rapidity length with the number of jets
double a=.5/(np-1);
Dy=log(ran_.flat())/(-a);
weight_/=a;
}
if (std::max(abs(ymin),abs(ymin+Dy))>rapmax) {
weight_=0.0;
status_ = 1;
return {};
}
rescale_rapidities(partons,ymin,ymin+Dy);
}
// Need to check that at LO, the number of jets = number of partons;
// assert(std::all_of(partons.cbegin(), partons.cend(), is_nonjet_parton));
fastjet::ClusterSequence cs(partons, jet_def_);
auto cluster_jets=cs.inclusive_jets(jetptmin_);
if (cluster_jets.size()!=unsigned(np)){
weight_=0.0;
status_ = 2;
return {};
}
std::sort(begin(partons), end(partons), rapidity_less{});
return partons;
}
Sparticle PhaseSpacePoint::gen_boson(
RHEJ::ParticleID bosonid
){
std::array<double,2> ptrans{0.,0.};
for (auto const & parton:outgoing_) {
ptrans[0]-=parton.px();
ptrans[1]-=parton.py();
}
// The Higgs:
// Generate a y Gaussian distributed around 0
double lninvr1,r1,r2,temp,a;
r1=ran_.flat();
r2=ran_.flat();
lninvr1=-log(r1);
a=1.6;
temp=a*sqrt(2.*lninvr1)*cos(2.*M_PI*r2);
double y=temp;
weight_=weight_*(exp(temp*temp/2./a/a))*sqrt(2.*M_PI)*a;
// r1=ran.flat();
// double sH=flags.mH*(flags.mH + flags.GammaH*tan((M_PI*r1)/2. + (-1. + r1)*atan(flags.mH/flags.GammaH)));
double sH=125.*125.;
double mHperp=sqrt(ptrans[0]*ptrans[0]+ptrans[1]*ptrans[1]+sH);
double pz=mHperp*sinh(y);
double E=mHperp*cosh(y);
return Sparticle{bosonid,fastjet::PseudoJet{ptrans[0],ptrans[1],pz,E}};
}
void PhaseSpacePoint::rescale_rapidities(
std::vector<fastjet::PseudoJet> & partons,
double ymin, double ymax
){
constexpr double ep = 1e-7;
for(auto & parton: partons){
assert(0 <= parton.rapidity() && parton.rapidity() <= 1);
const double dy = ymax - ymin - 2*ep;
const double y = ymin + ep + dy*parton.rapidity();
parton.reset_momentum_PtYPhiM(parton.pt(), y, parton.phi());
weight_ *= dy;
assert(ymin <= parton.rapidity() && parton.rapidity() <= ymax);
}
}
Sparticle const & PhaseSpacePoint::most_backward_FKL(
std::vector<Sparticle> const & partons
) const{
if(unob_) return partons[1];
if(!RHEJ::is_parton(partons[0])) return partons[1];
return partons[0];
}
Sparticle const & PhaseSpacePoint::most_forward_FKL(
std::vector<Sparticle> const & partons
) const{
const size_t last_idx = partons.size() - 1;
if(unof_) return partons[last_idx-1];
if(!RHEJ::is_parton(partons[last_idx])) return partons[last_idx-1];
return partons[last_idx];
}
Sparticle & PhaseSpacePoint::most_backward_FKL(
std::vector<Sparticle> & partons
) const{
if(unob_) return partons[1];
if(!RHEJ::is_parton(partons[0])) return partons[1];
return partons[0];
}
Sparticle & PhaseSpacePoint::most_forward_FKL(
std::vector<Sparticle> & partons
) const{
const size_t last_idx = partons.size() - 1;
if(unof_) return partons[last_idx-1];
if(!RHEJ::is_parton(partons[last_idx])) return partons[last_idx-1];
return partons[last_idx];
}
void PhaseSpacePoint::reconstruct_incoming(
RHEJ::PDF & pdf
){
std::tie(incoming_[0].p, incoming_[1].p) = incoming_momenta(outgoing_);
// calculate xa, xb
constexpr double sqrts=13000.;
double xa=(incoming_[0].p.e()-incoming_[0].p.pz())/sqrts;
double xb=(incoming_[1].p.e()+incoming_[1].p.pz())/sqrts;
// abort if phase space point is outside of collider energy reach
if (xa>1.||xb>1.) {
weight_=0;
status_ = 3;
return;
}
// pick pdfs
/** TODO:
* ufa, ufb don't correspond to our final scale choice.
* The reversed HEJ scale generators currently expect a full event as input,
* so fixing this is not completely trivial
*/
double ufa=jetptmin_;
double ufb=jetptmin_;
std::tie(incoming_[0].type,incoming_[1].type)=GenerateFKLIncomingParticles(xa,ufa,xb,ufb,pdf);
assert(momentum_conserved(1e-7));
}
std::pair<RHEJ::ParticleID,RHEJ::ParticleID> PhaseSpacePoint::GenerateFKLIncomingParticles(double xa,double ufa,double xb,double ufb,RHEJ::PDF & pdf)
{
double r1,lwt(1.),sum;
RHEJ::ParticleID aptype,bptype;
double pdfa,pdfb,pdfda,pdfdb,pdfuxa,pdfuxb,pdfdxa,pdfdxb,pdfga,pdfba,pdfgb,pdfsa,pdfsxa,pdfsb,pdfsxb,pdfca,pdfcb,pdfua,pdfub,pdfbb;
pdfga=fabs(pdf.pdfpt(0,xa,ufa,pid::gluon));
pdfua=fabs(pdf.pdfpt(0,xa,ufa,pid::up));
pdfda=fabs(pdf.pdfpt(0,xa,ufa,pid::down));
pdfuxa=fabs(pdf.pdfpt(0,xa,ufa,pid::u_bar));
pdfdxa=fabs(pdf.pdfpt(0,xa,ufa,pid::d_bar));
pdfca=fabs(pdf.pdfpt(0,xa,ufa,pid::charm));
pdfsa=fabs(pdf.pdfpt(0,xa,ufa,pid::strange));
pdfsxa=fabs(pdf.pdfpt(0,xa,ufa,pid::s_bar));
pdfba=fabs(pdf.pdfpt(0,xa,ufa,pid::b));
pdfa=pdfga+4.0/9.0*(pdfua + pdfda + pdfuxa + pdfdxa +pdfsa +pdfsxa + 2.0*(pdfca +pdfba ));
r1=pdfa*ran_.flat();
#if 1
if (r1<(sum=pdfga)) {
aptype=pid::gluon;
lwt*=pdfa/pdfga;}
else if (r1<(sum+=(4./9.)*pdfua)) {
aptype=pid::up;
lwt*=pdfa/((4./9.)*pdfua); }
else if (r1<(sum+=(4./9.)*pdfda)) {
aptype=pid::down;
lwt*=pdfa/((4./9.)*pdfda); }
else if (r1<(sum+=(4./9.)*pdfuxa)) {
aptype=pid::u_bar;
lwt*=pdfa/((4./9.)*pdfuxa); }
else if (r1<(sum+=(4./9.)*pdfdxa)) {
aptype=pid::d_bar;
lwt*=pdfa/((4./9.)*pdfdxa); }
else if (r1<(sum+=(4./9.)*pdfca)) {
aptype=pid::c;
lwt*=pdfa/((4./9.)*pdfca); }
else if (r1<(sum+=(4./9.)*pdfca)){
aptype=pid::c_bar;
lwt*=pdfa/((4./9.)*pdfca); }
else if (r1<(sum+=(4./9.)*pdfsa)) {
aptype=pid::s;
lwt*=pdfa/((4./9.)*pdfsa); }
else if (r1<(sum+=(4./9.)*pdfsxa)) {
aptype=pid::s_bar;
lwt*=pdfa/((4./9.)*pdfsxa); }
else if (r1<(sum+=(4./9.)*pdfba)) {
aptype=pid::b;
lwt*=pdfa/((4./9.)*pdfba); }
else if (r1<=(sum+=(4./9.)*pdfba)) {
aptype=pid::b_bar;
lwt*=pdfa/((4./9.)*pdfba); }
else {
std::cout << "Error in choosing incoming parton a : "<<xa<<" "<<ufa<<" "<<sum<<" "<<pdfa<<" "<<r1;
std::cout << " "<<pdfga+4./9.*(pdfua+pdfuxa+pdfda+pdfdxa+pdfsa+pdfsxa+2.*(pdfca+pdfba))<<std::endl;
assert(false);
}
#else
aptype=pid::down;
#endif
// parton->mrst(xb,ufb);
// pdfb=max(0.,parton->cont.glu)+4.0/9.0*(max(0.,parton->cont.upv+parton->cont.usea) + max(0.,parton->cont.dnv+parton->cont.dsea) + max(0.,parton->cont.usea)+max(0.,parton->cont.dsea) + 2.0*(max(0.,parton->cont.str)+max(0.,parton->cont.chm)+max(0.,parton->cont.bot)));
// pdfb=fabs(parton->cont.glu)+4.0/9.0*(fabs(parton->cont.upv) + fabs(parton->cont.dnv) + 2.0*(fabs(parton->cont.usea)+fabs(parton->cont.dsea)+fabs(parton->cont.str)+fabs(parton->cont.chm)+fabs(parton->cont.bot)));
pdfgb=fabs(pdf.pdfpt(1,xb,ufb,pid::gluon));
pdfub=fabs(pdf.pdfpt(1,xb,ufb,pid::up));
pdfdb=fabs(pdf.pdfpt(1,xb,ufb,pid::down));
pdfuxb=fabs(pdf.pdfpt(1,xb,ufb,pid::u_bar));
pdfdxb=fabs(pdf.pdfpt(1,xb,ufb,pid::d_bar));
pdfcb=fabs(pdf.pdfpt(1,xb,ufb,pid::charm));
pdfsb=fabs(pdf.pdfpt(1,xb,ufb,pid::strange));
pdfsxb=fabs(pdf.pdfpt(1,xb,ufb,pid::s_bar));
pdfbb=fabs(pdf.pdfpt(1,xb,ufb,pid::b));
pdfb=pdfgb+4.0/9.0*(pdfub + pdfdb + pdfuxb + pdfdxb + pdfsb +pdfsxb +2.0*(pdfcb +pdfbb ));
r1=pdfb*ran_.flat();
#if 1
if (r1<(sum=pdfgb)) {
bptype=pid::gluon;
lwt*=pdfb/pdfgb; }
else if (r1<(sum+=(4./9.)*pdfub)) {
bptype=pid::up;
lwt*=pdfb/((4./9.)*pdfub); }
else if (r1<(sum+=(4./9.)*pdfdb)) {
bptype=pid::down;
lwt*=pdfb/((4./9.)*pdfdb); }
else if (r1<(sum+=(4./9.)*pdfuxb)) {
bptype=pid::u_bar;
lwt*=pdfb/((4./9.)*pdfuxb); }
else if (r1<(sum+=(4./9.)*pdfdxb)) {
bptype=pid::d_bar;
lwt*=pdfb/((4./9.)*pdfdxb); }
else if (r1<(sum+=(4./9.)*pdfcb)) {
bptype=pid::c;
lwt*=pdfb/((4./9.)*pdfcb); }
else if (r1<(sum+=(4./9.)*pdfcb)){
bptype=pid::c_bar;
lwt*=pdfb/((4./9.)*pdfcb); }
else if (r1<(sum+=(4./9.)*pdfsb)) {
bptype=pid::s;
lwt*=pdfb/((4./9.)*pdfsb); }
else if (r1<(sum+=(4./9.)*pdfsxb)) {
bptype=pid::s_bar;
lwt*=pdfb/((4./9.)*pdfsxb); }
else if (r1<(sum+=(4./9.)*pdfbb)) {
bptype=pid::b;
lwt*=pdfb/((4./9.)*pdfbb); }
else if (r1<(sum+=(4./9.)*pdfbb)) {
bptype=pid::b_bar;
lwt*=pdfb/((4./9.)*pdfbb); }
else {
std::cout << "Error in choosing incoming partons b : "<<xb<<" "<<ufb<<" "<<sum<<" "<<pdfb<<" "<<r1;
std::cout << " "<<pdfgb+4./9.*(pdfub+pdfuxb+pdfdb+pdfdxb+pdfsb+pdfsxb+2.*(pdfcb+pdfbb))<<std::endl;
assert(false);
}
#else
bptype=pid::gluon;
#endif
weight_*=lwt;
return std::make_pair(aptype,bptype);
}
double PhaseSpacePoint::phase_space_normalisation(
int num_Born_jets
) const{
return pow(16*pow(M_PI,3), num_Born_jets);
}
bool PhaseSpacePoint::momentum_conserved(double ep) const{
fastjet::PseudoJet diff;
for(auto const & in: incoming()) diff += in.p;
for(auto const & out: outgoing()) diff -= out.p;
return nearby_ep(diff, fastjet::PseudoJet{}, ep);
}
}
File Metadata
Details
Attached
Mime Type
text/x-diff
Expires
Sun, Feb 23, 2:28 PM (22 h, 24 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
4485616
Default Alt Text
(15 KB)
Attached To
rHEJ HEJ
Event Timeline
Log In to Comment