Page Menu
Home
HEPForge
Search
Configure Global Search
Log In
Files
F8725549
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Award Token
Flag For Later
Size
18 KB
Subscribers
None
View Options
diff --git a/FixedOrderGen/include/PhaseSpacePoint.hh b/FixedOrderGen/include/PhaseSpacePoint.hh
index 5000cfc..464ecf7 100644
--- a/FixedOrderGen/include/PhaseSpacePoint.hh
+++ b/FixedOrderGen/include/PhaseSpacePoint.hh
@@ -1,122 +1,119 @@
/** \file PhaseSpacePoint.hh
* \brief Contains the PhaseSpacePoint Class
*/
#pragma once
#include <vector>
#include <CLHEP/Random/Randomize.h>
#include <CLHEP/Random/RanluxEngine.h>
#include "fastjet/JetDefinition.hh"
#include "RHEJ/utility.hh"
#include "RHEJ/Event.hh"
#include "RHEJ/PDG_codes.hh"
#include "RHEJ/PDF.hh"
namespace HEJFOG{
class Process;
using RHEJ::Sparticle;
//! A point in resummation phase space
class PhaseSpacePoint{
public:
//! Default PhaseSpacePoint Constructor
PhaseSpacePoint() = default;
//! PhaseSpacePoint Constructor
/**
* @param proc The process to generate
* @param jet_def The Jet Definition Used
* @param jetptmin Minimum Jet Transverse Momentum
* @param rapmax Maximum parton rapidity
* @param pdf The pdf set (used for sampling)
*/
PhaseSpacePoint(
Process const & proc,
fastjet::JetDefinition jet_def,double jetptmin, double rapmax, RHEJ::PDF & pdf
);
//! Get Weight Function
/**
* @returns Weight of Event
*/
double weight() const{
return weight_;
}
double status() const{
return status_;
}
//! Get Incoming Function
/**
* @returns Incoming Particles
*/
std::array<Sparticle, 2> const & incoming() const{
return incoming_;
}
//! Get Outgoing Function
/**
* @returns Outgoing Particles
*/
std::vector<Sparticle> const & outgoing() const{
return outgoing_;
}
static void reset_ranlux(std::string const & init_file);
static void reset_ranlux(char const * init_file);
private:
std::vector<fastjet::PseudoJet> gen_LO_partons(
int count, double ptmin, double ptmax, double rapmax
);
Sparticle gen_boson(
RHEJ::ParticleID bosonid
);
void rescale_rapidities(
std::vector<fastjet::PseudoJet> & partons,
double ymin, double ymax
);
bool jets_ok(
std::vector<fastjet::PseudoJet> const & Born_jets,
std::vector<fastjet::PseudoJet> const & partons
) const;
void reconstruct_incoming(RHEJ::PDF & pdf);
std::pair<RHEJ::ParticleID,RHEJ::ParticleID> GenerateFKLIncomingParticles(double xa,double ufa,double xb,double ufb,RHEJ::PDF & pdf);
- double phase_space_normalisation(
- int num_Born_jets
- ) const;
bool momentum_conserved(double ep) const;
RHEJ::Sparticle const & most_backward_FKL(
std::vector<RHEJ::Sparticle> const & partons
) const;
RHEJ::Sparticle const & most_forward_FKL(
std::vector<RHEJ::Sparticle> const & partons
) const;
RHEJ::Sparticle & most_backward_FKL(std::vector<RHEJ::Sparticle> & partons) const;
RHEJ::Sparticle & most_forward_FKL(std::vector<RHEJ::Sparticle> & partons) const;
bool extremal_FKL_ok(
std::vector<fastjet::PseudoJet> const & partons
) const;
bool unob_, unof_;
double weight_;
int status_;
double jetptmin_;
fastjet::JetDefinition jet_def_;
std::array<Sparticle, 2> incoming_;
std::vector<Sparticle> outgoing_;
static CLHEP::Ranlux64Engine ran_;
};
RHEJ::UnclusteredEvent to_UnclusteredEvent(PhaseSpacePoint const & psp);
}
diff --git a/FixedOrderGen/src/PhaseSpacePoint.cc b/FixedOrderGen/src/PhaseSpacePoint.cc
index 53fb2ac..5e8fd42 100644
--- a/FixedOrderGen/src/PhaseSpacePoint.cc
+++ b/FixedOrderGen/src/PhaseSpacePoint.cc
@@ -1,454 +1,447 @@
#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 nout = proc.njets + (proc.boson?1:0);
status_ = 0;
weight_ = 1;
weight_ /= std::tgamma(nout);
{
outgoing_.reserve(nout);
// sqrt(s)/2 is the maximum pt
for(auto&& p_out: gen_LO_partons(proc.njets, jetptmin_, 13000./2., rapmax)){
outgoing_.emplace_back(Sparticle{pid::gluon, std::move(p_out)});
}
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);
}
// 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_ /= 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
Tue, Jan 21, 1:48 AM (1 d, 14 h)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
4243563
Default Alt Text
(18 KB)
Attached To
rHEJ HEJ
Event Timeline
Log In to Comment