Page MenuHomeHEPForge

No OneTemporary

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

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)

Event Timeline