Page Menu
Home
HEPForge
Search
Configure Global Search
Log In
Files
F19244567
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Award Token
Flag For Later
Size
27 KB
Referenced Files
None
Subscribers
None
View Options
diff --git a/Hadronization/ClusterHadronizationHandler.cc b/Hadronization/ClusterHadronizationHandler.cc
--- a/Hadronization/ClusterHadronizationHandler.cc
+++ b/Hadronization/ClusterHadronizationHandler.cc
@@ -1,312 +1,318 @@
// -*- C++ -*-
//
// ClusterHadronizationHandler.cc is a part of Herwig++ - A multi-purpose Monte Carlo event generator
// Copyright (C) 2002-2011 The Herwig Collaboration
//
// Herwig++ is licenced under version 2 of the GPL, see COPYING for details.
// Please respect the MCnet academic guidelines, see GUIDELINES for details.
//
//
// This is the implementation of the non-inlined, non-templated member
// functions of the ClusterHadronizationHandler class.
//
#include "ClusterHadronizationHandler.h"
#include <ThePEG/Interface/ClassDocumentation.h>
#include <ThePEG/Persistency/PersistentOStream.h>
#include <ThePEG/Persistency/PersistentIStream.h>
#include <ThePEG/Interface/Parameter.h>
#include <ThePEG/Interface/Reference.h>
#include <ThePEG/Handlers/EventHandler.h>
#include <ThePEG/Handlers/Hint.h>
#include <ThePEG/PDT/ParticleData.h>
#include <ThePEG/EventRecord/Particle.h>
#include <ThePEG/EventRecord/Step.h>
#include <ThePEG/PDT/PDT.h>
#include <ThePEG/PDT/EnumParticles.h>
#include <ThePEG/Utilities/Throw.h>
#include "Herwig++/Utilities/EnumParticles.h"
#include "CluHadConfig.h"
#include "Cluster.h"
#include <ThePEG/Utilities/DescribeClass.h>
using namespace Herwig;
ClusterHadronizationHandler * ClusterHadronizationHandler::currentHandler_ = 0;
DescribeClass<ClusterHadronizationHandler,HadronizationHandler>
describeClusterHadronizationHandler("Herwig::ClusterHadronizationHandler","");
IBPtr ClusterHadronizationHandler::clone() const {
return new_ptr(*this);
}
IBPtr ClusterHadronizationHandler::fullclone() const {
return new_ptr(*this);
}
void ClusterHadronizationHandler::persistentOutput(PersistentOStream & os)
const {
os << _partonSplitter
<< _clusterFinder
<< _colourReconnector
<< _clusterFissioner
<< _lightClusterDecayer
<< _clusterDecayer
<< ounit(_minVirtuality2,GeV2)
<< ounit(_maxDisplacement,mm)
<< _underlyingEventHandler;
}
void ClusterHadronizationHandler::persistentInput(PersistentIStream & is, int) {
is >> _partonSplitter
>> _clusterFinder
>> _colourReconnector
>> _clusterFissioner
>> _lightClusterDecayer
>> _clusterDecayer
>> iunit(_minVirtuality2,GeV2)
>> iunit(_maxDisplacement,mm)
>> _underlyingEventHandler;
}
void ClusterHadronizationHandler::Init() {
static ClassDocumentation<ClusterHadronizationHandler> documentation
("This is the main handler class for the Cluster Hadronization",
"The hadronization was performed using the cluster model of \\cite{Webber:1983if}.",
"%\\cite{Webber:1983if}\n"
"\\bibitem{Webber:1983if}\n"
" B.~R.~Webber,\n"
" ``A QCD Model For Jet Fragmentation Including Soft Gluon Interference,''\n"
" Nucl.\\ Phys.\\ B {\\bf 238}, 492 (1984).\n"
" %%CITATION = NUPHA,B238,492;%%\n"
// main manual
);
static Reference<ClusterHadronizationHandler,PartonSplitter>
interfacePartonSplitter("PartonSplitter",
"A reference to the PartonSplitter object",
&Herwig::ClusterHadronizationHandler::_partonSplitter,
false, false, true, false);
static Reference<ClusterHadronizationHandler,ClusterFinder>
interfaceClusterFinder("ClusterFinder",
"A reference to the ClusterFinder object",
&Herwig::ClusterHadronizationHandler::_clusterFinder,
false, false, true, false);
static Reference<ClusterHadronizationHandler,ColourReconnector>
interfaceColourReconnector("ColourReconnector",
"A reference to the ColourReconnector object",
&Herwig::ClusterHadronizationHandler::_colourReconnector,
false, false, true, false);
static Reference<ClusterHadronizationHandler,ClusterFissioner>
interfaceClusterFissioner("ClusterFissioner",
"A reference to the ClusterFissioner object",
&Herwig::ClusterHadronizationHandler::_clusterFissioner,
false, false, true, false);
static Reference<ClusterHadronizationHandler,LightClusterDecayer>
interfaceLightClusterDecayer("LightClusterDecayer",
"A reference to the LightClusterDecayer object",
&Herwig::ClusterHadronizationHandler::_lightClusterDecayer,
false, false, true, false);
static Reference<ClusterHadronizationHandler,ClusterDecayer>
interfaceClusterDecayer("ClusterDecayer",
"A reference to the ClusterDecayer object",
&Herwig::ClusterHadronizationHandler::_clusterDecayer,
false, false, true, false);
static Parameter<ClusterHadronizationHandler,Energy2> interfaceMinVirtuality2
("MinVirtuality2",
"Minimum virtuality^2 of partons to use in calculating distances (unit [GeV2]).",
&ClusterHadronizationHandler::_minVirtuality2, GeV2, 0.1*GeV2, ZERO, 10.0*GeV2,false,false,false);
static Parameter<ClusterHadronizationHandler,Length> interfaceMaxDisplacement
("MaxDisplacement",
"Maximum displacement that is allowed for a particle (unit [millimeter]).",
&ClusterHadronizationHandler::_maxDisplacement, mm, 1.0e-10*mm,
0.0*mm, 1.0e-9*mm,false,false,false);
static Reference<ClusterHadronizationHandler,StepHandler> interfaceUnderlyingEventHandler
("UnderlyingEventHandler",
"Pointer to the handler for the Underlying Event. "
"Set to NULL to disable.",
&ClusterHadronizationHandler::_underlyingEventHandler, false, false, true, true, false);
}
namespace {
void extractChildren(tPPtr p, set<PPtr> & all) {
if (p->children().empty()) return;
for (PVector::const_iterator child = p->children().begin();
child != p->children().end(); ++child) {
all.insert(*child);
extractChildren(*child, all);
}
}
}
void ClusterHadronizationHandler::
handle(EventHandler & ch, const tPVector & tagged,
const Hint &) {
useMe();
currentHandler_ = this;
PVector currentlist(tagged.begin(),tagged.end());
// set the scale for coloured particles to just above the gluon mass squared
// if less than this so they are classed as perturbative
Energy2 Q02 = 1.01*sqr(getParticleData(ParticleID::g)->constituentMass());
for(unsigned int ix=0;ix<currentlist.size();++ix) {
if(currentlist[ix]->scale()<Q02) currentlist[ix]->scale(Q02);
}
// split the gluons
_partonSplitter->split(currentlist);
// form the clusters
ClusterVector clusters =
_clusterFinder->formClusters(currentlist);
_clusterFinder->reduceToTwoComponents(clusters);
// perform colour reconnection if needed and then
// decay the clusters into one hadron
bool lightOK = false;
short tried = 0;
const ClusterVector savedclusters = clusters;
tPVector finalHadrons; // only needed for partonic decayer
while (!lightOK && tried++ < 10) {
// no colour reconnection with baryon-number-violating (BV) clusters
ClusterVector CRclusters, BVclusters;
CRclusters.reserve( clusters.size() );
BVclusters.reserve( clusters.size() );
for (size_t ic = 0; ic < clusters.size(); ++ic) {
ClusterPtr cl = clusters.at(ic);
bool hasClusterParent = false;
for (unsigned int ix=0; ix < cl->parents().size(); ++ix) {
if (cl->parents()[ix]->id() == ParticleID::Cluster) {
hasClusterParent = true;
break;
}
}
if (cl->numComponents() > 2 || hasClusterParent) BVclusters.push_back(cl);
else CRclusters.push_back(cl);
}
// colour reconnection
_colourReconnector->rearrange(CRclusters);
// tag new clusters as children of the partons to hadronize
_setChildren(CRclusters);
// recombine vectors of (possibly) reconnected and BV clusters
clusters.clear();
clusters.insert( clusters.end(), CRclusters.begin(), CRclusters.end() );
clusters.insert( clusters.end(), BVclusters.begin(), BVclusters.end() );
// fission of heavy clusters
// NB: during cluster fission, light hadrons might be produced straight away
finalHadrons = _clusterFissioner->fission(clusters,isSoftUnderlyingEventON());
lightOK = _lightClusterDecayer->decay(clusters,finalHadrons);
// if the decay of the light clusters was not successful, undo the cluster
// fission and decay steps and revert to the original state of the event
// record
if (!lightOK) {
clusters = savedclusters;
for_each(clusters.begin(),
clusters.end(),
mem_fun(&Particle::undecay));
}
}
if (!lightOK) {
// currentHandler_ = 0;
throw Exception("CluHad::handle(): tried LightClusterDecayer 10 times!",
Exception::eventerror);
}
// decay the remaining clusters
_clusterDecayer->decay(clusters,finalHadrons);
// *****************************************
// *****************************************
// *****************************************
StepPtr pstep = newStep();
set<PPtr> allDecendants;
for (tPVector::const_iterator it = tagged.begin();
it != tagged.end(); ++it) {
extractChildren(*it, allDecendants);
}
for(set<PPtr>::const_iterator it = allDecendants.begin();
it != allDecendants.end(); ++it) {
// this is a workaround because the set sometimes
// re-orders parents after their children
if ((*it)->children().empty())
pstep->addDecayProduct(*it);
else {
pstep->addDecayProduct(*it);
pstep->addIntermediate(*it);
}
}
// *****************************************
// *****************************************
// *****************************************
// soft underlying event if needed
if (isSoftUnderlyingEventON()) {
assert(_underlyingEventHandler);
ch.performStep(_underlyingEventHandler,Hint::Default());
}
// zero all positions
// extract all particles from the event
tEventPtr event=ch.currentEvent();
vector<tPPtr> particles;
particles.reserve(256);
event->select(back_inserter(particles), ThePEG::AllSelector());
// and the final-state particles
set<tPPtr> finalstate;
event->selectFinalState(inserter(finalstate));
for(vector<tPPtr>::const_iterator pit=particles.begin();
pit!=particles.end();++pit) {
- // if a final-state particle just zero production
- if(finalstate.find(*pit)!=finalstate.end()) {
- (**pit).setVertex(LorentzPoint());
+ // fix the vertex position
+ tPPtr parent = (**pit).parents().empty() ? tPPtr() : (**pit).parents()[0];
+ bool inClusters(false);
+ bool newVertex(false);
+ while(parent&&!parent->parents().empty()) {
+ if(!inClusters&&parent->id()==ParticleID::Cluster) {
+ inClusters = true;
+ }
+ else if(inClusters&&parent->id()!=ParticleID::Cluster) {
+ newVertex = true;
+ break;
+ }
+ parent = parent->parents()[0];
}
- // if not zero the lot
- else {
- (**pit).setVertex(LorentzPoint());
- (**pit).setLifeLength(LorentzDistance());
- }
+ if(newVertex) (**pit).setVertex(parent->vertex());
}
// currentHandler_ = 0;
}
void ClusterHadronizationHandler::_setChildren(ClusterVector clusters) const {
// erase existing information about the partons' children
tPVector partons;
for (ClusterVector::const_iterator cl = clusters.begin();
cl != clusters.end(); cl++) {
partons.push_back( (*cl)->colParticle() );
partons.push_back( (*cl)->antiColParticle() );
}
for_each(partons.begin(), partons.end(), mem_fun(&Particle::undecay));
// give new parents to the clusters: their constituents
for (ClusterVector::iterator cl = clusters.begin();
cl != clusters.end(); cl++) {
(*cl)->colParticle()->addChild(*cl);
(*cl)->antiColParticle()->addChild(*cl);
}
}
diff --git a/MatrixElement/MEfftoVH.cc b/MatrixElement/MEfftoVH.cc
--- a/MatrixElement/MEfftoVH.cc
+++ b/MatrixElement/MEfftoVH.cc
@@ -1,422 +1,421 @@
// -*- C++ -*-
//
// This is the implementation of the non-inlined, non-templated member
// functions of the MEfftoVH class.
//
#include "MEfftoVH.h"
#include "ThePEG/Interface/ClassDocumentation.h"
#include "ThePEG/Interface/Parameter.h"
#include "ThePEG/Interface/Switch.h"
#include "ThePEG/Persistency/PersistentOStream.h"
#include "ThePEG/Persistency/PersistentIStream.h"
#include "ThePEG/PDT/EnumParticles.h"
#include "ThePEG/MatrixElement/Tree2toNDiagram.h"
#include "ThePEG/Utilities/SimplePhaseSpace.h"
#include "ThePEG/Handlers/StandardXComb.h"
#include "ThePEG/Cuts/Cuts.h"
#include "Herwig++/Models/StandardModel/StandardModel.h"
#include "Herwig++/MatrixElement/HardVertex.h"
#include "Herwig++/Utilities/Kinematics.h"
#include "ThePEG/PDF/PolarizedBeamParticleData.h"
using namespace Herwig;
void MEfftoVH::persistentOutput(PersistentOStream & os) const {
os << _shapeopt << _wplus << _wminus << _z0 << _higgs
<< _vertexFFW << _vertexFFZ << _vertexWWH << _maxflavour
<< ounit(_mh,GeV) << ounit(_wh,GeV) << _hmass;
}
void MEfftoVH::persistentInput(PersistentIStream & is, int) {
is >> _shapeopt >> _wplus >> _wminus >> _z0 >> _higgs
>> _vertexFFW >> _vertexFFZ >> _vertexWWH >> _maxflavour
>> iunit(_mh,GeV) >> iunit(_wh,GeV) >> _hmass;
}
AbstractClassDescription<MEfftoVH> MEfftoVH::initMEfftoVH;
// Definition of the static class description member.
void MEfftoVH::Init() {
static ClassDocumentation<MEfftoVH> documentation
("The MEfftoVH class is the base class for the Bjirken process f fbar -> V H");
static Switch<MEfftoVH,unsigned int> interfaceShapeOption
("ShapeScheme",
"Option for the treatment of the Higgs resonance shape",
&MEfftoVH::_shapeopt, 2, false, false);
static SwitchOption interfaceStandardShapeFixed
(interfaceShapeOption,
"FixedBreitWigner",
"Breit-Wigner s-channel resonanse",
1);
static SwitchOption interfaceStandardShapeRunning
(interfaceShapeOption,
"MassGenerator",
"Use the mass generator to give the shape",
2);
static SwitchOption interfaceStandardShapeOnShell
(interfaceShapeOption,
"OnShell",
"Produce an on-shell Higgs boson",
0);
static Parameter<MEfftoVH,unsigned int> interfaceMaxFlavour
( "MaxFlavour",
"The heaviest incoming quark flavour this matrix element is allowed to handle "
"(if applicable).",
&MEfftoVH::_maxflavour, 5, 1, 5, false, false, true);
}
unsigned int MEfftoVH::orderInAlphaS() const {
return 0;
}
unsigned int MEfftoVH::orderInAlphaEW() const {
return 3;
}
Energy2 MEfftoVH::scale() const {
return sHat();
}
int MEfftoVH::nDim() const {
return 4 + int(_shapeopt>0);
}
void MEfftoVH::setKinematics() {
DrellYanBase::setKinematics();
}
Selector<MEBase::DiagramIndex>
MEfftoVH::diagrams(const DiagramVector & diags) const {
Selector<DiagramIndex> sel;
for ( DiagramIndex i = 0; i < diags.size(); ++i )
sel.insert(1.0, i);
return sel;
}
Selector<const ColourLines *>
MEfftoVH::colourGeometries(tcDiagPtr ) const {
static ColourLines c1("");
static ColourLines c2("6 -7");
static ColourLines c3("1 -2");
static ColourLines c4("1 -2, 6 -7");
Selector<const ColourLines *> sel;
if(mePartonData()[0]->coloured()) {
if(mePartonData()[4]->coloured()) sel.insert(1.0, &c4);
else sel.insert(1.0, &c3);
}
else {
if(mePartonData()[4]->coloured()) sel.insert(1.0, &c2);
else sel.insert(1.0, &c1);
}
return sel;
}
void MEfftoVH::doinit() {
DrellYanBase::doinit();
// get the vedrtex pointers from the SM object
tcHwSMPtr hwsm= dynamic_ptr_cast<tcHwSMPtr>(standardModel());
// do the initialisation
if(hwsm) {
_vertexFFW = hwsm->vertexFFW();
_vertexFFZ = hwsm->vertexFFZ();
}
else throw InitException() << "Wrong type of StandardModel object in "
<< "MEfftoVH::doinit() the Herwig++"
<< " version must be used"
<< Exception::runerror;
// get the particle data objects for the intermediates
_wplus = getParticleData(ParticleID::Wplus );
_wminus = getParticleData(ParticleID::Wminus);
_z0 = getParticleData(ParticleID::Z0);
// higgs stuff
_mh = _higgs->mass();
_wh = _higgs->width();
if(_higgs->massGenerator()) {
_hmass=dynamic_ptr_cast<GenericMassGeneratorPtr>(_higgs->massGenerator());
}
if(_shapeopt==2&&!_hmass)
throw InitException()
<< "If using the mass generator for the line shape in MEfftoVH::doinit()"
<< "the mass generator must be an instance of the GenericMassGenerator class"
<< Exception::runerror;
}
double MEfftoVH::me2() const {
vector<SpinorWaveFunction> fin,aout;
vector<SpinorBarWaveFunction> ain,fout;
SpinorWaveFunction q(meMomenta()[0],mePartonData()[0],incoming);
SpinorBarWaveFunction qbar(meMomenta()[1],mePartonData()[1],incoming);
SpinorBarWaveFunction f(meMomenta()[3],mePartonData()[3],outgoing);
SpinorWaveFunction fbar(meMomenta()[4],mePartonData()[4],outgoing);
for(unsigned int ix=0;ix<2;++ix) {
q.reset(ix) ; fin.push_back(q);
qbar.reset(ix); ain.push_back(qbar);
f.reset(ix) ;fout.push_back(f);
fbar.reset(ix);aout.push_back(fbar);
}
return helicityME(fin,ain,fout,aout,false)*sHat()*UnitRemoval::InvE2;
}
double MEfftoVH::helicityME(vector<SpinorWaveFunction> & fin ,
vector<SpinorBarWaveFunction> & ain ,
vector<SpinorBarWaveFunction> & fout,
vector<SpinorWaveFunction> & aout,
bool calc) const {
// scale
Energy2 mb2(scale());
// matrix element to be stored
ProductionMatrixElement menew(PDT::Spin1Half,PDT::Spin1Half,PDT::Spin0,
PDT::Spin1Half,PDT::Spin1Half);
// work out the id of the vector boson
int incharge = mePartonData()[0]->iCharge()+mePartonData()[1]->iCharge();
tcPDPtr vec;
if(incharge==0) vec = _z0;
else if(incharge>0) vec = _wplus;
else vec = _wminus;
// vertex for vector boson
AbstractFFVVertexPtr vertex = vec==_z0 ? _vertexFFZ : _vertexFFW;
// wavefunction for the scalar
ScalarWaveFunction higgs(meMomenta()[2],mePartonData()[2],1.,outgoing);
// calculate the matrix element
VectorWaveFunction inter[2];
unsigned int ihel1,ihel2,ohel1,ohel2;
Complex diag;
double me(0.);
for(ihel1=0;ihel1<2;++ihel1) {
for(ihel2=0;ihel2<2;++ihel2) {
// wavefunction for the intermediate 1st vector
inter[0] = vertex->evaluate(mb2,1,vec,fin[ihel1],ain[ihel2]);
- // after the emission of the higgs
- inter[1] = _vertexWWH->evaluate(mb2,1,vec,inter[0],higgs);
// boson decay piece
for(ohel1=0;ohel1<2;++ohel1) {
for(ohel2=0;ohel2<2;++ohel2) {
- diag = vertex->evaluate(sqr(inter[1].particle()->mass()),
- aout[ohel2],fout[ohel1],inter[1]);
- me += norm(diag);
+ inter[1] = vertex->evaluate(sqr(vec->mass()),1,vec,
+ aout[ohel2],fout[ohel1]);
+ diag = _vertexWWH->evaluate(mb2,inter[1],inter[0],higgs);
+ me += norm(diag);
menew(ihel1,ihel2,0,ohel1,ohel2) = diag;
}
}
}
}
// spin factor
me *=0.25;
tcPolarizedBeamPDPtr beam[2] =
{dynamic_ptr_cast<tcPolarizedBeamPDPtr>(mePartonData()[0]),
dynamic_ptr_cast<tcPolarizedBeamPDPtr>(mePartonData()[1])};
if( beam[0] || beam[1] ) {
RhoDMatrix rho[2] =
{beam[0] ? beam[0]->rhoMatrix() : RhoDMatrix(mePartonData()[0]->iSpin()),
beam[1] ? beam[1]->rhoMatrix() : RhoDMatrix(mePartonData()[1]->iSpin())};
me = menew.average(rho[0],rho[1]);
}
// incoming colour factor
if(mePartonData()[0]->coloured()) me /= 3.;
// outgoing colour factor
if(mePartonData()[3]->coloured()) me *= 3.;
if(calc) _me.reset(menew);
return me;
}
void MEfftoVH::constructVertex(tSubProPtr sub) {
// extract the particles in the hard process
ParticleVector hard;
hard.push_back(sub->incoming().first);
hard.push_back(sub->incoming().second);
hard.push_back(sub->outgoing()[0]);
hard.push_back(sub->outgoing()[1]);
hard.push_back(sub->outgoing()[2]);
// ensure right order
if(hard[0]->id()<0) swap(hard[0],hard[1]);
if(hard[3]->dataPtr()->iSpin()==PDT::Spin0) swap(hard[2],hard[3]);
if(hard[4]->dataPtr()->iSpin()==PDT::Spin0) swap(hard[2],hard[4]);
if(hard[3]->id()<0) swap(hard[3],hard[4]);
vector<SpinorWaveFunction> fin,aout;
vector<SpinorBarWaveFunction> ain,fout;
SpinorWaveFunction( fin ,hard[0],incoming,false,true);
SpinorBarWaveFunction(ain ,hard[1],incoming,false,true);
ScalarWaveFunction( hard[2],outgoing,true);
SpinorBarWaveFunction(fout,hard[3],outgoing,true ,true);
SpinorWaveFunction( aout,hard[4],outgoing,true ,true);
helicityME(fin,ain,fout,aout,true);
// construct the vertex
HardVertexPtr hardvertex=new_ptr(HardVertex());
// set the matrix element for the vertex
hardvertex->ME(_me);
// set the pointers and to and from the vertex
for(unsigned int ix=0;ix<5;++ix) {
tcSpinPtr spin = hard[ix]->spinInfo();
if(ix<2) {
tcPolarizedBeamPDPtr beam =
dynamic_ptr_cast<tcPolarizedBeamPDPtr>(hard[ix]->dataPtr());
if(beam) spin->rhoMatrix() = beam->rhoMatrix();
}
spin->productionVertex(hardvertex);
}
}
bool MEfftoVH::generateKinematics(const double * r) {
using Constants::pi;
// workout the ID of the vector boson
tcPDPtr vec = mePartonData()[0]->iCharge()+mePartonData()[1]->iCharge()!=0
? _wplus : _z0;
// order determined randomly
Energy e = sqrt(sHat())/2.0;
Energy mh(_mh),mv;
double jac(1.);
if(UseRandom::rndbool()) {
double rhomax,rhomin;
// generate the mass of the Higgs
if(_shapeopt!=0) {
Energy mhmax = min(2.*e-vec->massMin(),mePartonData()[2]->massMax());
Energy mhmin = max(ZERO ,mePartonData()[2]->massMin());
if(mhmax<=mhmin) return false;
rhomin = atan2((sqr(mhmin)-sqr(_mh)), _mh*_wh);
rhomax = atan2((sqr(mhmax)-sqr(_mh)), _mh*_wh);
mh = sqrt(_mh*_wh*tan(rhomin+r[3]*(rhomax-rhomin))+sqr(_mh));
jac *= rhomax-rhomin;
}
// generate the mass of the vector boson
Energy2 mvmax2 = sqr(min(2.*e-mh,vec->massMax()));
Energy2 mvmin2 = sqr(vec->massMin());
if(mvmax2<=mvmin2) return false;
rhomin = atan2((mvmin2-sqr(vec->mass())), vec->mass()*vec->width());
rhomax = atan2((mvmax2-sqr(vec->mass())), vec->mass()*vec->width());
mv = sqrt(vec->mass()*vec->width()*tan(rhomin+r[1]*(rhomax-rhomin))
+sqr(vec->mass()));
jac *= rhomax-rhomin;
}
else {
// generate the mass of the vector boson
Energy2 mvmax2 = sqr(min(2.*e,vec->massMax()));
Energy2 mvmin2 = sqr(vec->massMin());
if(mvmax2<=mvmin2) return false;
double rhomin = atan2((mvmin2-sqr(vec->mass())), vec->mass()*vec->width());
double rhomax = atan2((mvmax2-sqr(vec->mass())), vec->mass()*vec->width());
mv = sqrt(vec->mass()*vec->width()*tan(rhomin+r[1]*(rhomax-rhomin))
+sqr(vec->mass()));
jac *= rhomax-rhomin;
// generate the mass of the Higgs
if(_shapeopt!=0) {
Energy mhmax = min(2.*e-mv,mePartonData()[2]->massMax());
Energy mhmin = max(ZERO ,mePartonData()[2]->massMin());
if(mhmax<=mhmin) return false;
rhomin = atan2((sqr(mhmin)-sqr(_mh)), _mh*_wh);
rhomax = atan2((sqr(mhmax)-sqr(_mh)), _mh*_wh);
mh = sqrt(_mh*_wh*tan(rhomin+r[3]*(rhomax-rhomin))+sqr(_mh));
jac *= rhomax-rhomin;
}
}
if(mh+mv>2.*e) return false;
// assign masses
meMomenta()[2].setMass(mh);
for(unsigned int ix=3;ix<5;++ix)
meMomenta()[ix] = Lorentz5Momentum(mePartonData()[ix]->generateMass());
Energy q = ZERO;
Lorentz5Momentum pvec(mv);
try {
q = SimplePhaseSpace::
getMagnitude(sHat(), meMomenta()[2].mass(), mv);
}
catch ( ImpossibleKinematics ) {
return false;
}
Energy ptmin = max(lastCuts().minKT(mePartonData()[2]),
lastCuts().minKT(vec));
Energy2 m22 = meMomenta()[2].mass2();
Energy2 m32 = pvec .mass2();
Energy2 e0e2 = 2.0*e*sqrt(sqr(q) + m22);
Energy2 e1e2 = 2.0*e*sqrt(sqr(q) + m22);
Energy2 e0e3 = 2.0*e*sqrt(sqr(q) + m32);
Energy2 e1e3 = 2.0*e*sqrt(sqr(q) + m32);
Energy2 pq = 2.0*e*q;
double ctmin = -1.0,ctmax = 1.0;
Energy2 thmin = lastCuts().minTij(mePartonData()[0], mePartonData()[2]);
if ( thmin > ZERO ) ctmax = min(ctmax, (e0e2 - m22 - thmin)/pq);
thmin = lastCuts().minTij(mePartonData()[1], mePartonData()[2]);
if ( thmin > ZERO ) ctmin = max(ctmin, (thmin + m22 - e1e2)/pq);
thmin = lastCuts().minTij(mePartonData()[1], mePartonData()[3]);
if ( thmin > ZERO ) ctmax = min(ctmax, (e1e3 - m32 - thmin)/pq);
thmin = lastCuts().minTij(mePartonData()[0], mePartonData()[3]);
if ( thmin > ZERO ) ctmin = max(ctmin, (thmin + m32 - e0e3)/pq);
if ( ptmin > ZERO ) {
double ctm = 1.0 - sqr(ptmin/q);
if ( ctm <= 0.0 ) return false;
ctmin = max(ctmin, -sqrt(ctm));
ctmax = min(ctmax, sqrt(ctm));
}
if ( ctmin >= ctmax ) return false;
jacobian(1.);
double cth = getCosTheta(ctmin, ctmax, r[0]);
Energy pt = q*sqrt(1.0-sqr(cth));
double phi = UseRandom::rnd()*2.0*pi;
meMomenta()[2].setX(pt*sin(phi));
meMomenta()[2].setY(pt*cos(phi));
meMomenta()[2].setZ(q*cth);
pvec .setX(-pt*sin(phi));
pvec .setY(-pt*cos(phi));
pvec .setZ(-q*cth);
meMomenta()[2].rescaleEnergy();
pvec .rescaleEnergy();
// decay of the vector boson
bool test=Kinematics::twoBodyDecay(pvec,meMomenta()[3].mass(),
meMomenta()[4].mass(),
-1.+2*r[2],r[3]*2.*pi,
meMomenta()[3],meMomenta()[4]);
if(!test) return false;
// check cuts
vector<LorentzMomentum> out;
tcPDVector tout;
for(unsigned int ix=2;ix<5;++ix) {
out .push_back(meMomenta()[ix]);
tout.push_back(mePartonData()[ix]);
}
if ( !lastCuts().passCuts(tout, out, mePartonData()[0], mePartonData()[1]) )
return false;
// jacobian factors
// main piece
jacobian((pq/sHat())*pi*jacobian());
// mass piece
jacobian(jac*jacobian());
// decay piece
Energy p2 = Kinematics::pstarTwoBodyDecay(mv,meMomenta()[3].mass(),
meMomenta()[4].mass());
jacobian(p2/mv/8./sqr(pi)*jacobian());
// jacobian factor for the gauge boson
jacobian((sqr(sqr(mv)-sqr(vec->mass()))+sqr(vec->mass()*vec->width()))/
(vec->mass()*vec->width())*jacobian()/sHat());
return true;
}
CrossSection MEfftoVH::dSigHatDR() const {
using Constants::pi;
// jacobian factor for the higgs
InvEnergy2 bwfact(ZERO);
Energy moff =meMomenta()[2].mass();
if(_shapeopt==1) {
tcPDPtr h0 = mePartonData()[2]->iSpin()==PDT::Spin0 ?
mePartonData()[2] : mePartonData()[3];
bwfact = h0->generateWidth(moff)*moff/pi/
(sqr(sqr(moff)-sqr(_mh))+sqr(_mh*_wh));
}
else if(_shapeopt==2) {
bwfact = _hmass->BreitWignerWeight(moff);
}
double jac1 = _shapeopt!=0 ?
double(bwfact*(sqr(sqr(moff)-sqr(_mh))+sqr(_mh*_wh))/(_mh*_wh)) : 1.;
// answer
return jac1*me2()*jacobian()/(16.0*sqr(pi)*sHat())*sqr(hbarc);
}
File Metadata
Details
Attached
Mime Type
text/x-diff
Expires
Tue, Sep 30, 4:43 AM (1 d, 17 h)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
6564790
Default Alt Text
(27 KB)
Attached To
Mode
rHERWIGHG herwighg
Attached
Detach File
Event Timeline
Log In to Comment