Page Menu
Home
HEPForge
Search
Configure Global Search
Log In
Files
F7879745
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Award Token
Flag For Later
Size
36 KB
Subscribers
None
View Options
diff --git a/MatrixElement/DrellYanBase.cc b/MatrixElement/DrellYanBase.cc
--- a/MatrixElement/DrellYanBase.cc
+++ b/MatrixElement/DrellYanBase.cc
@@ -1,973 +1,964 @@
// -*- C++ -*-
//
// This is the implementation of the non-inlined, non-templated member
// functions of the DrellYanBase class.
//
#include "DrellYanBase.h"
#include "ThePEG/Repository/EventGenerator.h"
#include "ThePEG/Interface/ClassDocumentation.h"
#include "ThePEG/Interface/Parameter.h"
#include "ThePEG/Interface/Reference.h"
#include "ThePEG/Persistency/PersistentOStream.h"
#include "ThePEG/Persistency/PersistentIStream.h"
#include "ThePEG/PDT/EnumParticles.h"
#include "Herwig/Shower/QTilde/Base/ShowerProgenitor.h"
#include "Herwig/Shower/QTilde/Base/ShowerParticle.h"
#include "Herwig/Shower/QTilde/Base/Branching.h"
#include "Herwig/Shower/RealEmissionProcess.h"
using namespace Herwig;
DrellYanBase::DrellYanBase()
: _channelwgtA(0.12), _channelwgtB(2.00), _nover(0), _maxwgt(0.),
_power(2.0),_preqqbar(6.5),_preqg(4.0),_pregqbar(4.0),
_min_pt(2.*GeV) {}
void DrellYanBase::persistentOutput(PersistentOStream & os) const {
os << _channelwgtA << _channelwgtB << _channelweights << _alpha
<< _power << _preqqbar << _preqg << _pregqbar << ounit( _min_pt, GeV )
<< _prefactor;
}
void DrellYanBase::persistentInput(PersistentIStream & is, int) {
is >> _channelwgtA >> _channelwgtB >> _channelweights >> _alpha
>> _power >> _preqqbar >> _preqg >> _pregqbar >> iunit( _min_pt, GeV )
>> _prefactor;
}
AbstractClassDescription<DrellYanBase> DrellYanBase::initDrellYanBase;
// Definition of the static class description member.
void DrellYanBase::Init() {
static ClassDocumentation<DrellYanBase> documentation
("The DrellYanBase class provides a base class for the"
" corrections to Drell-Yan type processes");
static Parameter<DrellYanBase,double> interfaceQQbarChannelWeight
("QQbarChannelWeight",
"The relative weights of the q qbar abd q g channels for selection."
" This is a technical parameter for the phase-space generation and "
"should not affect the results only the efficiency and fraction"
" of events with weight > 1.",
&DrellYanBase::_channelwgtA, 0.12, 0.01, 100.,
false, false, Interface::limited);
static Parameter<DrellYanBase,double> interfaceQGChannelWeight
("QGChannelWeight",
"The relative weights of the qg abd qbar g channels for selection."
" This is a technical parameter for the phase-space generation and "
"should not affect the results only the efficiency and fraction",
&DrellYanBase::_channelwgtB, 2., 0.01, 100.,
false, false, Interface::limited);
static Reference<DrellYanBase,ShowerAlpha> interfaceCoupling
("Coupling",
"Pointer to the object to calculate the coupling for the correction",
&DrellYanBase::_alpha, false, false, true, false, false);
static Parameter<DrellYanBase,double> interfacePower
("Power",
"The power for the sampling of the matrix elements",
&DrellYanBase::_power, 2.0, 1.0, 10.0,
false, false, Interface::limited);
static Parameter<DrellYanBase,double> interfacePrefactorqqbar
("Prefactorqqbar",
"The prefactor for the sampling of the q qbar channel",
&DrellYanBase::_preqqbar, 5.0, 0.0, 1000.0,
false, false, Interface::limited);
static Parameter<DrellYanBase,double> interfacePrefactorqg
("Prefactorqg",
"The prefactor for the sampling of the q g channel",
&DrellYanBase::_preqg, 3.0, 0.0, 1000.0,
false, false, Interface::limited);
static Parameter<DrellYanBase,double> interfacePrefactorgqbar
("Prefactorgqbar",
"The prefactor for the sampling of the g qbar channel",
&DrellYanBase::_pregqbar, 3.0, 0.0, 1000.0,
false, false, Interface::limited);
static Parameter<DrellYanBase, Energy> interfacePtMin
("minPt",
"The pt cut on hardest emision generation"
"2*(1-Beta)*exp(-sqr(intrinsicpT/RMS))/sqr(RMS)",
&DrellYanBase::_min_pt, GeV, 2.*GeV, ZERO, 100000.0*GeV,
false, false, Interface::limited);
}
void DrellYanBase::doinit() {
HwMEBase::doinit();
_channelweights.push_back(_channelwgtA/(1.+_channelwgtA));
_channelweights.push_back(_channelweights[0]+1./(1.+_channelwgtA)/(1+_channelwgtB));
_channelweights.push_back(1.0);
_prefactor.push_back(_preqqbar);
_prefactor.push_back(_preqg);
_prefactor.push_back(_pregqbar);
}
void DrellYanBase::dofinish() {
HwMEBase::dofinish();
if(_nover==0) return;
generator()->log() << "DrellYanBase when applying the hard correction "
<< _nover << " weights larger than one were generated of which"
<< " the largest was " << _maxwgt << "\n";
}
RealEmissionProcessPtr DrellYanBase::applyHardMatrixElementCorrection(PerturbativeProcessPtr born) {
// get the quark,antiquark
ParticleVector incoming;
vector<tcBeamPtr> beams;
pair<double,double> xnew;
for(unsigned int ix=0;ix<born->incoming().size();++ix) {
incoming.push_back(born->incoming()[ix].first);
tPPtr beam = incoming.back()->parents()[0];
beams.push_back(dynamic_ptr_cast<tcBeamPtr>(beam->dataPtr()));
if(ix==0)
xnew.first = incoming[ix]->momentum().rho()/beam->momentum().rho();
else
xnew.second = incoming[ix]->momentum().rho()/beam->momentum().rho();
}
// ensure that the quark is first
if(incoming[0]->id()<incoming[1]->id()) {
swap(incoming[0],incoming[1]);
swap(beams[0],beams[1]);
swap(xnew.first,xnew.second);
}
// and the gauge boson
Lorentz5Momentum pboson;
for(unsigned int ix=0;ix<born->outgoing().size();++ix) {
pboson += born->outgoing()[ix].first->momentum();
}
pboson.rescaleMass();
// calculate the momenta
unsigned int iemit,itype;
vector<Lorentz5Momentum> pnew;
LorentzRotation trans;
-
-
- cerr << *incoming[0] << "\n";
- cerr << *incoming[1] << "\n";
- cerr << beams[0]->fullName() << " " << beams[1]->fullName() << "\n";
- cerr << pboson/GeV << "\n";
- cerr << xnew.first << " " << xnew.second << "\n";
-
// if not accepted return
if(!applyHard(incoming,beams,pboson,iemit,itype,pnew,trans,xnew)) return RealEmissionProcessPtr();
// process to be returned
RealEmissionProcessPtr real(new_ptr(RealEmissionProcess(born)));
// if applying ME correction create the new particles
// first the final-state particles
Boost boostv=pboson.findBoostToCM();
trans *=LorentzRotation(boostv);
real->transformation(trans);
for(unsigned int ix=0;ix<born->outgoing().size();++ix) {
Lorentz5Momentum pnew = trans*(born->outgoing()[ix].first->momentum());
real->outgoing().push_back(make_pair(born->outgoing()[ix].first->dataPtr()->produceParticle(pnew),
PerturbativeProcessPtr()));
- cerr << "outgoing " << *real->outgoing()[ix].first << "\n";
}
// then emitter, spectator and emitted
// emission of a final-state gluon
if(itype==0) {
// get the momenta of the new particles
Lorentz5Momentum pquark(pnew[0]),panti(pnew[1]),pgluon(pnew[2]);
if(iemit==2) swap(pquark,panti);
// ensure gluon can be put on shell
Lorentz5Momentum ptest(pgluon);
if(ptest.boost(-(pquark+panti).boostVector()).e() <
getParticleData(ParticleID::g)->constituentMass()) return RealEmissionProcessPtr();
// outgoing gluon
real->outgoing().push_back(make_pair(getParticleData(ParticleID::g)->produceParticle(pgluon),
PerturbativeProcessPtr()));
// incoming particles
if(born->incoming()[0].first->id()>0) {
if(iemit==1) {
real->emitter(0);
real->spectator(1);
}
else {
real->emitter(1);
real->spectator(0);
}
real->incoming().push_back(make_pair(born->incoming()[0].first->dataPtr()->produceParticle(pquark),
PerturbativeProcessPtr()));
real->incoming().push_back(make_pair(born->incoming()[1].first->dataPtr()->produceParticle(panti),
PerturbativeProcessPtr()));
real->outgoing().back().first->incomingColour(real->incoming()[0].first);
real->outgoing().back().first->incomingAntiColour(real->incoming()[1].first);
}
else {
if(iemit==1) {
real->emitter(1);
real->spectator(0);
}
else {
real->emitter(0);
real->spectator(1);
}
real->incoming().push_back(make_pair(born->incoming()[0].first->dataPtr()->produceParticle(panti),
PerturbativeProcessPtr()));
real->incoming().push_back(make_pair(born->incoming()[1].first->dataPtr()->produceParticle(pquark),
PerturbativeProcessPtr()));
real->outgoing().back().first->incomingColour(real->incoming()[1].first);
real->outgoing().back().first->incomingAntiColour(real->incoming()[0].first);
}
}
else if(itype==1) {
Lorentz5Momentum pin(pnew[0]),pout(pnew[1]),pgluon(pnew[2]);
if(iemit==2) swap(pin,pout);
// ensure outgoing quark can be put on-shell
Lorentz5Momentum ptest(pout);
if(ptest.boost(-(pin+pgluon).boostVector()).e() <
incoming[1]->dataPtr()->constituentMass()) return RealEmissionProcessPtr();
// create the new gluon
PPtr newg = getParticleData(ParticleID::g)->produceParticle(pgluon);
// create the new outgoing quark
PPtr newout= incoming[1]->dataPtr()->CC()->produceParticle(pout);
// create the new incoming quark
PPtr newin = incoming[0]->dataPtr()->produceParticle(pin);
// colours
newout->incomingColour(newg);
newin->antiColourNeighbour(newg);
if(born->incoming()[0].first->id()>0) {
real->emitter (1);
real->spectator(0);
real->incoming().push_back(make_pair(newin,PerturbativeProcessPtr()));
real->incoming().push_back(make_pair(newg,PerturbativeProcessPtr()));
}
else {
real->emitter (0);
real->spectator(1);
real->incoming().push_back(make_pair(newg ,PerturbativeProcessPtr()));
real->incoming().push_back(make_pair(newin,PerturbativeProcessPtr()));
}
real->outgoing().push_back(make_pair(newout,PerturbativeProcessPtr()));
}
else if(itype==2) {
Lorentz5Momentum pin(pnew[0]),pout(pnew[1]),pgluon(pnew[2]);
if(iemit==2) swap(pin,pout);
// ensure outgoing antiquark can be put on-shell
Lorentz5Momentum ptest(pout);
if(ptest.boost(-(pin+pgluon).boostVector()).e() <
incoming[0]->dataPtr()->constituentMass()) return RealEmissionProcessPtr();
// create the new gluon
PPtr newg = getParticleData(ParticleID::g)->produceParticle(pgluon);
// create the new outgoing antiquark
PPtr newout= incoming[0]->dataPtr()->CC()->produceParticle(pout);
// create the new incoming antiquark
PPtr newin = incoming[1]->dataPtr()->produceParticle(pin);
// colours
newout->incomingAntiColour(newg);
newin->colourNeighbour(newg);
if(born->incoming()[0].first->id()>0) {
real->emitter (0);
real->spectator(1);
real->incoming().push_back(make_pair(newg ,PerturbativeProcessPtr()));
real->incoming().push_back(make_pair(newin,PerturbativeProcessPtr()));
}
else {
real->emitter (1);
real->spectator(0);
real->incoming().push_back(make_pair(newin,PerturbativeProcessPtr()));
real->incoming().push_back(make_pair(newg ,PerturbativeProcessPtr()));
}
real->outgoing().push_back(make_pair(newout,PerturbativeProcessPtr()));
}
else
assert(false);
real->emitted(real->outgoing().size()+1);
if(born->incoming()[0].first->id()>0) {
swap(xnew.first,xnew.second);
}
real->x(xnew);
return real;
}
bool DrellYanBase::applyHard(ParticleVector & quarks,
vector<tcBeamPtr> beams, Lorentz5Momentum boson,
unsigned int & iemit,unsigned int & itype,
vector<Lorentz5Momentum> & pnew,
LorentzRotation & trans,
pair<double,double> & xout) {
// check that quark along +z and qbar along -z
bool quarkplus=quarks[0]->momentum().z()>quarks[1]->momentum().z();
// calculate the limits on s
Energy mb = sqrt(mb2_);
Energy2 smin=mb2_;
Energy2 s=
(generator()->currentEvent()->incoming().first ->momentum()+
generator()->currentEvent()->incoming().second->momentum()).m2();
Energy2 smax(s);
// calculate the rapidity of the boson
double yB=0.5*log((boson.e()+boson.z())/
(boson.e()-boson.z()));
if(!quarkplus) yB=-yB;
// if no phase-space return
if(smax<smin) return false;
// get the evolution scales (this needs improving)
double kappa[2]={1.,1.};
// get the momentum fractions for the leading order process
// and the values of the PDF's
double x[2]={-99.99e99,-99.99e99}, fx[2]={-99.99e99,-99.99e99};
tcPDFPtr pdf[2];
x[0] = xout. first;
x[1] = xout.second;
for(unsigned int ix=0;ix<quarks.size();++ix) {
assert(beams[ix]);
pdf[ix]=beams[ix]->pdf();
assert(pdf[ix]);
fx[ix]=pdf[ix]->xfx(beams[ix],quarks[ix]->dataPtr(),mb2_,x[ix]);
}
// select the type of process and generate the kinematics
double rn(UseRandom::rnd());
Energy2 shat(ZERO),uhat(ZERO),that(ZERO);
double weight(0.),xnew[2]={1.,1.};
// generate the value of s according to 1/s^2
shat = smax*smin/(smin+UseRandom::rnd()*(smax-smin));
Energy2 jacobian = sqr(shat)*(1./smin-1./smax);
double sbar=shat/mb2_;
// calculate limits on that
Energy2 tmax=mb2_*kappa[0]*(1.-sbar)/(kappa[0]+sbar);
Energy2 tmin=shat*(1.-sbar)/(kappa[1]+sbar);
// calculate the limits on uhat
Energy2 umax(mb2_-shat-tmin),umin(mb2_-shat-tmax);
// check inside phase space
if(tmax<tmin||umax<umin) return false;
// q qbar -> g V
if(rn<_channelweights[0]) {
// generate t and u according to 1/t+1/u
// generate in 1/t
if(UseRandom::rndbool(0.5)) {
that=tmax*pow(tmin/tmax,UseRandom::rnd());
uhat=mb2_-shat-that;
jacobian *=log(tmin/tmax);
}
// generate in 1/u
else {
uhat=umax*pow(umin/umax,UseRandom::rnd());
that=mb2_-shat-uhat;
jacobian *=log(umin/umax);
}
Energy4 jacobian2 = jacobian * 2.*uhat*that/(shat-mb2_);
// new scale (this is mt^2=pt^2+mb^2)
Energy2 scale(uhat*that/shat+mb2_);
// the PDF's with the emitted gluon
double fxnew[2];
xnew[0]=exp(yB)/sqrt(s)*sqrt(shat*(mb2_-uhat)/(mb2_-that));
xnew[1]=shat/(s*xnew[0]);
for(unsigned int ix=0;ix<2;++ix)
{fxnew[ix]=pdf[ix]->xfx(beams[ix],quarks[ix]->dataPtr(),scale,xnew[ix]);}
// jacobian and me parts of the weight
weight=jacobian2*(sqr(mb2_-that)+sqr(mb2_-uhat))/(sqr(shat)*that*uhat);
// pdf part of the weight
weight *=fxnew[0]*fxnew[1]*x[0]*x[1]/(fx[0]*fx[1]*xnew[0]*xnew[1]);
// finally coupling, colour factor and different channel pieces
weight *= 2./3./Constants::pi/_channelweights[0]*_alpha->value(scale);
// select the emiting particle
iemit=1;
if(UseRandom::rnd()<sqr(mb2_-uhat)/(sqr(mb2_-uhat)+sqr(mb2_-that))) iemit=2;
itype=0;
}
// incoming gluon
else {
// generate t
if(rn>_channelweights[1]) {
swap(tmax,tmin);
tmax=mb2_-shat-tmax;
tmin=mb2_-shat-tmin;
}
that=tmax*pow(tmin/tmax,UseRandom::rnd());
uhat=mb2_-shat-that;
Energy4 jacobian2 = jacobian * that*log(tmax/tmin);
// new scale (this is mt^2=pt^2+mb^2)
Energy2 scale(uhat*that/shat+mb2_);
// g qbar -> qbar V
double fxnew[2];
if(rn<_channelweights[1]) {
itype=2;
xnew[0]=exp(yB)/sqrt(s)*sqrt(shat*(mb2_-uhat)/(mb2_-that));
xnew[1]=shat/(s*xnew[0]);
fxnew[0]=pdf[0]->xfx(beams[0],getParticleData(ParticleID::g),scale,xnew[0]);
fxnew[1]=pdf[1]->xfx(beams[1],quarks[1]->dataPtr(),scale,xnew[1]);
jacobian2/=(_channelweights[1]-_channelweights[0]);
}
// q g -> q V
else {
itype=1;
xnew[0]=exp(yB)/sqrt(s)*sqrt(shat*(mb2_-that)/(mb2_-uhat));
xnew[1]=shat/(s*xnew[0]);
fxnew[0]=pdf[0]->xfx(beams[0],quarks[0]->dataPtr(),scale,xnew[0]);
fxnew[1]=pdf[1]->xfx(beams[1],getParticleData(ParticleID::g),scale,xnew[1]);
jacobian2/=(_channelweights[2]-_channelweights[1]);
}
// jacobian and me parts of the weight
weight=-jacobian2*(sqr(mb2_-that)+sqr(mb2_-shat))/(sqr(shat)*shat*that);
// pdf part of the weight
weight *=fxnew[0]*fxnew[1]*x[0]*x[1]/(fx[0]*fx[1]*xnew[0]*xnew[1]);
// finally coupling, colour factor and different channel pieces
weight *= 0.25/Constants::pi*_alpha->value(scale);
// select the emiting particle
iemit=1;
if(UseRandom::rnd()<sqr(mb2_-that)/(sqr(mb2_-that)+sqr(mb2_-shat))) iemit=2;
}
// if me correction should be applied
if(weight>1.) {
++_nover;
_maxwgt=max(_maxwgt,weight);
weight=1.;
}
if(UseRandom::rnd()>weight) return false;
// construct the momenta in the rest frame of the boson
Lorentz5Momentum pb(ZERO,ZERO,ZERO,mb,mb),pspect,pg,pemit;
double cos3 = 0.0;
if(itype==0)
{
pg = Lorentz5Momentum(ZERO,ZERO,ZERO,0.5*(shat-mb2_)/mb,ZERO);
Energy2 tp(that),up(uhat);
double zsign(-1.);
if(iemit==2)
{
tp=uhat;
up=that;
zsign=1.;
}
pspect = Lorentz5Momentum(ZERO,ZERO,zsign*0.5*(mb2_-tp)/mb,
0.5*(mb2_-tp)/mb,ZERO);
Energy eemit=0.5*(mb2_-up)/mb;
cos3 = 0.5/pspect.z()/pg.e()*(sqr(pspect.e())+sqr(pg.e())-sqr(eemit));
}
else
{
pg=Lorentz5Momentum(ZERO,ZERO,ZERO,0.5*(mb2_-uhat)/mb,ZERO);
double zsign(1.);
if(iemit==1)
{
if(itype==1) zsign=-1.;
pspect=Lorentz5Momentum(ZERO,ZERO,0.5*zsign*(shat-mb2_)/mb,
0.5*(shat-mb2_)/mb);
Energy eemit=0.5*(mb2_-that)/mb;
cos3 = 0.5/pspect.z()/pg.e()*(sqr(pspect.e())+sqr(pg.e())-sqr(eemit));
}
else
{
if(itype==2) zsign=-1.;
pspect=Lorentz5Momentum(ZERO,ZERO,0.5*zsign*(mb2_-that)/mb,
0.5*(mb2_-that)/mb);
Energy eemit=0.5*(shat-mb2_)/mb;
cos3 = 0.5/pspect.z()/pg.e()*(-sqr(pspect.e())-sqr(pg.e())+sqr(eemit));
}
}
// rotate the gluon
double sin3(sqrt(1.-sqr(cos3)));
double phi(Constants::twopi*UseRandom::rnd());
pg.setX(pg.e()*sin3*cos(phi));
pg.setY(pg.e()*sin3*sin(phi));
pg.setZ(pg.e()*cos3);
if(itype==0) {
pemit=pb+pg-pspect;
}
else {
if(iemit==1) pemit=pb+pspect-pg;
else pemit=pspect+pg-pb;
}
pemit.rescaleMass();
// find the new CMF
Lorentz5Momentum pp[2];
if(itype==0) {
if(iemit==1) {
pp[0]=pemit;
pp[1]=pspect;
}
else {
pp[0]=pspect;
pp[1]=pemit;
}
}
else if(itype==1) {
pp[1]=pg;
if(iemit==1) pp[0]=pemit;
else pp[0]=pspect;
}
else {
pp[0]=pg;
if(iemit==1) pp[1]=pemit;
else pp[1]=pspect;
}
Lorentz5Momentum pz= quarkplus ? pp[0] : pp[1];
pp[0]/=xnew[0];
pp[1]/=xnew[1];
Lorentz5Momentum plab(pp[0]+pp[1]);
plab.rescaleMass();
// construct the boost to rest frame of plab
trans=LorentzRotation(plab.findBoostToCM());
pz.transform(trans);
// rotate so emitting particle along z axis
// rotate so in x-z plane
trans.rotateZ(-atan2(pz.y(),pz.x()));
// rotate so along
trans.rotateY(-acos(pz.z()/pz.vect().mag()));
// undo azimuthal rotation
trans.rotateZ(atan2(pz.y(),pz.x()));
// perform the transforms
pb .transform(trans);
pspect.transform(trans);
pg .transform(trans);
pemit .transform(trans);
// momenta to be returned
pnew.push_back(pemit);
pnew.push_back(pspect);
pnew.push_back(pg);
pnew.push_back(pb);
xout.first=xnew[0];
xout.second=xnew[1];
return true;
}
bool DrellYanBase::softMatrixElementVeto(ShowerProgenitorPtr initial,
ShowerParticlePtr parent,Branching br) {
if(parent->isFinalState()) return false;
// check if me correction should be applied
long id[2]={initial->id(),parent->id()};
if(id[0]!=id[1]||id[1]==ParticleID::g) return false;
// get the pT
Energy pT=br.kinematics->pT();
// check if hardest so far
if(pT<initial->highestpT()) return false;
// compute the invariants
double kappa(sqr(br.kinematics->scale())/mb2_),z(br.kinematics->z());
Energy2 shat(mb2_/z*(1.+(1.-z)*kappa)),that(-(1.-z)*kappa*mb2_),uhat(-(1.-z)*shat);
// check which type of process
// g qbar
double wgt(1.);
if(id[0]>0&&br.ids[0]->id()==ParticleID::g)
wgt=mb2_/(shat+uhat)*(sqr(mb2_-that)+sqr(mb2_-shat))/(sqr(shat+uhat)+sqr(uhat));
else if(id[0]>0&&br.ids[0]->id()==id[0])
wgt=mb2_/(shat+uhat)*(sqr(mb2_-uhat)+sqr(mb2_-that))/(sqr(shat)+sqr(shat+uhat));
else if(id[0]<0&&br.ids[0]->id()==ParticleID::g)
wgt=mb2_/(shat+uhat)*(sqr(mb2_-that)+sqr(mb2_-shat))/(sqr(shat+uhat)+sqr(uhat));
else if(id[0]<0&&br.ids[0]->id()==-id[0])
wgt=mb2_/(shat+uhat)*(sqr(mb2_-uhat)+sqr(mb2_-that))/(sqr(shat)+sqr(shat+uhat));
else return false;
if(wgt<.0||wgt>1.) generator()->log() << "Soft ME correction weight too large or "
<< "negative in DrellYanBase::"
<< "softMatrixElementVeto()soft weight "
<< " sbar = " << shat/mb2_
<< " tbar = " << that/mb2_
<< "weight = " << wgt << "\n";
// if not vetoed
if(UseRandom::rndbool(wgt)) return false;
// otherwise
parent->vetoEmission(br.type,br.kinematics->scale());
return true;
}
// HardTreePtr DrellYanBase::generateHardest(ShowerTreePtr tree,ShowerInteraction::Type inter) {
// if(inter==ShowerInteraction::QED) return HardTreePtr();
// useMe();
// // get the particles to be showered
// _beams.clear();
// _partons.clear();
// // find the incoming particles
// ShowerParticleVector incoming;
// map<ShowerProgenitorPtr,ShowerParticlePtr>::const_iterator cit;
// _quarkplus = true;
// vector<ShowerProgenitorPtr> particlesToShower;
// //progenitor particles are produced in z direction.
// for( cit = tree->incomingLines().begin(); cit != tree->incomingLines().end(); ++cit ) {
// incoming.push_back( cit->first->progenitor() );
// _beams.push_back( cit->first->beam() );
// _partons.push_back( cit->first->progenitor()->dataPtr() );
// // check that quark is along +ve z direction
// if(cit->first->progenitor()->id() > 0 &&
// cit->first->progenitor()->momentum().z() < ZERO )
// _quarkplus = false;
// particlesToShower.push_back( cit->first );
// }
// Lorentz5Momentum pboson;
// for( map<ShowerProgenitorPtr,tShowerParticlePtr>::const_iterator
// cjt= tree->outgoingLines().begin();
// cjt != tree->outgoingLines().end();++cjt ) {
// pboson += cjt->first->original()->momentum();
// }
// pboson.rescaleMass();
// // calculate the rapidity of the boson
// _yb = 0.5 * log((pboson.e()+pboson.z())/(pboson.e()-pboson.z()));
// _yb *= _quarkplus ? 1. : -1.;
// _mass = pboson.mass();
// // we are assuming quark first, swap order to ensure this
// // if antiquark first
// if(_partons[0]->id()<_partons[1]->id()) {
// swap(_partons[0],_partons[1]);
// swap(_beams[0],_beams[1]);
// }
// vector<Lorentz5Momentum> pnew;
// int emission_type(-1);
// // generate the hard emission and return if no emission
// if(!getEvent(pnew,emission_type)) {
// for(unsigned int ix=0;ix<particlesToShower.size();++ix)
// particlesToShower[ix]->maximumpT(_min_pt,ShowerInteraction::QCD);
// return HardTreePtr();
// }
// // construct the HardTree object needed to perform the showers
// ShowerParticleVector newparticles;
// // make the particles for the HardTree
// tcPDPtr gluon=getParticleData(ParticleID::g);
// // create the partons
// int iemit;
// // q qbar -> g V
// ColinePtr newline[2]={new_ptr(ColourLine()),new_ptr(ColourLine())};
// if(emission_type==0) {
// newparticles.push_back(new_ptr(ShowerParticle(_partons[0] ,false)));
// newparticles.push_back(new_ptr(ShowerParticle(_partons[1] ,false)));
// newparticles.push_back(new_ptr(ShowerParticle(gluon , true)));
// newline[1]->addColoured(newparticles[0]);
// newline[1]->addColoured(newparticles[2]);
// newline[0]->addAntiColoured(newparticles[1]);
// newline[0]->addAntiColoured(newparticles[2]);
// iemit = (pnew[0]-pnew[2]).m2()>(pnew[1]-pnew[2]).m2() ? 0 : 1;
// }
// // q g -> q V
// else if(emission_type==1) {
// iemit=1;
// newparticles.push_back(new_ptr(ShowerParticle(_partons[0] ,false)));
// newparticles.push_back(new_ptr(ShowerParticle(gluon ,false)));
// newparticles.push_back(new_ptr(ShowerParticle(_partons[1]->CC(), true)));
// newline[1]->addColoured(newparticles[0]);
// newline[1]->addAntiColoured(newparticles[1]);
// newline[0]->addColoured(newparticles[1]);
// newline[0]->addColoured(newparticles[2]);
// }
// // g qbar -> qbar V
// else {
// iemit=0;
// newparticles.push_back(new_ptr(ShowerParticle(gluon ,false)));
// newparticles.push_back(new_ptr(ShowerParticle(_partons[1] ,false)));
// newparticles.push_back(new_ptr(ShowerParticle(_partons[0]->CC(), true)));
// newline[0]->addAntiColoured(newparticles[1]);
// newline[0]->addColoured(newparticles[0]);
// newline[1]->addAntiColoured(newparticles[0]);
// newline[1]->addAntiColoured(newparticles[2]);
// }
// // set the momenta
// for(unsigned int ix=0;ix<3;++ix) newparticles[ix]->set5Momentum(pnew[ix]);
// // create the off-shell particle
// Lorentz5Momentum poff=pnew[iemit]-pnew[2];
// poff.rescaleMass();
// newparticles.push_back(new_ptr(ShowerParticle(_partons[iemit],false)));
// newparticles.back()->set5Momentum(poff);
// if(iemit==0) {
// newline[0]->addColoured(newparticles.back());
// }
// else {
// newline[1]->addAntiColoured(newparticles.back());
// }
// // compute the boost for the bosons
// LorentzRotation boost(pboson.findBoostToCM());
// boost.boost(pnew[3].boostVector());
// for( map<ShowerProgenitorPtr,tShowerParticlePtr>::const_iterator
// cjt= tree->outgoingLines().begin();
// cjt != tree->outgoingLines().end();++cjt ) {
// newparticles.push_back(new_ptr(ShowerParticle(cjt->first->original()->dataPtr(),
// true)));
// newparticles.back()->set5Momentum(boost*cjt->first->original()->momentum());
// }
// vector<HardBranchingPtr> inBranch,hardBranch;
// // create the branchings for the incoming particles
// inBranch.push_back(new_ptr(HardBranching(newparticles[0],SudakovPtr(),
// HardBranchingPtr(),HardBranching::Incoming)));
// inBranch.push_back(new_ptr(HardBranching(newparticles[1],SudakovPtr(),
// HardBranchingPtr(),HardBranching::Incoming)));
// // intermediate IS particle
// hardBranch.push_back(new_ptr(HardBranching(newparticles[3],SudakovPtr(),
// inBranch[iemit],HardBranching::Incoming)));
// inBranch[iemit]->addChild(hardBranch.back());
// inBranch[iemit]->type(hardBranch.back()->branchingParticle()->id()>0 ?
// ShowerPartnerType::QCDColourLine : ShowerPartnerType::QCDAntiColourLine);
// // create the branching for the emitted jet
// inBranch[iemit]->addChild(new_ptr(HardBranching(newparticles[2],SudakovPtr(),
// inBranch[iemit],HardBranching::Outgoing)));
// // set the colour partners
// hardBranch.back()->colourPartner(inBranch[iemit==0 ? 1 : 0]);
// inBranch[iemit==0 ? 1 : 0]->colourPartner(hardBranch.back());
// // add other particle
// hardBranch.push_back(inBranch[iemit==0 ? 1 : 0]);
// // outgoing particles
// for(unsigned int ix=4;ix<newparticles.size();++ix) {
// hardBranch.push_back(new_ptr(HardBranching(newparticles[ix],SudakovPtr(),
// HardBranchingPtr(),HardBranching::Outgoing)));
// }
// // make the tree
// HardTreePtr hardtree=new_ptr(HardTree(hardBranch,inBranch,ShowerInteraction::QCD));
// // connect the ShowerParticles with the branchings
// // and set the maximum pt for the radiation
// set<HardBranchingPtr> hard=hardtree->branchings();
// for(unsigned int ix=0;ix<particlesToShower.size();++ix) {
// if( _pt < _min_pt ) particlesToShower[ix]->maximumpT(_min_pt,ShowerInteraction::QCD);
// else particlesToShower[ix]->maximumpT(_pt,ShowerInteraction::QCD);
// for(set<HardBranchingPtr>::const_iterator mit=hard.begin();
// mit!=hard.end();++mit) {
// if(particlesToShower[ix]->progenitor()->id()==(*mit)->branchingParticle()->id()&&
// (( particlesToShower[ix]->progenitor()->isFinalState()&&
// (**mit).status()==HardBranching::Outgoing)||
// (!particlesToShower[ix]->progenitor()->isFinalState()&&
// (**mit).status()==HardBranching::Incoming))) {
// hardtree->connect(particlesToShower[ix]->progenitor(),*mit);
// if((**mit).status()==HardBranching::Incoming) {
// (*mit)->beam(particlesToShower[ix]->original()->parents()[0]);
// }
// HardBranchingPtr parent=(*mit)->parent();
// while(parent) {
// parent->beam(particlesToShower[ix]->original()->parents()[0]);
// parent=parent->parent();
// };
// }
// }
// }
// // return the tree
// return hardtree;
// }
double DrellYanBase::getResult(int emis_type, Energy pt, double yj) {
Energy2 s=sqr(generator()->maximumCMEnergy());
Energy2 m2(sqr(_mass));
Energy2 scale = m2+sqr(pt);
Energy et=sqrt(scale);
// longitudinal real correction fractions
double x = pt*exp( yj)/sqrt(s)+et*exp( _yb)/sqrt(s);
double y = pt*exp(-yj)/sqrt(s)+et*exp(-_yb)/sqrt(s);
// reject if outside region
if(x<0.||x>1.||y<0.||y>1.||x*y<m2/s) return 0.;
// longitudinal born fractions
double x1 = _mass*exp( _yb)/sqrt(s);
double y1 = _mass*exp(-_yb)/sqrt(s);
// mandelstam variables
Energy2 th = -sqrt(s)*x*pt*exp(-yj);
Energy2 uh = -sqrt(s)*y*pt*exp( yj);
Energy2 sh = m2-th-uh;
double res;
// pdf part of the cross section
double pdf[4];
pdf[0]=_beams[0]->pdf()->xfx(_beams[0],_partons[0],m2,x1);
pdf[1]=_beams[1]->pdf()->xfx(_beams[1],_partons[1],m2,y1);
//qqbar2Zg
using Constants::pi;
if(emis_type==0) {
pdf[2]=_beams[0]->pdf()->xfx(_beams[0],_partons[0],scale,x);
pdf[3]=_beams[1]->pdf()->xfx(_beams[1],_partons[1],scale,y);
res = 4./3./pi*(sqr(th-m2)+sqr(uh-m2))*pt/(sh*uh*th)*GeV;
}
//qg2Zq
else if(emis_type==1) {
pdf[2]=_beams[0]->pdf()->xfx(_beams[0],_partons[0],scale,x);
pdf[3]=_beams[1]->pdf()->xfx(_beams[1],getParticleData(ParticleID::g),scale,y);
res = -1./2./pi*(sqr(uh-m2)+sqr(sh-m2))*pt/(sh*sh*uh)*GeV;
}
//qbarg2Zqbar
else {
pdf[2]=_beams[0]->pdf()->xfx(_beams[0],getParticleData(ParticleID::g),scale,x);
pdf[3]=_beams[1]->pdf()->xfx(_beams[1],_partons[1],scale,y);
res =- 1./2./pi*(sqr(th-m2)+sqr(sh-m2))*pt/(sh*sh*th)*GeV;
}
//deals with pdf zero issue at large x
if(pdf[0]<=0.||pdf[1]<=0.||pdf[2]<=0.||pdf[3]<=0.) {
res=0.;
}
else {
res*=pdf[2]*pdf[3]/pdf[0]/pdf[1]*m2/sh;
}
res*=_alpha->ratio(sqr(pt));
return res;
}
bool DrellYanBase::getEvent(vector<Lorentz5Momentum> & pnew,
int & emis_type){
// pt cut-off
// Energy minp = 0.1*GeV;
// maximum pt (half of centre-of-mass energy)
Energy maxp = 0.5*generator()->maximumCMEnergy();
// set pt of emission to zero
_pt=ZERO;
//Working Variables
Energy pt;
double yj;
// limits on the rapidity of the jet
double minyj = -8.0,maxyj = 8.0;
bool reject;
double wgt;
emis_type=-1;
for(int j=0;j<3;j++) {
pt=maxp;
double a = _alpha->overestimateValue()*_prefactor[j]*(maxyj-minyj)/(_power-1.);
do {
// generate next pt
pt=GeV/pow(pow(GeV/pt,_power-1)-log(UseRandom::rnd())/a,1./(_power-1.));
// generate rapidity of the jet
yj=UseRandom::rnd()*(maxyj-minyj)+ minyj;
// calculate rejection weight
wgt=getResult(j,pt,yj);
wgt/= _prefactor[j]*pow(GeV/pt,_power);
reject = UseRandom::rnd()>wgt;
//no emission event if p goes past p min - basically set to outside
//of the histogram bounds (hopefully hist object just ignores it)
if(pt<_min_pt){
pt=ZERO;
reject = false;
}
if(wgt>1.0) {
ostringstream s;
s << "DrellYanBase::getEvent weight for channel " << j
<< "is " << wgt << " which is greater than 1";
generator()->logWarning( Exception(s.str(), Exception::warning) );
}
}
while(reject);
// set pt of emission etc
if(pt>_pt){
emis_type = j;
_pt=pt;
_yj=yj;
}
}
//was this an (overall) no emission event?
if(_pt<_min_pt){
_pt=ZERO;
emis_type = 3;
}
if(emis_type==3) return false;
// generate the momenta of the particles
// hadron-hadron cmf
Energy2 s=sqr(generator()->maximumCMEnergy());
// transverse energy
Energy2 m2(sqr(_mass));
Energy et=sqrt(m2+sqr(_pt));
// first calculate all the kinematic variables
// longitudinal real correction fractions
double x = _pt*exp( _yj)/sqrt(s)+et*exp( _yb)/sqrt(s);
double y = _pt*exp(-_yj)/sqrt(s)+et*exp(-_yb)/sqrt(s);
// that and uhat
Energy2 th = -sqrt(s)*x*_pt*exp(-_yj);
Energy2 uh = -sqrt(s)*y*_pt*exp( _yj);
Energy2 sh = x*y*s;
if(emis_type==1) swap(th,uh);
// decide which was the emitting particle
unsigned int iemit=1;
// from q qbar
if(emis_type==0) {
if(UseRandom::rnd()<sqr(m2-uh)/(sqr(m2-uh)+sqr(m2-th))) iemit=2;
}
else {
if(UseRandom::rnd()<sqr(m2-th)/(sqr(m2-th)+sqr(m2-sh))) iemit=2;
}
// reconstruct the momenta in the rest frame of the gauge boson
Lorentz5Momentum pb(ZERO,ZERO,ZERO,_mass,_mass),pspect,pg,pemit;
double cos3;
if(emis_type==0) {
pg=Lorentz5Momentum(ZERO,ZERO,ZERO,0.5*(sh-m2)/_mass,ZERO);
Energy2 tp(th),up(uh);
double zsign(-1.);
if(iemit==2) {
swap(tp,up);
zsign=1;
}
pspect = Lorentz5Momentum(ZERO,ZERO
,zsign*0.5*(m2-tp)/_mass,0.5*(m2-tp)/_mass,
ZERO);
Energy eemit=0.5*(m2-up)/_mass;
cos3 = 0.5/pspect.z()/pg.e()*(sqr(pspect.e())+sqr(pg.e())-sqr(eemit));
}
else {
pg=Lorentz5Momentum(ZERO,ZERO,ZERO,0.5*(m2-uh)/_mass,ZERO);
double zsign(1.);
if(iemit==1) {
if(emis_type==1) zsign=-1.;
pspect=Lorentz5Momentum(ZERO,ZERO,0.5*zsign*(sh-m2)/_mass,0.5*(sh-m2)/_mass);
Energy eemit=0.5*(m2-th)/_mass;
cos3 = 0.5/pspect.z()/pg.e()*(sqr(pspect.e())+sqr(pg.e())-sqr(eemit));
}
else {
if(emis_type==2) zsign=-1.;
pspect=Lorentz5Momentum(ZERO,ZERO,0.5*zsign*(m2-th)/_mass,0.5*(m2-th)/_mass);
Energy eemit=0.5*(sh-m2)/_mass;
cos3 = 0.5/pspect.z()/pg.e()*(-sqr(pspect.e())-sqr(pg.e())+sqr(eemit));
}
}
// rotate the gluon
double sin3(sqrt(1.-sqr(cos3))),phi(Constants::twopi*UseRandom::rnd());
pg.setX(pg.e()*sin3*cos(phi));
pg.setY(pg.e()*sin3*sin(phi));
pg.setZ(pg.e()*cos3);
if(emis_type==0) {
pemit=pb+pg-pspect;
}
else {
if(iemit==1) pemit=pb+pspect-pg;
else pemit=pspect+pg-pb;
}
pemit .setMass(ZERO);
pg .setMass(ZERO);
pspect.setMass(ZERO);
// find the new CMF
Lorentz5Momentum pp[2];
if(emis_type==0) {
pp[0]=pemit;
pp[1]=pspect;
if(iemit==2) swap(pp[0],pp[1]);
}
else if(emis_type==1) {
pp[1]=pg;
if(iemit==1) pp[0]=pemit;
else pp[0]=pspect;
}
else {
pp[0]=pg;
if(iemit==1) pp[1]=pemit;
else pp[1]=pspect;
}
Lorentz5Momentum pz= _quarkplus ? pp[0] : pp[1];
pp[0]/=x;
pp[1]/=y;
Lorentz5Momentum plab(pp[0]+pp[1]);
plab.rescaleMass();
// construct the boost to rest frame of plab
LorentzRotation trans=LorentzRotation(plab.findBoostToCM());
pz.transform(trans);
// rotate so emitting particle along z axis
// rotate so in x-z plane
trans.rotateZ(-atan2(pz.y(),pz.x()));
// rotate so along
trans.rotateY(-acos(pz.z()/pz.vect().mag()));
// undo azimuthal rotation
trans.rotateZ(atan2(pz.y(),pz.x()));
// perform the transforms
pb .transform(trans);
pspect.transform(trans);
pg .transform(trans);
pemit .transform(trans);
// copy the momenta for the new particles
pnew.resize(4);
if(emis_type==0) {
pnew[0]=pemit;
pnew[1]=pspect;
if(iemit==2) swap(pnew[0],pnew[1]);
pnew[2]=pg;
}
else if(emis_type==1) {
pnew[0]=pemit;
pnew[2]=pspect;
if(iemit==2) swap(pnew[0],pnew[2]);
pnew[1]=pg;
}
else if(emis_type==2) {
pnew[1]=pspect;
pnew[2]=pemit;
if(iemit==1) swap(pnew[1],pnew[2]);
pnew[0]=pg;
}
pnew[3]=pb;
return true;
}
File Metadata
Details
Attached
Mime Type
text/x-diff
Expires
Tue, Nov 19, 8:51 PM (1 d, 2 h)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
3790356
Default Alt Text
(36 KB)
Attached To
R563 testingHerwigHG
Event Timeline
Log In to Comment