Page MenuHomeHEPForge

No OneTemporary

diff --git a/DipoleShower/Base/DipoleChainOrdering.cc b/DipoleShower/Base/DipoleChainOrdering.cc
--- a/DipoleShower/Base/DipoleChainOrdering.cc
+++ b/DipoleShower/Base/DipoleChainOrdering.cc
@@ -1,146 +1,146 @@
// -*- C++ -*-
//
// DipoleChainOrdering.cc is a part of Herwig++ - A multi-purpose Monte Carlo event generator
// Copyright (C) 2002-2007 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 DipoleChainOrdering class.
//
#include "DipoleChainOrdering.h"
#include "ThePEG/Interface/ClassDocumentation.h"
#include "ThePEG/Interface/Switch.h"
#include "ThePEG/Persistency/PersistentOStream.h"
#include "ThePEG/Persistency/PersistentIStream.h"
using namespace Herwig;
DipoleChainOrdering::DipoleChainOrdering()
: DipoleEvolutionOrdering(), virtualityOrdering(false) {}
DipoleChainOrdering::~DipoleChainOrdering() {}
IBPtr DipoleChainOrdering::clone() const {
return new_ptr(*this);
}
IBPtr DipoleChainOrdering::fullclone() const {
return new_ptr(*this);
}
Energy DipoleChainOrdering::hardScale(tPPtr emitter, tPPtr spectator,
double emitterX, double spectatorX,
const DipoleSplittingKernel& split,
const DipoleIndex& index) const {
Energy scale =
split.splittingKinematics()->dipoleScale(emitter->momentum(),
spectator->momentum());
return
virtualityOrdering ?
- split.splittingKinematics()->QMax(scale,emitterX,spectatorX,index) :
+ split.splittingKinematics()->QMax(scale,emitterX,spectatorX,index,split) :
split.splittingKinematics()->ptMax(scale,emitterX,spectatorX,index,split);
}
void DipoleChainOrdering::setEvolutionScale(Energy scale,
const DipoleSplittingInfo&,
DipoleChain& chain,
pair<list<Dipole>::iterator,list<Dipole>::iterator>) const {
for ( list<Dipole>::iterator dip = chain.dipoles().begin();
dip != chain.dipoles().end(); ++dip ) {
if ( dip->emitterScale(make_pair(true,false)) > scale )
dip->emitterScale(make_pair(true,false),scale);
if ( dip->emitterScale(make_pair(false,true)) > scale )
dip->emitterScale(make_pair(false,true),scale);
}
}
void DipoleChainOrdering::setEvolutionScale(Energy scale,
const DipoleSplittingInfo&,
DipoleChain& chain,
list<Dipole>::iterator) const {
for ( list<Dipole>::iterator dip = chain.dipoles().begin();
dip != chain.dipoles().end(); ++dip ) {
if ( dip->emitterScale(make_pair(true,false)) > scale )
dip->emitterScale(make_pair(true,false),scale);
if ( dip->emitterScale(make_pair(false,true)) > scale )
dip->emitterScale(make_pair(false,true),scale);
}
}
Energy DipoleChainOrdering::evolutionScale(const DipoleSplittingInfo& split,
const DipoleSplittingKernel& spkernel) const {
return
virtualityOrdering ?
spkernel.splittingKinematics()->QFromPt(split.lastPt(),split) :
split.lastPt();
}
Energy DipoleChainOrdering::maxPt(Energy scale,
const DipoleSplittingInfo& split,
const DipoleSplittingKernel& spkernel) const {
return
virtualityOrdering ?
spkernel.splittingKinematics()->ptMax(scale,split.emitterX(),split.spectatorX(),split.index(),spkernel) :
scale;
}
// If needed, insert default implementations of virtual function defined
// in the InterfacedBase class here (using ThePEG-interfaced-impl in Emacs).
void DipoleChainOrdering::persistentOutput(PersistentOStream & os) const {
os << virtualityOrdering;
}
void DipoleChainOrdering::persistentInput(PersistentIStream & is, int) {
is >> virtualityOrdering;
}
ClassDescription<DipoleChainOrdering> DipoleChainOrdering::initDipoleChainOrdering;
// Definition of the static class description member.
void DipoleChainOrdering::Init() {
static ClassDocumentation<DipoleChainOrdering> documentation
("DipoleChainOrdering performs ordering on "
"complete colour singlet dipole chains.");
static Switch<DipoleChainOrdering,bool> interfaceVirtualityOrdering
("Ordering",
"[experimental] Switch between virtuality and pt ordering.",
&DipoleChainOrdering::virtualityOrdering, false, false, false);
static SwitchOption interfaceVirtualityOrderingPt
(interfaceVirtualityOrdering,
"Pt",
"Perform pt ordering",
false);
static SwitchOption interfaceVirtualityOrderingVirtuality
(interfaceVirtualityOrdering,
"Virtuality",
"Perform virtuality ordering",
true);
interfaceVirtualityOrdering.rank(-1);
}
diff --git a/DipoleShower/Base/DipoleSplittingGenerator.cc b/DipoleShower/Base/DipoleSplittingGenerator.cc
--- a/DipoleShower/Base/DipoleSplittingGenerator.cc
+++ b/DipoleShower/Base/DipoleSplittingGenerator.cc
@@ -1,553 +1,548 @@
// -*- C++ -*-
//
// DipoleSplittingGenerator.cc is a part of Herwig++ - A multi-purpose Monte Carlo event generator
// Copyright (C) 2002-2007 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 DipoleSplittingGenerator class.
//
#include "DipoleSplittingGenerator.h"
#include "ThePEG/Interface/ClassDocumentation.h"
#include "ThePEG/Interface/Reference.h"
#include "ThePEG/Repository/EventGenerator.h"
#include "ThePEG/Persistency/PersistentOStream.h"
#include "ThePEG/Persistency/PersistentIStream.h"
#include "Herwig++/DipoleShower/DipoleShowerHandler.h"
using namespace Herwig;
DipoleSplittingGenerator::DipoleSplittingGenerator()
: HandlerBase(),
theExponentialGenerator(0), prepared(false), presampling(false) {
if ( ShowerHandler::currentHandler() )
setGenerator(ShowerHandler::currentHandler()->generator());
}
DipoleSplittingGenerator::~DipoleSplittingGenerator() {
if ( theExponentialGenerator ) {
delete theExponentialGenerator;
theExponentialGenerator = 0;
}
}
IBPtr DipoleSplittingGenerator::clone() const {
return new_ptr(*this);
}
IBPtr DipoleSplittingGenerator::fullclone() const {
return new_ptr(*this);
}
void DipoleSplittingGenerator::wrap(Ptr<DipoleSplittingGenerator>::ptr other) {
assert(!prepared);
theOtherGenerator = other;
}
void DipoleSplittingGenerator::prepare(const DipoleSplittingInfo& sp) {
generatedSplitting = sp;
generatedSplitting.splittingKinematics(splittingKernel()->splittingKinematics());
generatedSplitting.splittingParameters().resize(splittingKernel()->nDimAdditional());
if ( wrapping() ) {
generatedSplitting.emitterData(theSplittingKernel->emitter(generatedSplitting.index()));
generatedSplitting.spectatorData(theSplittingKernel->spectator(generatedSplitting.index()));
generatedSplitting.emissionData(theSplittingKernel->emission(generatedSplitting.index()));
parameters.resize(theOtherGenerator->nDim());
prepared = true;
return;
}
generatedSplitting.emitterData(splittingKernel()->emitter(generatedSplitting.index()));
generatedSplitting.spectatorData(splittingKernel()->spectator(generatedSplitting.index()));
generatedSplitting.emissionData(splittingKernel()->emission(generatedSplitting.index()));
presampledSplitting = generatedSplitting;
prepared = true;
parameters.resize(nDim());
theExponentialGenerator =
new exsample::exponential_generator<DipoleSplittingGenerator,UseRandom>();
theExponentialGenerator->sampling_parameters().maxtry = maxtry();
theExponentialGenerator->sampling_parameters().presampling_points = presamplingPoints();
theExponentialGenerator->function(this);
theExponentialGenerator->initialize();
}
void DipoleSplittingGenerator::fixParameters(const DipoleSplittingInfo& sp) {
assert(generator());
assert(!presampling);
assert(prepared);
assert(sp.index() == generatedSplitting.index());
generatedSplitting.scale(sp.scale());
parameters[3] = sp.scale()/generator()->maximumCMEnergy();
- Energy maxPossible =
- generatedSplitting.splittingKinematics()->ptMax(sp.scale(),
+ generatedSplitting.hardPt(sp.hardPt());
+
+ parameters[0] = splittingKinematics()->ptToRandom(generatedSplitting.hardPt(),
+ sp.scale(),
sp.emitterX(), sp.spectatorX(),
generatedSplitting.index(),
*splittingKernel());
- if ( maxPossible >= sp.hardPt() )
- generatedSplitting.hardPt(sp.hardPt());
- else
- generatedSplitting.hardPt(maxPossible);
-
- parameters[0] = splittingKinematics()->ptToRandom(generatedSplitting.hardPt(),
- sp.scale(),generatedSplitting.index());
-
size_t shift = 4;
if ( generatedSplitting.index().emitterPDF().pdf() &&
generatedSplitting.index().spectatorPDF().pdf() ) {
generatedSplitting.emitterX(sp.emitterX());
generatedSplitting.spectatorX(sp.spectatorX());
parameters[4] = sp.emitterX();
parameters[5] = sp.spectatorX();
shift += 2;
}
if ( generatedSplitting.index().emitterPDF().pdf() &&
!generatedSplitting.index().spectatorPDF().pdf() ) {
generatedSplitting.emitterX(sp.emitterX());
parameters[4] = sp.emitterX();
++shift;
}
if ( !generatedSplitting.index().emitterPDF().pdf() &&
generatedSplitting.index().spectatorPDF().pdf() ) {
generatedSplitting.spectatorX(sp.spectatorX());
parameters[4] = sp.spectatorX();
++shift;
}
if ( splittingReweight() ) {
parameters[shift] = splittingReweight()->evaluate(sp);
++shift;
}
if ( splittingKernel()->nDimAdditional() )
copy(sp.lastSplittingParameters().begin(),sp.lastSplittingParameters().end(),parameters.begin()+shift);
if ( sp.emitter() )
generatedSplitting.emitter(sp.emitter());
if ( sp.spectator() )
generatedSplitting.spectator(sp.spectator());
}
int DipoleSplittingGenerator::nDim() const {
assert(!wrapping());
assert(prepared);
int ret = 4; // 0 pt, 1 z, 2 phi, 3 scale, 4/5 xs + parameters
if ( generatedSplitting.index().emitterPDF().pdf() ) {
++ret;
}
if ( generatedSplitting.index().spectatorPDF().pdf() ) {
++ret;
}
if ( splittingReweight() )
++ret;
ret += splittingKernel()->nDimAdditional();
return ret;
}
const vector<bool>& DipoleSplittingGenerator::sampleFlags() {
assert(!wrapping());
if ( !theFlags.empty() )
return theFlags;
theFlags.resize(nDim(),false);
theFlags[0] = true; theFlags[1] = true; theFlags[2] = true; // 0 pt, 1 z, 2 phi
return theFlags;
}
const pair<vector<double>,vector<double> >& DipoleSplittingGenerator::support() {
assert(!wrapping());
if ( !theSupport.first.empty() )
return theSupport;
vector<double> lower(nDim(),0.);
vector<double> upper(nDim(),1.);
pair<double,double> kSupport =
generatedSplitting.splittingKinematics()->kappaSupport(generatedSplitting);
pair<double,double> xSupport =
generatedSplitting.splittingKinematics()->xiSupport(generatedSplitting);
lower[0] = kSupport.first;
lower[1] = xSupport.first;
upper[0] = kSupport.second;
upper[1] = xSupport.second;
if ( splittingReweight() ) {
pair<double,double> bounds = splittingReweight()->reweightBounds(generatedSplitting.index());
int pos = 4;
if ( generatedSplitting.index().emitterPDF().pdf() ) {
++pos;
}
if ( generatedSplitting.index().spectatorPDF().pdf() ) {
++pos;
}
lower[pos] = bounds.first;
upper[pos] = bounds.second;
}
theSupport.first = lower;
theSupport.second = upper;
return theSupport;
}
void DipoleSplittingGenerator::startPresampling() {
assert(!wrapping());
splittingKernel()->startPresampling(generatedSplitting.index());
presampling = true;
}
void DipoleSplittingGenerator::stopPresampling() {
assert(!wrapping());
splittingKernel()->stopPresampling(generatedSplitting.index());
presampling = false;
}
bool DipoleSplittingGenerator::haveOverestimate() const {
assert(!wrapping());
assert(prepared);
return
generatedSplitting.splittingKinematics()->haveOverestimate() &&
splittingKernel()->haveOverestimate(generatedSplitting);
}
bool DipoleSplittingGenerator::overestimate(const vector<double>& point) {
assert(!wrapping());
assert(prepared);
assert(!presampling);
assert(haveOverestimate());
if ( ! generatedSplitting.splittingKinematics()->generateSplitting(point[0],point[1],point[2],
- generatedSplitting) )
+ generatedSplitting,
+ *splittingKernel()) )
return 0.;
generatedSplitting.splittingKinematics()->prepareSplitting(generatedSplitting);
return
( generatedSplitting.splittingKinematics()->jacobianOverestimate() *
splittingKernel()->overestimate(generatedSplitting) *
(splittingReweight() ? splittingReweight()->evaluate(generatedSplitting) : 1.) );
}
double DipoleSplittingGenerator::invertOverestimateIntegral(double value) const {
assert(!wrapping());
assert(prepared);
assert(!presampling);
assert(haveOverestimate());
return
splittingKernel()->invertOverestimateIntegral(generatedSplitting,value);
}
double DipoleSplittingGenerator::evaluate(const vector<double>& point) {
assert(!wrapping());
assert(prepared);
assert(generator());
DipoleSplittingInfo& split =
( !presampling ? generatedSplitting : presampledSplitting );
split.continuesEvolving();
size_t shift = 4;
if ( presampling ) {
split.scale(point[3] * generator()->maximumCMEnergy());
if ( split.index().emitterPDF().pdf() &&
split.index().spectatorPDF().pdf() ) {
split.emitterX(point[4]);
split.spectatorX(point[5]);
shift += 2;
}
if ( split.index().emitterPDF().pdf() &&
!split.index().spectatorPDF().pdf() ) {
split.emitterX(point[4]);
++shift;
}
if ( !split.index().emitterPDF().pdf() &&
split.index().spectatorPDF().pdf() ) {
split.spectatorX(point[4]);
++shift;
}
if ( splittingReweight() )
++shift;
if ( splittingKernel()->nDimAdditional() )
copy(point.begin()+shift,point.end(),split.splittingParameters().begin());
split.hardPt(split.splittingKinematics()->ptMax(split.scale(),
split.emitterX(),
split.spectatorX(),
split.index(),
*splittingKernel()));
}
- if ( ! split.splittingKinematics()->generateSplitting(point[0],point[1],point[2],split) ) {
+ if ( ! split.splittingKinematics()->generateSplitting(point[0],point[1],point[2],split,*splittingKernel()) ) {
split.lastValue(0.);
return 0.;
}
split.splittingKinematics()->prepareSplitting(split);
if ( split.stoppedEvolving() ) {
split.lastValue(0.);
return 0.;
}
double kernel = splittingKernel()->evaluate(split);
if ( splittingReweight() ) {
if ( !presampling )
kernel *= splittingReweight()->evaluate(split);
else
kernel *= point[shift-1];
}
double jac = split.splittingKinematics()->jacobian();
split.lastValue( abs(jac) * kernel );
if ( kernel < 0. )
return 0.;
return split.lastValue();
}
void DipoleSplittingGenerator::doGenerate() {
assert(!wrapping());
double res = 0.;
Energy startPt = generatedSplitting.hardPt();
while (true) {
try {
res = theExponentialGenerator->generate();
} catch (exsample::exponential_regenerate&) {
generatedSplitting.hardPt(startPt);
continue;
} catch (exsample::hit_and_miss_maxtry&) {
throw DipoleShowerHandler::RedoShower();
} catch (exsample::selection_maxtry&) {
throw DipoleShowerHandler::RedoShower();
}
break;
}
if ( res == 0. ) {
generatedSplitting.lastPt(0.0*GeV);
generatedSplitting.didStopEvolving();
} else {
generatedSplitting.continuesEvolving();
if ( theMCCheck )
theMCCheck->book(generatedSplitting.emitterX(),
generatedSplitting.spectatorX(),
generatedSplitting.scale(),
startPt,
generatedSplitting.lastPt(),
generatedSplitting.lastZ(),
1.);
}
}
Energy DipoleSplittingGenerator::generate(const DipoleSplittingInfo& split) {
fixParameters(split);
if ( wrapping() ) {
return theOtherGenerator->generateWrapped(generatedSplitting);
}
doGenerate();
return generatedSplitting.lastPt();
}
Energy DipoleSplittingGenerator::generateWrapped(DipoleSplittingInfo& split) {
assert(!wrapping());
DipoleSplittingInfo backup = generatedSplitting;
generatedSplitting = split;
fixParameters(split);
try {
doGenerate();
} catch (...) {
split = generatedSplitting;
generatedSplitting = backup;
throw;
}
Energy pt = generatedSplitting.lastPt();
split = generatedSplitting;
generatedSplitting = backup;
return pt;
}
void DipoleSplittingGenerator::completeSplitting(DipoleSplittingInfo& sp) const {
pair<bool,bool> conf = sp.configuration();
sp = generatedSplitting;
sp.configuration(conf);
}
Ptr<DipoleSplittingKernel>::tptr DipoleSplittingGenerator::splittingKernel() const {
if ( wrapping() )
return theOtherGenerator->splittingKernel();
return theSplittingKernel;
}
Ptr<DipoleSplittingReweight>::tptr DipoleSplittingGenerator::splittingReweight() const {
if ( wrapping() )
return theOtherGenerator->splittingReweight();
return theSplittingReweight;
}
Ptr<DipoleSplittingKinematics>::tptr DipoleSplittingGenerator::splittingKinematics() const {
if ( wrapping() )
return theOtherGenerator->splittingKinematics();
return theSplittingKernel->splittingKinematics();
}
void DipoleSplittingGenerator::splittingKernel(Ptr<DipoleSplittingKernel>::tptr sp) {
theSplittingKernel = sp;
if ( theSplittingKernel->mcCheck() )
theMCCheck = theSplittingKernel->mcCheck();
}
void DipoleSplittingGenerator::splittingReweight(Ptr<DipoleSplittingReweight>::tptr sp) {
theSplittingReweight = sp;
}
void DipoleSplittingGenerator::debugGenerator(ostream& os) const {
os << "--- DipoleSplittingGenerator ---------------------------------------------------\n";
os << " generating splittings using\n"
<< " splittingKernel = " << splittingKernel()->name()
<< " splittingKinematics = " << generatedSplitting.splittingKinematics()->name() << "\n"
<< " to sample splittings of type:\n";
os << generatedSplitting;
os << "--------------------------------------------------------------------------------\n";
}
void DipoleSplittingGenerator::debugLastEvent(ostream& os) const {
os << "--- DipoleSplittingGenerator ---------------------------------------------------\n";
os << " last generated event:\n";
os << generatedSplitting;
os << "--------------------------------------------------------------------------------\n";
}
// If needed, insert default implementations of virtual function defined
// in the InterfacedBase class here (using ThePEG-interfaced-impl in Emacs).
void DipoleSplittingGenerator::persistentOutput(PersistentOStream & os) const {
os << theOtherGenerator << theSplittingKernel << theSplittingReweight << theMCCheck;
}
void DipoleSplittingGenerator::persistentInput(PersistentIStream & is, int) {
is >> theOtherGenerator >> theSplittingKernel >> theSplittingReweight >> theMCCheck;
}
ClassDescription<DipoleSplittingGenerator> DipoleSplittingGenerator::initDipoleSplittingGenerator;
// Definition of the static class description member.
void DipoleSplittingGenerator::Init() {
static ClassDocumentation<DipoleSplittingGenerator> documentation
("DipoleSplittingGenerator is used by the dipole shower "
"to sample splittings from a given dipole splitting kernel.");
static Reference<DipoleSplittingGenerator,DipoleSplittingKernel> interfaceSplittingKernel
("SplittingKernel",
"Set the splitting kernel to sample from.",
&DipoleSplittingGenerator::theSplittingKernel, false, false, true, false, false);
static Reference<DipoleSplittingGenerator,DipoleSplittingReweight> interfaceSplittingReweight
("SplittingReweight",
"Set the splitting reweight.",
&DipoleSplittingGenerator::theSplittingReweight, false, false, true, true, false);
static Reference<DipoleSplittingGenerator,DipoleMCCheck> interfaceMCCheck
("MCCheck",
"[debug option] MCCheck",
&DipoleSplittingGenerator::theMCCheck, false, false, true, true, false);
interfaceMCCheck.rank(-1);
}
diff --git a/DipoleShower/DipoleShowerHandler.cc b/DipoleShower/DipoleShowerHandler.cc
--- a/DipoleShower/DipoleShowerHandler.cc
+++ b/DipoleShower/DipoleShowerHandler.cc
@@ -1,992 +1,1008 @@
// -*- C++ -*-
//
// DipoleShowerHandler.cc is a part of Herwig++ - A multi-purpose Monte Carlo event generator
// Copyright (C) 2002-2007 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 DipoleShowerHandler class.
//
#include "DipoleShowerHandler.h"
#include "ThePEG/Interface/ClassDocumentation.h"
#include "ThePEG/Interface/Reference.h"
#include "ThePEG/Interface/RefVector.h"
#include "ThePEG/Interface/Parameter.h"
#include "ThePEG/Interface/Switch.h"
#include "ThePEG/Persistency/PersistentOStream.h"
#include "ThePEG/Persistency/PersistentIStream.h"
// include theses to have complete types
#include "Herwig++/Shower/Base/Evolver.h"
#include "Herwig++/Shower/Base/ShowerParticle.h"
#include "Herwig++/PDF/MPIPDF.h"
#include "Herwig++/PDF/MinBiasPDF.h"
#include "Herwig++/Shower/Base/ShowerTree.h"
#include "Herwig++/Shower/Base/KinematicsReconstructor.h"
#include "Herwig++/Shower/Base/PartnerFinder.h"
#include "Herwig++/PDF/HwRemDecayer.h"
#include "Herwig++/DipoleShower/Utility/DipolePartonSplitter.h"
#include "Herwig++/MatrixElement/Matchbox/Base/SubtractedME.h"
#include "Herwig++/MatrixElement/Matchbox/MatchboxFactory.h"
using namespace Herwig;
DipoleShowerHandler::DipoleShowerHandler()
: ShowerHandler(), chainOrderVetoScales(true),
nEmissions(0), discardNoEmissions(false), firstMCatNLOEmission(false),
doFSR(true), doISR(true), realignmentScheme(0),
hardFirstEmission(false),
verbosity(0), printEvent(0), nTries(0),
didRadiate(false), didRealign(false),
theRenormalizationScaleFreeze(1.*GeV),
theFactorizationScaleFreeze(1.*GeV),
theFactorizationScaleFactor(1.0),
theRenormalizationScaleFactor(1.0),
theHardScaleFactor(1.0),
isMCatNLOSEvent(false),
isMCatNLOHEvent(false) {}
DipoleShowerHandler::~DipoleShowerHandler() {}
IBPtr DipoleShowerHandler::clone() const {
return new_ptr(*this);
}
IBPtr DipoleShowerHandler::fullclone() const {
return new_ptr(*this);
}
tPPair DipoleShowerHandler::cascade(tSubProPtr sub, XCPtr) {
prepareCascade(sub);
if ( !doFSR && ! doISR )
return sub->incoming();
eventRecord().clear();
eventRecord().prepare(sub,dynamic_ptr_cast<tStdXCombPtr>(lastXCombPtr()),pdfs());
if ( eventRecord().outgoing().empty() && !doISR )
return sub->incoming();
if ( !eventRecord().incoming().first->coloured() &&
!eventRecord().incoming().second->coloured() &&
!doFSR )
return sub->incoming();
nTries = 0;
while ( true ) {
try {
didRadiate = false;
didRealign = false;
isMCatNLOSEvent = false;
isMCatNLOHEvent = false;
Ptr<SubtractedME>::tptr subme =
dynamic_ptr_cast<Ptr<SubtractedME>::tptr>(eventRecord().xcombPtr()->matrixElement());
Ptr<MatchboxMEBase>::tptr me =
dynamic_ptr_cast<Ptr<MatchboxMEBase>::tptr>(eventRecord().xcombPtr()->matrixElement());
if ( subme ) {
if ( subme->showerApproximation() ) {
theShowerApproximation = subme->showerApproximation();
if ( subme->realShowerSubtraction() )
isMCatNLOHEvent = true;
else if ( subme->virtualShowerSubtraction() )
isMCatNLOSEvent = true;
}
} else if ( me ) {
if ( me->factory()->showerApproximation() ) {
theShowerApproximation = me->factory()->showerApproximation();
isMCatNLOSEvent = true;
}
}
if ( theShowerApproximation ) {
theHardScaleFactor = theShowerApproximation->hardScaleFactor();
}
hardScales();
if ( verbosity > 1 ) {
generator()->log() << "DipoleShowerHandler starting off:\n";
eventRecord().debugLastEvent(generator()->log());
generator()->log() << flush;
}
unsigned int nEmitted = 0;
if ( firstMCatNLOEmission ) {
if ( !isMCatNLOHEvent )
nEmissions = 1;
else
nEmissions = 0;
}
if ( !firstMCatNLOEmission ) {
doCascade(nEmitted);
if ( discardNoEmissions ) {
if ( !didRadiate )
throw Veto();
if ( nEmissions )
if ( nEmissions < nEmitted )
throw Veto();
}
} else {
if ( nEmissions == 1 )
doCascade(nEmitted);
}
if ( intrinsicPtGenerator ) {
if ( eventRecord().incoming().first->coloured() &&
eventRecord().incoming().second->coloured() ) {
SpinOneLorentzRotation rot =
intrinsicPtGenerator->kick(eventRecord().incoming(),
eventRecord().intermediates());
eventRecord().transform(rot);
}
}
didRealign = realign();
constituentReshuffle();
break;
} catch (RedoShower&) {
if ( ++nTries > maxtry() )
throw ShowerTriesVeto(maxtry());
eventRecord().clear();
eventRecord().prepare(sub,dynamic_ptr_cast<tStdXCombPtr>(lastXCombPtr()),pdfs());
continue;
} catch (...) {
throw;
}
}
return eventRecord().fillEventRecord(newStep(),firstInteraction(),didRealign);
}
void DipoleShowerHandler::constituentReshuffle() {
if ( constituentReshuffler ) {
constituentReshuffler->reshuffle(eventRecord().outgoing(),
eventRecord().incoming(),
eventRecord().intermediates());
}
}
void DipoleShowerHandler::hardScales() {
Energy maxPt = generator()->maximumCMEnergy();
bool restrictPhasespace = !hardFirstEmission;
if ( !restrictPhasespace ) {
assert(eventRecord().xcombPtr());
Ptr<SubtractedME>::tptr subme =
dynamic_ptr_cast<Ptr<SubtractedME>::tptr>(eventRecord().xcombPtr()->matrixElement());
if ( subme )
if ( subme->realShowerSubtraction() )
restrictPhasespace = true;
}
if ( (eventRecord().incoming().first->coloured() ||
eventRecord().incoming().second->coloured()) &&
restrictPhasespace ) {
if ( !eventRecord().outgoing().empty() ) {
for ( PList::const_iterator p = eventRecord().outgoing().begin();
p != eventRecord().outgoing().end(); ++p )
maxPt = min(maxPt,(**p).momentum().perp());
} else {
assert(!eventRecord().hard().empty());
Lorentz5Momentum phard(ZERO,ZERO,ZERO,ZERO);
for ( PList::const_iterator p = eventRecord().hard().begin();
p != eventRecord().hard().end(); ++p )
phard += (**p).momentum();
Energy mhard = phard.m();
maxPt = mhard;
}
maxPt *= theHardScaleFactor;
}
for ( list<DipoleChain>::iterator ch = eventRecord().chains().begin();
ch != eventRecord().chains().end(); ++ch ) {
Energy minVetoScale = -1.*GeV;
for ( list<Dipole>::iterator dip = ch->dipoles().begin();
dip != ch->dipoles().end(); ++dip ) {
// max scale per config
Energy maxFirst = 0.0*GeV;
Energy maxSecond = 0.0*GeV;
for ( vector<Ptr<DipoleSplittingKernel>::ptr>::iterator k =
kernels.begin(); k != kernels.end(); ++k ) {
pair<bool,bool> conf = make_pair(true,false);
if ( (**k).canHandle(dip->index(conf)) ) {
Energy scale =
evolutionOrdering()->hardScale(dip->emitter(conf),dip->spectator(conf),
dip->emitterX(conf),dip->spectatorX(conf),
**k,dip->index(conf));
maxFirst = max(maxFirst,scale);
}
conf = make_pair(false,true);
if ( (**k).canHandle(dip->index(conf)) ) {
Energy scale =
evolutionOrdering()->hardScale(dip->emitter(conf),dip->spectator(conf),
dip->emitterX(conf),dip->spectatorX(conf),
**k,dip->index(conf));
maxSecond = max(maxSecond,scale);
}
}
if ( dip->leftParticle()->vetoScale() >= ZERO ) {
maxFirst = min(maxFirst,sqrt(dip->leftParticle()->vetoScale()));
if ( minVetoScale >= ZERO )
minVetoScale = min(minVetoScale,sqrt(dip->leftParticle()->vetoScale()));
else
minVetoScale = sqrt(dip->leftParticle()->vetoScale());
}
if ( dip->rightParticle()->vetoScale() >= ZERO ) {
maxSecond = min(maxSecond,sqrt(dip->rightParticle()->vetoScale()));
if ( minVetoScale >= ZERO )
minVetoScale = min(minVetoScale,sqrt(dip->rightParticle()->vetoScale()));
else
minVetoScale = sqrt(dip->rightParticle()->vetoScale());
}
maxFirst = min(maxPt,maxFirst);
dip->emitterScale(make_pair(true,false),maxFirst);
maxSecond = min(maxPt,maxSecond);
dip->emitterScale(make_pair(false,true),maxSecond);
}
if ( !evolutionOrdering()->independentDipoles() &&
chainOrderVetoScales &&
minVetoScale >= ZERO ) {
for ( list<Dipole>::iterator dip = ch->dipoles().begin();
dip != ch->dipoles().end(); ++dip ) {
dip->leftScale(min(dip->leftScale(),minVetoScale));
dip->rightScale(min(dip->rightScale(),minVetoScale));
}
}
}
}
Energy DipoleShowerHandler::getWinner(DipoleSplittingInfo& winner,
const Dipole& dip,
pair<bool,bool> conf) {
if ( !dip.index(conf).initialStateEmitter() &&
!doFSR ) {
winner.didStopEvolving();
return 0.0*GeV;
}
if ( dip.index(conf).initialStateEmitter() &&
!doISR ) {
winner.didStopEvolving();
return 0.0*GeV;
}
DipoleSplittingInfo candidate;
candidate.index(dip.index(conf));
candidate.configuration(conf);
candidate.emitterX(dip.emitterX(conf));
candidate.spectatorX(dip.spectatorX(conf));
if ( generators().find(candidate.index()) == generators().end() )
getGenerators(candidate.index());
//
// NOTE -- needs proper fixing at some point
//
// For some very strange reason, equal_range gives back
// key ranges it hasn't been asked for. This particularly
// happens e.g. for FI dipoles of the same kind, but different
// PDF (hard vs MPI PDF). I can't see a reason for this,
// as DipoleIndex properly implements comparison for equality
// and (lexicographic) ordering; for the time being, we
// use equal_range, extented by an explicit check for wether
// the key is indeed what we wanted. See line after (*) comment
// below.
//
pair<GeneratorMap::iterator,GeneratorMap::iterator> gens
= generators().equal_range(candidate.index());
tPPtr emitter = dip.emitter(conf);
tPPtr spectator = dip.spectator(conf);
Energy startScale = dip.emitterScale(conf);
Energy winnerScale = 0.0*GeV;
GeneratorMap::iterator winnerGen = generators().end();
for ( GeneratorMap::iterator gen = gens.first; gen != gens.second; ++gen ) {
// (*) see NOTE above
if ( !(gen->first == candidate.index()) )
continue;
if ( startScale <= gen->second->splittingKinematics()->IRCutoff() )
continue;
Energy dScale =
gen->second->splittingKinematics()->dipoleScale(emitter->momentum(),
spectator->momentum());
// in very exceptional cases happening in DIS
if ( isnan(dScale/GeV ) )
throw RedoShower();
candidate.scale(dScale);
candidate.continuesEvolving();
Energy hardScale = evolutionOrdering()->maxPt(startScale,candidate,*(gen->second->splittingKernel()));
- candidate.hardPt(hardScale);
+ Energy maxPossible =
+ gen->second->splittingKinematics()->ptMax(candidate.scale(),
+ candidate.emitterX(), candidate.spectatorX(),
+ candidate.index(),
+ *gen->second->splittingKernel());
+
+ if ( maxPossible <= gen->second->splittingKinematics()->IRCutoff() ) {
+ continue;
+ }
+
+ if ( maxPossible >= hardScale )
+ candidate.hardPt(hardScale);
+ else
+ candidate.hardPt(maxPossible);
gen->second->generate(candidate);
Energy nextScale = evolutionOrdering()->evolutionScale(gen->second->lastSplitting(),*(gen->second->splittingKernel()));
if ( isMCatNLOSEvent ) {
- assert(theShowerApproximation);
- if ( theShowerApproximation->restrictPhasespace() &&
- theShowerApproximation->profileScales() ) {
- while ( UseRandom::rnd() > theShowerApproximation->hardScaleProfile(hardScale,nextScale) ) {
- candidate.continuesEvolving();
- Energy nextHardScale = evolutionOrdering()->maxPt(nextScale,candidate,*(gen->second->splittingKernel()));
- candidate.hardPt(nextHardScale);
- gen->second->generate(candidate);
- nextScale = evolutionOrdering()->evolutionScale(gen->second->lastSplitting(),*(gen->second->splittingKernel()));
- if ( nextScale == ZERO || candidate.stoppedEvolving() )
- break;
+ if ( eventRecord().incoming().first->coloured() ||
+ eventRecord().incoming().second->coloured() ) {
+ assert(theShowerApproximation);
+ if ( theShowerApproximation->restrictPhasespace() &&
+ theShowerApproximation->profileScales() ) {
+ while ( UseRandom::rnd() > theShowerApproximation->hardScaleProfile(hardScale,nextScale) ) {
+ candidate.continuesEvolving();
+ Energy nextHardScale = evolutionOrdering()->maxPt(nextScale,candidate,*(gen->second->splittingKernel()));
+ candidate.hardPt(nextHardScale);
+ gen->second->generate(candidate);
+ nextScale = evolutionOrdering()->evolutionScale(gen->second->lastSplitting(),*(gen->second->splittingKernel()));
+ if ( nextScale == ZERO || candidate.stoppedEvolving() )
+ break;
+ }
}
}
}
if ( nextScale > winnerScale ) {
winner = candidate;
gen->second->completeSplitting(winner);
winnerGen = gen;
winnerScale = nextScale;
}
}
if ( winnerGen == generators().end() ) {
winner.didStopEvolving();
return 0.0*GeV;
}
if ( winner.stoppedEvolving() )
return 0.0*GeV;
return winnerScale;
}
void DipoleShowerHandler::doCascade(unsigned int& emDone) {
if ( nEmissions )
if ( emDone == nEmissions )
return;
DipoleSplittingInfo winner;
DipoleSplittingInfo dipoleWinner;
while ( eventRecord().haveChain() ) {
if ( verbosity > 2 ) {
generator()->log() << "DipoleShowerHandler selecting splittings for the chain:\n"
<< eventRecord().currentChain() << flush;
}
list<Dipole>::iterator winnerDip = eventRecord().currentChain().dipoles().end();
Energy winnerScale = 0.0*GeV;
Energy nextLeftScale = 0.0*GeV;
Energy nextRightScale = 0.0*GeV;
for ( list<Dipole>::iterator dip = eventRecord().currentChain().dipoles().begin();
dip != eventRecord().currentChain().dipoles().end(); ++dip ) {
nextLeftScale = getWinner(dipoleWinner,*dip,make_pair(true,false));
if ( nextLeftScale > winnerScale ) {
winnerScale = nextLeftScale;
winner = dipoleWinner;
winnerDip = dip;
}
nextRightScale = getWinner(dipoleWinner,*dip,make_pair(false,true));
if ( nextRightScale > winnerScale ) {
winnerScale = nextRightScale;
winner = dipoleWinner;
winnerDip = dip;
}
if ( evolutionOrdering()->independentDipoles() ) {
Energy dipScale = max(nextLeftScale,nextRightScale);
if ( dip->leftScale() > dipScale )
dip->leftScale(dipScale);
if ( dip->rightScale() > dipScale )
dip->rightScale(dipScale);
}
}
if ( verbosity > 1 ) {
if ( winnerDip != eventRecord().currentChain().dipoles().end() )
generator()->log() << "DipoleShowerHandler selected the splitting:\n"
<< winner << " for the dipole\n"
<< (*winnerDip) << flush;
else
generator()->log() << "DipoleShowerHandler could not select a splitting above the IR cutoff\n"
<< flush;
}
// pop the chain if no dipole did radiate
if ( winnerDip == eventRecord().currentChain().dipoles().end() ) {
eventRecord().popChain();
continue;
}
// otherwise perform the splitting
didRadiate = true;
isMCatNLOSEvent = false;
isMCatNLOHEvent = false;
pair<list<Dipole>::iterator,list<Dipole>::iterator> children;
DipoleChain* firstChain = 0;
DipoleChain* secondChain = 0;
eventRecord().split(winnerDip,winner,children,firstChain,secondChain);
assert(firstChain && secondChain);
evolutionOrdering()->setEvolutionScale(winnerScale,winner,*firstChain,children);
if ( !secondChain->dipoles().empty() )
evolutionOrdering()->setEvolutionScale(winnerScale,winner,*secondChain,children);
if ( verbosity > 1 ) {
generator()->log() << "DipoleShowerHandler did split the last selected dipole into:\n"
<< (*children.first) << (*children.second) << flush;
}
if ( verbosity > 2 ) {
generator()->log() << "After splitting the last selected dipole, "
<< "DipoleShowerHandler encountered the following chains:\n"
<< (*firstChain) << (*secondChain) << flush;
}
if ( nEmissions )
if ( ++emDone == nEmissions )
return;
}
}
bool DipoleShowerHandler::realign() {
if ( !didRadiate && !intrinsicPtGenerator )
return false;
if ( eventRecord().incoming().first->coloured() ||
eventRecord().incoming().second->coloured() ) {
if ( eventRecord().incoming().first->momentum().perp2()/GeV2 < 1e-10 &&
eventRecord().incoming().second->momentum().perp2()/GeV2 < 1e-10 )
return false;
pair<Lorentz5Momentum,Lorentz5Momentum> inMomenta
(eventRecord().incoming().first->momentum(),
eventRecord().incoming().second->momentum());
SpinOneLorentzRotation transform((inMomenta.first+inMomenta.second).findBoostToCM());
Axis dir = (transform * inMomenta.first).vect().unit();
Axis rot (-dir.y(),dir.x(),0);
double theta = dir.theta();
if ( lastParticles().first->momentum().z() < ZERO )
theta = -theta;
transform.rotate(-theta,rot);
inMomenta.first = transform*inMomenta.first;
inMomenta.second = transform*inMomenta.second;
assert(inMomenta.first.z() > ZERO &&
inMomenta.second.z() < ZERO);
Energy2 sHat =
(eventRecord().incoming().first->momentum() +
eventRecord().incoming().second->momentum()).m2();
pair<Energy,Energy> masses(eventRecord().incoming().first->mass(),
eventRecord().incoming().second->mass());
pair<Energy,Energy> qs;
if ( !eventRecord().incoming().first->coloured() ) {
assert(masses.second == ZERO);
qs.first = eventRecord().incoming().first->momentum().z();
qs.second = (sHat-sqr(masses.first))/(2.*(qs.first+sqrt(sqr(masses.first)+sqr(qs.first))));
} else if ( !eventRecord().incoming().second->coloured() ) {
assert(masses.first == ZERO);
qs.second = eventRecord().incoming().second->momentum().z();
qs.first = (sHat-sqr(masses.second))/(2.*(qs.second+sqrt(sqr(masses.second)+sqr(qs.second))));
} else {
assert(masses.first == ZERO && masses.second == ZERO);
if ( realignmentScheme == 0 ) {
double yX = eventRecord().pX().rapidity();
double yInt = (transform*eventRecord().pX()).rapidity();
double dy = yX-yInt;
qs.first = (sqrt(sHat)/2.)*exp(dy);
qs.second = (sqrt(sHat)/2.)*exp(-dy);
} else if ( realignmentScheme == 1 ) {
Energy sS = sqrt((lastParticles().first->momentum() +
lastParticles().second->momentum()).m2());
qs.first = eventRecord().fractions().first * sS / 2.;
qs.second = eventRecord().fractions().second * sS / 2.;
}
}
double beta =
(qs.first-qs.second) /
( sqrt(sqr(masses.first)+sqr(qs.first)) +
sqrt(sqr(masses.second)+sqr(qs.second)) );
transform.boostZ(beta);
Lorentz5Momentum tmp;
if ( eventRecord().incoming().first->coloured() ) {
tmp = eventRecord().incoming().first->momentum();
tmp = transform * tmp;
eventRecord().incoming().first->set5Momentum(tmp);
}
if ( eventRecord().incoming().second->coloured() ) {
tmp = eventRecord().incoming().second->momentum();
tmp = transform * tmp;
eventRecord().incoming().second->set5Momentum(tmp);
}
eventRecord().transform(transform);
return true;
}
return false;
}
void DipoleShowerHandler::resetAlphaS(Ptr<AlphaSBase>::tptr as) {
for ( vector<Ptr<DipoleSplittingKernel>::ptr>::iterator k = kernels.begin();
k != kernels.end(); ++k ) {
(**k).alphaS(as);
(**k).renormalizationScaleFreeze(theRenormalizationScaleFreeze);
(**k).factorizationScaleFreeze(theFactorizationScaleFreeze);
}
// clear the generators to be rebuild
// actually, there shouldn't be any generators
// when this happens.
generators().clear();
}
void DipoleShowerHandler::resetReweight(Ptr<DipoleSplittingReweight>::tptr rw) {
for ( GeneratorMap::iterator k = generators().begin();
k != generators().end(); ++k )
k->second->splittingReweight(rw);
}
void DipoleShowerHandler::getGenerators(const DipoleIndex& ind,
Ptr<DipoleSplittingReweight>::tptr rw) {
bool gotone = false;
for ( vector<Ptr<DipoleSplittingKernel>::ptr>::iterator k =
kernels.begin(); k != kernels.end(); ++k ) {
if ( (**k).canHandle(ind) ) {
if ( verbosity > 0 ) {
generator()->log() << "DipoleShowerHandler encountered the dipole configuration\n"
<< ind << " in event number "
<< eventHandler()->currentEvent()->number()
<< "\nwhich can be handled by the splitting kernel '"
<< (**k).name() << "'.\n" << flush;
}
gotone = true;
Ptr<DipoleSplittingGenerator>::ptr nGenerator =
new_ptr(DipoleSplittingGenerator());
nGenerator->splittingKernel(*k);
nGenerator->splittingKernel()->renormalizationScaleFactor(theRenormalizationScaleFactor);
nGenerator->splittingKernel()->factorizationScaleFactor(theFactorizationScaleFactor);
GeneratorMap::const_iterator equivalent = generators().end();
for ( GeneratorMap::const_iterator eq = generators().begin();
eq != generators().end(); ++eq ) {
if ( !eq->second->wrapping() )
if ( (**k).canHandleEquivalent(ind,*(eq->second->splittingKernel()),eq->first) ) {
equivalent = eq;
if ( verbosity > 0 ) {
generator()->log() << "The dipole configuration "
<< ind
<< " can equivalently be handled by the existing\n"
<< "generator for configuration "
<< eq->first << " using the kernel '"
<< eq->second->splittingKernel()->name()
<< "'\n" << flush;
}
break;
}
}
if ( equivalent != generators().end() ) {
nGenerator->wrap(equivalent->second);
}
DipoleSplittingInfo dummy;
dummy.index(ind);
nGenerator->splittingReweight(rw);
nGenerator->prepare(dummy);
generators().insert(make_pair(ind,nGenerator));
}
}
if ( !gotone ) {
generator()->logWarning(Exception()
<< "DipoleShowerHandler could not "
<< "find a splitting kernel which is able "
<< "to handle splittings off the dipole "
<< ind << ".\n"
<< "Please check the input files."
<< Exception::warning);
}
}
// If needed, insert default implementations of virtual function defined
// in the InterfacedBase class here (using ThePEG-interfaced-impl in Emacs).
void DipoleShowerHandler::doinit() {
ShowerHandler::doinit();
if ( theGlobalAlphaS )
resetAlphaS(theGlobalAlphaS);
}
void DipoleShowerHandler::dofinish() {
ShowerHandler::dofinish();
}
void DipoleShowerHandler::doinitrun() {
ShowerHandler::doinitrun();
}
void DipoleShowerHandler::persistentOutput(PersistentOStream & os) const {
os << kernels << theEvolutionOrdering
<< constituentReshuffler << intrinsicPtGenerator
<< theGlobalAlphaS << chainOrderVetoScales
<< nEmissions << discardNoEmissions << firstMCatNLOEmission << doFSR << doISR
<< realignmentScheme << hardFirstEmission << verbosity << printEvent
<< ounit(theRenormalizationScaleFreeze,GeV)
<< ounit(theFactorizationScaleFreeze,GeV)
<< theFactorizationScaleFactor << theRenormalizationScaleFactor
<< theHardScaleFactor
<< isMCatNLOSEvent << isMCatNLOHEvent << theShowerApproximation;
}
void DipoleShowerHandler::persistentInput(PersistentIStream & is, int) {
is >> kernels >> theEvolutionOrdering
>> constituentReshuffler >> intrinsicPtGenerator
>> theGlobalAlphaS >> chainOrderVetoScales
>> nEmissions >> discardNoEmissions >> firstMCatNLOEmission >> doFSR >> doISR
>> realignmentScheme >> hardFirstEmission >> verbosity >> printEvent
>> iunit(theRenormalizationScaleFreeze,GeV)
>> iunit(theFactorizationScaleFreeze,GeV)
>> theFactorizationScaleFactor >> theRenormalizationScaleFactor
>> theHardScaleFactor
>> isMCatNLOSEvent >> isMCatNLOHEvent >> theShowerApproximation;
}
ClassDescription<DipoleShowerHandler> DipoleShowerHandler::initDipoleShowerHandler;
// Definition of the static class description member.
void DipoleShowerHandler::Init() {
static ClassDocumentation<DipoleShowerHandler> documentation
("The DipoleShowerHandler class manages the showering using "
"the dipole shower algorithm.",
"The shower evolution was performed using the algorithm described in "
"\\cite{Platzer:2009jq} and \\cite{Platzer:2011bc}.",
"%\\cite{Platzer:2009jq}\n"
"\\bibitem{Platzer:2009jq}\n"
"S.~Platzer and S.~Gieseke,\n"
"``Coherent Parton Showers with Local Recoils,''\n"
" JHEP {\\bf 1101}, 024 (2011)\n"
"arXiv:0909.5593 [hep-ph].\n"
"%%CITATION = ARXIV:0909.5593;%%\n"
"%\\cite{Platzer:2011bc}\n"
"\\bibitem{Platzer:2011bc}\n"
"S.~Platzer and S.~Gieseke,\n"
"``Dipole Showers and Automated NLO Matching in Herwig++,''\n"
"arXiv:1109.6256 [hep-ph].\n"
"%%CITATION = ARXIV:1109.6256;%%");
static RefVector<DipoleShowerHandler,DipoleSplittingKernel> interfaceKernels
("Kernels",
"Set the splitting kernels to be used by the dipole shower.",
&DipoleShowerHandler::kernels, -1, false, false, true, false, false);
static Reference<DipoleShowerHandler,DipoleEvolutionOrdering> interfaceEvolutionOrdering
("EvolutionOrdering",
"Set the evolution ordering to be used.",
&DipoleShowerHandler::theEvolutionOrdering, false, false, true, false, false);
static Reference<DipoleShowerHandler,ConstituentReshuffler> interfaceConstituentReshuffler
("ConstituentReshuffler",
"The object to be used to reshuffle partons to their constitutent mass shells.",
&DipoleShowerHandler::constituentReshuffler, false, false, true, true, false);
static Reference<DipoleShowerHandler,IntrinsicPtGenerator> interfaceIntrinsicPtGenerator
("IntrinsicPtGenerator",
"Set the object in charge to generate intrinsic pt for incoming partons.",
&DipoleShowerHandler::intrinsicPtGenerator, false, false, true, true, false);
static Reference<DipoleShowerHandler,AlphaSBase> interfaceGlobalAlphaS
("GlobalAlphaS",
"Set a global strong coupling for all splitting kernels.",
&DipoleShowerHandler::theGlobalAlphaS, false, false, true, true, false);
static Switch<DipoleShowerHandler,bool> interfaceDoFSR
("DoFSR",
"Switch on or off final state radiation.",
&DipoleShowerHandler::doFSR, true, false, false);
static SwitchOption interfaceDoFSROn
(interfaceDoFSR,
"On",
"Switch on final state radiation.",
true);
static SwitchOption interfaceDoFSROff
(interfaceDoFSR,
"Off",
"Switch off final state radiation.",
false);
static Switch<DipoleShowerHandler,bool> interfaceDoISR
("DoISR",
"Switch on or off initial state radiation.",
&DipoleShowerHandler::doISR, true, false, false);
static SwitchOption interfaceDoISROn
(interfaceDoISR,
"On",
"Switch on initial state radiation.",
true);
static SwitchOption interfaceDoISROff
(interfaceDoISR,
"Off",
"Switch off initial state radiation.",
false);
static Switch<DipoleShowerHandler,bool> interfaceHardFirstEmission
("HardFirstEmission",
"Switch on or off hard first emission.",
&DipoleShowerHandler::hardFirstEmission, false, false, false);
static SwitchOption interfaceHardFirstEmissionOn
(interfaceHardFirstEmission,
"On",
"Switch on hard first emission.",
true);
static SwitchOption interfaceHardFirstEmissionOff
(interfaceHardFirstEmission,
"Off",
"Switch off hard first emission.",
false);
static Switch<DipoleShowerHandler,int> interfaceRealignmentScheme
("RealignmentScheme",
"The realignment scheme to use.",
&DipoleShowerHandler::realignmentScheme, 0, false, false);
static SwitchOption interfaceRealignmentSchemePreserveRapidity
(interfaceRealignmentScheme,
"PreserveRapidity",
"Preserve the rapidity of non-coloured outgoing system.",
0);
static SwitchOption interfaceRealignmentSchemeEvolutionFractions
(interfaceRealignmentScheme,
"EvolutionFractions",
"Use momentum fractions as generated by the evolution.",
1);
static SwitchOption interfaceRealignmentSchemeCollisionFrame
(interfaceRealignmentScheme,
"CollisionFrame",
"Determine realignment from collision frame.",
2);
static Switch<DipoleShowerHandler,bool> interfaceChainOrderVetoScales
("ChainOrderVetoScales",
"[experimental] Switch on or off the chain ordering for veto scales.",
&DipoleShowerHandler::chainOrderVetoScales, true, false, false);
static SwitchOption interfaceChainOrderVetoScalesOn
(interfaceChainOrderVetoScales,
"On",
"Switch on chain ordering for veto scales.",
true);
static SwitchOption interfaceChainOrderVetoScalesOff
(interfaceChainOrderVetoScales,
"Off",
"Switch off chain ordering for veto scales.",
false);
interfaceChainOrderVetoScales.rank(-1);
static Parameter<DipoleShowerHandler,unsigned int> interfaceNEmissions
("NEmissions",
"[debug option] Limit the number of emissions to be generated. Zero does not limit the number of emissions.",
&DipoleShowerHandler::nEmissions, 0, 0, 0,
false, false, Interface::lowerlim);
interfaceNEmissions.rank(-1);
static Switch<DipoleShowerHandler,bool> interfaceDiscardNoEmissions
("DiscardNoEmissions",
"[debug option] Discard events without radiation.",
&DipoleShowerHandler::discardNoEmissions, false, false, false);
static SwitchOption interfaceDiscardNoEmissionsOn
(interfaceDiscardNoEmissions,
"On",
"Discard events without radiation.",
true);
static SwitchOption interfaceDiscardNoEmissionsOff
(interfaceDiscardNoEmissions,
"Off",
"Do not discard events without radiation.",
false);
interfaceDiscardNoEmissions.rank(-1);
static Switch<DipoleShowerHandler,bool> interfaceFirstMCatNLOEmission
("FirstMCatNLOEmission",
"[debug option] Only perform the first MC@NLO emission.",
&DipoleShowerHandler::firstMCatNLOEmission, false, false, false);
static SwitchOption interfaceFirstMCatNLOEmissionOn
(interfaceFirstMCatNLOEmission,
"On",
"",
true);
static SwitchOption interfaceFirstMCatNLOEmissionOff
(interfaceFirstMCatNLOEmission,
"Off",
"",
false);
interfaceFirstMCatNLOEmission.rank(-1);
static Parameter<DipoleShowerHandler,int> interfaceVerbosity
("Verbosity",
"[debug option] Set the level of debug information provided.",
&DipoleShowerHandler::verbosity, 0, 0, 0,
false, false, Interface::lowerlim);
interfaceVerbosity.rank(-1);
static Parameter<DipoleShowerHandler,int> interfacePrintEvent
("PrintEvent",
"[debug option] The number of events for which debugging information should be provided.",
&DipoleShowerHandler::printEvent, 0, 0, 0,
false, false, Interface::lowerlim);
interfacePrintEvent.rank(-1);
static Parameter<DipoleShowerHandler,double> interfaceFactorizationScaleFactor
("FactorizationScaleFactor",
"The factorization scale factor.",
&DipoleShowerHandler::theFactorizationScaleFactor, 1.0, 0.0, 0,
false, false, Interface::lowerlim);
static Parameter<DipoleShowerHandler,double> interfaceRenormalizationScaleFactor
("RenormalizationScaleFactor",
"The renormalization scale factor.",
&DipoleShowerHandler::theRenormalizationScaleFactor, 1.0, 0.0, 0,
false, false, Interface::lowerlim);
static Parameter<DipoleShowerHandler,double> interfaceHardScaleFactor
("HardScaleFactor",
"The hard scale factor.",
&DipoleShowerHandler::theHardScaleFactor, 1.0, 0.0, 0,
false, false, Interface::lowerlim);
static Parameter<DipoleShowerHandler,Energy> interfaceRenormalizationScaleFreeze
("RenormalizationScaleFreeze",
"The freezing scale for the renormalization scale.",
&DipoleShowerHandler::theRenormalizationScaleFreeze, GeV, 1.0*GeV, 0.0*GeV, 0*GeV,
false, false, Interface::lowerlim);
static Parameter<DipoleShowerHandler,Energy> interfaceFactorizationScaleFreeze
("FactorizationScaleFreeze",
"The freezing scale for the factorization scale.",
&DipoleShowerHandler::theFactorizationScaleFreeze, GeV, 1.0*GeV, 0.0*GeV, 0*GeV,
false, false, Interface::lowerlim);
}
diff --git a/DipoleShower/Kinematics/DipoleSplittingKinematics.cc b/DipoleShower/Kinematics/DipoleSplittingKinematics.cc
--- a/DipoleShower/Kinematics/DipoleSplittingKinematics.cc
+++ b/DipoleShower/Kinematics/DipoleSplittingKinematics.cc
@@ -1,167 +1,238 @@
// -*- C++ -*-
//
// DipoleSplittingKinematics.h is a part of Herwig++ - A multi-purpose Monte Carlo event generator
// Copyright (C) 2002-2007 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 DipoleSplittingKinematics class.
//
#include "DipoleSplittingKinematics.h"
#include "Herwig++/DipoleShower/Base/DipoleSplittingInfo.h"
#include "ThePEG/Interface/ClassDocumentation.h"
#include "ThePEG/Interface/Reference.h"
#include "ThePEG/Interface/Parameter.h"
#include "ThePEG/Persistency/PersistentOStream.h"
#include "ThePEG/Persistency/PersistentIStream.h"
+#include "Herwig++/MatrixElement/Matchbox/Phasespace/RandomHelpers.h"
+
#include <limits>
using namespace Herwig;
DipoleSplittingKinematics::DipoleSplittingKinematics()
: HandlerBase(), theIRCutoff(1.0*GeV),
theXMin(1.e-5), theJacobian(0.0),
theLastPt(0.0*GeV), theLastZ(0.0), theLastPhi(0.0),
theLastEmitterZ(1.0), theLastSpectatorZ(1.0),
theLastSplittingParameters() {}
DipoleSplittingKinematics::~DipoleSplittingKinematics() {}
void DipoleSplittingKinematics::persistentOutput(PersistentOStream & os) const {
os << ounit(theIRCutoff,GeV) << theXMin << theMCCheck;
}
void DipoleSplittingKinematics::persistentInput(PersistentIStream & is, int) {
is >> iunit(theIRCutoff,GeV) >> theXMin >> theMCCheck;
}
void DipoleSplittingKinematics::prepareSplitting(DipoleSplittingInfo& dInfo) {
dInfo.splittingKinematics(this);
if ( lastPt() > IRCutoff() )
dInfo.lastPt(lastPt());
else {
dInfo.lastPt(0.0*GeV);
dInfo.didStopEvolving();
}
dInfo.lastZ(lastZ());
dInfo.lastPhi(lastPhi());
dInfo.lastEmitterZ(lastEmitterZ());
dInfo.lastSpectatorZ(lastSpectatorZ());
dInfo.splittingParameters().resize(lastSplittingParameters().size());
copy(lastSplittingParameters().begin(),lastSplittingParameters().end(),
dInfo.splittingParameters().begin());
}
+Energy DipoleSplittingKinematics::generatePt(double r, Energy dScale,
+ double emX, double specX,
+ const DipoleIndex& dIndex,
+ const DipoleSplittingKernel& split,
+ double& weight) const {
+
+ Energy maxPt = ptMax(dScale,emX,specX,dIndex,split);
+ if ( maxPt <= IRCutoff() ) {
+ weight = 0.0;
+ return ZERO;
+ }
+
+ weight *= log(sqr(maxPt/IRCutoff()));
+
+ return IRCutoff()*pow(maxPt/IRCutoff(),r);
+
+}
+
+double DipoleSplittingKinematics::ptToRandom(Energy pt, Energy dScale,
+ double emX, double specX,
+ const DipoleIndex& dIndex,
+ const DipoleSplittingKernel& split) const {
+
+ Energy maxPt = ptMax(dScale,emX,specX,dIndex,split);
+ assert(pt >= IRCutoff() && pt <= maxPt);
+
+ return log(pt/IRCutoff())/log(maxPt/IRCutoff());
+
+}
+
+double DipoleSplittingKinematics::generateZ(double r, Energy pt, int sampling,
+ const DipoleSplittingInfo& dInfo,
+ const DipoleSplittingKernel& split,
+ double& weight) const {
+
+ pair<double,double> zLims = zBoundaries(pt,dInfo,split);
+
+ using namespace RandomHelpers;
+
+ if ( sampling == FlatZ ) {
+ pair<double,double> kw = generate(flat(zLims.first,zLims.second),r);
+ weight *= kw.second;
+ return kw.first;
+ }
+
+ if ( sampling == OneOverZ ) {
+ pair<double,double> kw = generate(inverse(0.0,zLims.first,zLims.second),r);
+ weight *= kw.second;
+ return kw.first;
+ }
+
+ if ( sampling == OneOverOneMinusZ ) {
+ pair<double,double> kw = generate(inverse(1.0,zLims.first,zLims.second),r);
+ weight *= kw.second;
+ return kw.first;
+ }
+
+ if ( sampling == OneOverOneMinusZ ) {
+ pair<double,double> kw = generate(inverse(0.0,zLims.first,zLims.second) +
+ inverse(1.0,zLims.first,zLims.second),r);
+ weight *= kw.second;
+ return kw.first;
+ }
+
+ weight = 0.0;
+ return 0.0;
+
+}
+
Lorentz5Momentum DipoleSplittingKinematics::getKt(const Lorentz5Momentum& p1,
const Lorentz5Momentum& p2,
Energy pt,
double phi,
bool spacelike) const {
Lorentz5Momentum P;
if ( !spacelike )
P = p1 + p2;
else
P = p1 - p2;
Energy2 Q2 = abs(P.m2());
Lorentz5Momentum Q =
!spacelike ?
Lorentz5Momentum(ZERO,ZERO,ZERO,sqrt(Q2),sqrt(Q2)) :
Lorentz5Momentum(ZERO,ZERO,sqrt(Q2),ZERO,-sqrt(Q2));
if ( spacelike && Q.z() < P.z() )
Q.setZ(-Q.z());
bool boost =
abs((P-Q).vect().mag2()/GeV2) > 1e-10 ||
abs((P-Q).t()/GeV) > 1e-5;
Lorentz5Momentum inFrame1;
if ( boost )
inFrame1 = p1 + ((P*p1-Q*p1)/(P*Q-Q.mass2()))*(P-Q);
else
inFrame1 = p1;
Energy ptx = inFrame1.x();
Energy pty = inFrame1.y();
Energy q = 2.*inFrame1.z();
Energy Qp = sqrt(4.*(sqr(ptx)+sqr(pty))+sqr(q));
Energy Qy = sqrt(4.*sqr(pty)+sqr(q));
double cPhi = cos(phi);
double sPhi = sqrt(1.-sqr(cPhi));
if ( phi > Constants::pi )
sPhi = -sPhi;
Lorentz5Momentum kt;
if ( !spacelike ) {
kt.setT(ZERO);
kt.setX(pt*Qy*cPhi/Qp);
kt.setY(-pt*(4*ptx*pty*cPhi/Qp+q*sPhi)/Qy);
kt.setZ(2.*pt*(-ptx*q*cPhi/Qp + pty*sPhi)/Qy);
} else {
kt.setT(2.*pt*(ptx*q*cPhi+pty*Qp*sPhi)/(q*Qy));
kt.setX(pt*(Qp*q*cPhi+4.*ptx*pty*sPhi)/(q*Qy));
kt.setY(pt*Qy*sPhi/q);
kt.setZ(ZERO);
}
if ( boost )
kt = kt + ((P*kt-Q*kt)/(P*Q-Q.mass2()))*(P-Q);
kt.setMass(-pt);
kt.rescaleRho();
return kt;
}
// If needed, insert default implementations of virtual function defined
// in the InterfacedBase class here (using ThePEG-interfaced-impl in Emacs).
AbstractClassDescription<DipoleSplittingKinematics> DipoleSplittingKinematics::initDipoleSplittingKinematics;
// Definition of the static class description member.
void DipoleSplittingKinematics::Init() {
static ClassDocumentation<DipoleSplittingKinematics> documentation
("DipoleSplittingKinematics is the base class for dipole splittings "
"as performed in the dipole shower.");
static Parameter<DipoleSplittingKinematics,Energy> interfaceIRCutoff
("IRCutoff",
"The IR cutoff to be used by this splitting kinematics.",
&DipoleSplittingKinematics::theIRCutoff, GeV, 1.0*GeV, 0.0*GeV, 0*GeV,
false, false, Interface::lowerlim);
static Parameter<DipoleSplittingKinematics,double> interfaceXMin
("XMin",
"The minimum momentum fraction for incoming partons",
&DipoleSplittingKinematics::theXMin, 1.0e-5, 0.0, 1.0,
false, false, Interface::limited);
static Reference<DipoleSplittingKinematics,DipoleMCCheck> interfaceMCCheck
("MCCheck",
"[debug option] MCCheck",
&DipoleSplittingKinematics::theMCCheck, false, false, true, true, false);
interfaceMCCheck.rank(-1);
}
diff --git a/DipoleShower/Kinematics/DipoleSplittingKinematics.h b/DipoleShower/Kinematics/DipoleSplittingKinematics.h
--- a/DipoleShower/Kinematics/DipoleSplittingKinematics.h
+++ b/DipoleShower/Kinematics/DipoleSplittingKinematics.h
@@ -1,476 +1,507 @@
// -*- C++ -*-
//
// DipoleSplittingKinematics.h is a part of Herwig++ - A multi-purpose Monte Carlo event generator
// Copyright (C) 2002-2007 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.
//
#ifndef HERWIG_DipoleSplittingKinematics_H
#define HERWIG_DipoleSplittingKinematics_H
//
// This is the declaration of the DipoleSplittingKinematics class.
//
#include "ThePEG/Handlers/HandlerBase.h"
#include "ThePEG/Vectors/Lorentz5Vector.h"
#include "Herwig++/DipoleShower/Utility/DipoleMCCheck.h"
namespace Herwig {
using namespace ThePEG;
class DipoleIndex;
class DipoleSplittingInfo;
class DipoleSplittingKernel;
/**
* \ingroup DipoleShower
* \author Simon Platzer
*
* \brief DipoleSplittingKinematics is the base class for dipole splittings
* as performed in the dipole shower.
*
* @see \ref DipoleSplittingKinematicsInterfaces "The interfaces"
* defined for DipoleSplittingKinematics.
*/
class DipoleSplittingKinematics: public HandlerBase {
public:
/** @name Standard constructors and destructors. */
//@{
/**
* The default constructor.
*/
DipoleSplittingKinematics();
/**
* The destructor.
*/
virtual ~DipoleSplittingKinematics();
//@}
public:
/**
* Return the boundaries in between the evolution
* variable random number is to be sampled; the lower
* cuoff is assumed to correspond to the infrared cutoff.
*/
- virtual pair<double,double> kappaSupport(const DipoleSplittingInfo& dIndex) const = 0;
+ virtual pair<double,double> kappaSupport(const DipoleSplittingInfo&) const {
+ return make_pair(0.0,1.0);
+ }
/**
* Return the boundaries in between the momentum
* fraction random number is to be sampled.
*/
- virtual pair<double,double> xiSupport(const DipoleSplittingInfo& dIndex) const = 0;
+ virtual pair<double,double> xiSupport(const DipoleSplittingInfo&) const {
+ return make_pair(0.0,1.0);
+ }
/**
* Return the dipole scale associated to the
* given pair of emitter and spectator. This
* should be the invariant mass or absolute value
* final/final or initial/initial and the absolute
* value of the momentum transfer for intial/final or
* final/initial dipoles.
*/
virtual Energy dipoleScale(const Lorentz5Momentum& pEmitter,
- const Lorentz5Momentum& pSpectator) const = 0;
+ const Lorentz5Momentum& pSpectator) const {
+ return sqrt(2.*pEmitter*pSpectator);
+ }
/**
* Return the maximum pt for the given dipole scale.
*/
virtual Energy ptMax(Energy dScale,
double emX, double specX,
const DipoleIndex& dIndex,
const DipoleSplittingKernel& split) const = 0;
/**
* Return the maximum virtuality for the given dipole scale.
*/
virtual Energy QMax(Energy dScale,
double emX, double specX,
- const DipoleIndex& dIndex) const = 0;
+ const DipoleIndex& dIndex,
+ const DipoleSplittingKernel& split) const = 0;
/**
* Return the pt given a virtuality.
*/
virtual Energy PtFromQ(Energy scale, const DipoleSplittingInfo&) const = 0;
/**
* Return the virtuality given a pt.
*/
virtual Energy QFromPt(Energy scale, const DipoleSplittingInfo&) const = 0;
/**
* Return the infrared cutoff.
*/
virtual Energy IRCutoff() const { return theIRCutoff; }
/**
* Return the minimum momentum fraction for
* incoming partons
*/
double xMin() const { return theXMin; }
/**
+ * Generate a pt
+ */
+ Energy generatePt(double r, Energy dScale,
+ double emX, double specX,
+ const DipoleIndex& dIndex,
+ const DipoleSplittingKernel& split,
+ double& weight) const;
+
+ /**
* Return the random number associated to
* the given pt.
*/
virtual double ptToRandom(Energy pt, Energy dScale,
- const DipoleIndex& dIndex) const = 0;
+ double emX, double specX,
+ const DipoleIndex& dIndex,
+ const DipoleSplittingKernel& split) const;
+
+ /**
+ * Return the boundaries on the momentum fraction
+ */
+ virtual pair<double,double> zBoundaries(Energy pt,
+ const DipoleSplittingInfo& dInfo,
+ const DipoleSplittingKernel& split) const = 0;
+
+ /**
+ * Enumerate the variants of sampling z
+ */
+ enum ZSamplingOptions {
+
+ FlatZ = 0,
+ OneOverZ,
+ OneOverOneMinusZ,
+ OneOverZOneMinusZ
+
+ };
+
+ /**
+ * Generate a z value flat
+ */
+ double generateZ(double r, Energy pt, int sampling,
+ const DipoleSplittingInfo& dInfo,
+ const DipoleSplittingKernel& split,
+ double& weight) const;
/**
* Generate splitting variables given three random numbers
* and the momentum fractions of the emitter and spectator.
* Return true on success.
*/
virtual bool generateSplitting(double kappa, double xi, double phi,
- DipoleSplittingInfo& dIndex) = 0;
-
- /**
- * For the splitting products present in the given dipole splitting
- * info object calculate the kinematics parameters and return the
- * propagator factor.
- */
- virtual InvEnergy2 setKinematics(DipoleSplittingInfo&) const = 0;
-
- /**
- * For the splitting parameters given in the dipole splitting info
- * object, calculate the phasespace Jacobian times the propagator
- * factor.
- */
- virtual double jacobianTimesPropagator(const DipoleSplittingInfo&,
- Energy) const = 0;
+ DipoleSplittingInfo& dIndex,
+ const DipoleSplittingKernel&) = 0;
/**
* Get the splitting phasespace weight associated to
* the last call to generateSplitting. This is taken to
* be the single particle phasespace times 16 \pi^2 divided
* by the relevant propagator invariant.
*/
double jacobian() const { return theJacobian; }
/**
* Return true, if this splitting kinematics
* class is capable of delivering an overestimate
* to the jacobian.
*/
virtual bool haveOverestimate() const { return false; }
/**
* Return the overestimated jacobian for the
* last generated parameters.
*/
virtual double jacobianOverestimate() const { return -1.; }
/**
* Return the last generated pt
*/
Energy lastPt() const { return theLastPt; }
/**
* Return the last generated momentum fraction.
*/
double lastZ() const { return theLastZ; }
/**
* Return the last generated azimuthal angle.
*/
double lastPhi() const { return theLastPhi; }
/**
* Return the momentum fraction, by which the emitter's
* momentum fraction should be divided after the splitting.
*/
double lastEmitterZ() const { return theLastEmitterZ; }
/**
* Return the momentum fraction, by which the spectator's
* momentum fraction should be divided after the splitting.
*/
double lastSpectatorZ() const { return theLastSpectatorZ; }
/**
* Return any additional parameters needed to
* evaluate the splitting kernel or to generate the
* full splitting.
*/
const vector<double>& lastSplittingParameters() const { return theLastSplittingParameters; }
/**
* Complete a DipoleSplittingInfo object with
* the parameters generated by the last call to
* generateSplitting()
*/
void prepareSplitting(DipoleSplittingInfo& dInfo);
public:
/**
* Generate the full kinematics given emitter and
* spectator momentum and a previously completeted
* DipoleSplittingInfo object.
*/
virtual void generateKinematics(const Lorentz5Momentum& pEmitter,
const Lorentz5Momentum& pSpectator,
const DipoleSplittingInfo& dInfo) = 0;
/**
* Return the emitter's momentum after the splitting.
*/
const Lorentz5Momentum& lastEmitterMomentum() const { return theEmitterMomentum; }
/**
* Return the spectator's momentum after the splitting.
*/
const Lorentz5Momentum& lastSpectatorMomentum() const { return theSpectatorMomentum; }
/**
* Return the emission's momentum.
*/
const Lorentz5Momentum& lastEmissionMomentum() const { return theEmissionMomentum; }
/*
* Return true, if there is a transformation which should
* be applied to all other final state particles except the ones
* involved in the splitting after having performed the splitting
*/
virtual bool doesTransform () const { return false; }
/*
* perform the transformation, if existing
*/
virtual Lorentz5Momentum transform (const Lorentz5Momentum& p) const { return p; }
protected:
/**
* Calculate a transverse momentum for the given momenta,
* invariant pt and azimuth.
*/
Lorentz5Momentum getKt(const Lorentz5Momentum& p1,
const Lorentz5Momentum& p2,
Energy pt,
double phi,
bool spacelike = false) const;
/**
* Set the splitting phasespace weight associated to
* the last call to generateSplitting. This is taken to
* be the single particle phasespace times 16 \pi^2 divided
* by the relevant propagator invariant.
*/
void jacobian(double w) { theJacobian = w; }
/**
* Set the last generated pt
*/
void lastPt(Energy p) { theLastPt = p; }
/**
* Set the last generated momentum fraction.
*/
void lastZ(double z) { theLastZ = z; }
/**
* Set the last generated azimuthal angle.
*/
void lastPhi(double p) { theLastPhi = p; }
/**
* Set the momentum fraction, by which the emitter's
* momentum fraction should be divided after the splitting.
*/
void lastEmitterZ(double z) { theLastEmitterZ = z; }
/**
* Set the momentum fraction, by which the spectator's
* momentum fraction should be divided after the splitting.
*/
void lastSpectatorZ(double z) { theLastSpectatorZ = z; }
/**
* Access any additional parameters needed to
* evaluate the splitting kernel or to generate the
* full splitting.
*/
vector<double>& splittingParameters() { return theLastSplittingParameters; }
/**
* Set the emitter's momentum after the splitting.
*/
void emitterMomentum(const Lorentz5Momentum& p) { theEmitterMomentum = p; }
/**
* Set the spectator's momentum after the splitting.
*/
void spectatorMomentum(const Lorentz5Momentum& p) { theSpectatorMomentum = p; }
/**
* Set the emission's momentum.
*/
void emissionMomentum(const Lorentz5Momentum& p) { theEmissionMomentum = p; }
public:
/**
* The standard Init function used to initialize the interfaces.
* Called exactly once for each class by the class description system
* before the main function starts or
* when this class is dynamically loaded.
*/
static void Init();
public:
/** @name Functions used by the persistent I/O system. */
//@{
/**
* Function used to write out object persistently.
* @param os the persistent output stream written to.
*/
void persistentOutput(PersistentOStream & os) const;
/**
* Function used to read in object persistently.
* @param is the persistent input stream read from.
* @param version the version number of the object when written.
*/
void persistentInput(PersistentIStream & is, int version);
//@}
// If needed, insert declarations of virtual function defined in the
// InterfacedBase class here (using ThePEG-interfaced-decl in Emacs).
private:
/**
* The infrared cutoff associated to this
* splitting kinematics.
*/
Energy theIRCutoff;
/**
* The minimum momentum fraction for
* incoming partons
*/
double theXMin;
/**
* The last calculated splitting phase space weight.
*/
double theJacobian;
/**
* The last generated pt
*/
Energy theLastPt;
/**
* The last generated momentum fraction.
*/
double theLastZ;
/**
* The last generated azimuthal angle.
*/
double theLastPhi;
/**
* The momentum fraction, by which the emitter's
* momentum fraction should be divided after the splitting.
*/
double theLastEmitterZ;
/**
* The momentum fraction, by which the spectator's
* momentum fraction should be divided after the splitting.
*/
double theLastSpectatorZ;
/**
* Any additional parameters needed to
* evaluate the splitting kernel or to generate the
* full splitting.
*/
vector<double> theLastSplittingParameters;
/**
* The emitter's momentum after the splitting.
*/
Lorentz5Momentum theEmitterMomentum;
/**
* The emission's momentum after the splitting.
*/
Lorentz5Momentum theEmissionMomentum;
/**
* The spectator's momentum after the splitting.
*/
Lorentz5Momentum theSpectatorMomentum;
protected:
/**
* Pointer to a check histogram object
*/
Ptr<DipoleMCCheck>::ptr theMCCheck;
private:
/**
* The static object used to initialize the description of this class.
* Indicates that this is an abstract class.
*/
static AbstractClassDescription<DipoleSplittingKinematics> initDipoleSplittingKinematics;
/**
* The assignment operator is private and must never be called.
* In fact, it should not even be implemented.
*/
DipoleSplittingKinematics & operator=(const DipoleSplittingKinematics &);
};
}
#include "ThePEG/Utilities/ClassTraits.h"
namespace ThePEG {
/** @cond TRAITSPECIALIZATIONS */
/** This template specialization informs ThePEG about the
* base classes of DipoleSplittingKinematics. */
template <>
struct BaseClassTrait<Herwig::DipoleSplittingKinematics,1> {
/** Typedef of the first base class of DipoleSplittingKinematics. */
typedef HandlerBase NthBase;
};
/** This template specialization informs ThePEG about the name of
* the DipoleSplittingKinematics class and the shared object where it is defined. */
template <>
struct ClassTraits<Herwig::DipoleSplittingKinematics>
: public ClassTraitsBase<Herwig::DipoleSplittingKinematics> {
/** Return a platform-independent class name */
static string className() { return "Herwig::DipoleSplittingKinematics"; }
/**
* The name of a file containing the dynamic library where the class
* DipoleSplittingKinematics is implemented. It may also include several, space-separated,
* libraries if the class DipoleSplittingKinematics depends on other classes (base classes
* excepted). In this case the listed libraries will be dynamically
* linked in the order they are specified.
*/
static string library() { return "HwDipoleShower.so"; }
};
/** @endcond */
}
#endif /* HERWIG_DipoleSplittingKinematics_H */
diff --git a/DipoleShower/Kinematics/FFLightKinematics.cc b/DipoleShower/Kinematics/FFLightKinematics.cc
--- a/DipoleShower/Kinematics/FFLightKinematics.cc
+++ b/DipoleShower/Kinematics/FFLightKinematics.cc
@@ -1,239 +1,173 @@
// -*- C++ -*-
//
// FFLightKinematics.cc is a part of Herwig++ - A multi-purpose Monte Carlo event generator
// Copyright (C) 2002-2007 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 FFLightKinematics class.
//
#include "FFLightKinematics.h"
#include "ThePEG/Interface/ClassDocumentation.h"
#include "ThePEG/Persistency/PersistentOStream.h"
#include "ThePEG/Persistency/PersistentIStream.h"
#include "ThePEG/Repository/UseRandom.h"
#include "ThePEG/Repository/EventGenerator.h"
#include "Herwig++/DipoleShower/Base/DipoleSplittingInfo.h"
using namespace Herwig;
FFLightKinematics::FFLightKinematics()
: DipoleSplittingKinematics() {}
FFLightKinematics::~FFLightKinematics() {}
IBPtr FFLightKinematics::clone() const {
return new_ptr(*this);
}
IBPtr FFLightKinematics::fullclone() const {
return new_ptr(*this);
}
-pair<double,double> FFLightKinematics::kappaSupport(const DipoleSplittingInfo&) const {
- return make_pair(0.0,1.0);
-}
-
-pair<double,double> FFLightKinematics::xiSupport(const DipoleSplittingInfo& split) const {
- double c = sqrt(1.-4.*sqr(IRCutoff()/generator()->maximumCMEnergy()));
- if ( split.index().emitterData()->id() == ParticleID::g ) {
- if ( split.emissionData()->id() != ParticleID::g )
- return make_pair(0.5*(1.-c),0.5*(1.+c));
- double b = log((1.+c)/(1.-c));
- return make_pair(-b,b);
- }
- return make_pair(-log(0.5*(1.+c)),-log(0.5*(1.-c)));
-}
-
-Energy FFLightKinematics::dipoleScale(const Lorentz5Momentum& pEmitter,
- const Lorentz5Momentum& pSpectator) const {
- return sqrt(2.*(pEmitter*pSpectator));
-}
-
Energy FFLightKinematics::ptMax(Energy dScale,
double, double,
const DipoleIndex&,
const DipoleSplittingKernel&) const {
return dScale/2.;
}
Energy FFLightKinematics::QMax(Energy dScale,
double, double,
- const DipoleIndex&) const {
+ const DipoleIndex&,
+ const DipoleSplittingKernel&) const {
return dScale;
}
Energy FFLightKinematics::PtFromQ(Energy scale, const DipoleSplittingInfo& split) const {
double z = split.lastZ();
return scale*sqrt(z*(1.-z));
}
Energy FFLightKinematics::QFromPt(Energy scale, const DipoleSplittingInfo& split) const {
double z = split.lastZ();
return scale/sqrt(z*(1.-z));
}
-double FFLightKinematics::ptToRandom(Energy pt, Energy,
- const DipoleIndex&) const {
- return log(pt/IRCutoff()) / log(0.5 * generator()->maximumCMEnergy()/IRCutoff());
+pair<double,double> FFLightKinematics::zBoundaries(Energy pt,
+ const DipoleSplittingInfo& dInfo,
+ const DipoleSplittingKernel&) const {
+ double s = sqrt(1.-sqr(pt/dInfo.hardPt()));
+ return make_pair(0.5*(1.-s),0.5*(1.+s));
}
bool FFLightKinematics::generateSplitting(double kappa, double xi, double rphi,
- DipoleSplittingInfo& info) {
+ DipoleSplittingInfo& info,
+ const DipoleSplittingKernel& split) {
- Energy pt = IRCutoff() * pow(0.5 * generator()->maximumCMEnergy()/IRCutoff(),kappa);
+ double weight = 1.0;
- if ( pt > info.hardPt() ) {
+ Energy pt = generatePt(kappa,info.scale(),
+ info.emitterX(),info.spectatorX(),
+ info.index(),split,
+ weight);
+
+ if ( pt < IRCutoff() || pt > info.hardPt() ) {
jacobian(0.0);
return false;
}
- double z;
- double mapZJacobian;
+ double z = 0.0;
if ( info.index().emitterData()->id() == ParticleID::g ) {
if ( info.emissionData()->id() != ParticleID::g ) {
- z = xi;
- mapZJacobian = 1.;
+ z = generateZ(xi,pt,FlatZ,
+ info,split,weight);
} else {
- z = exp(xi)/(1.+exp(xi));
- mapZJacobian = z*(1.-z);
+ z = generateZ(xi,pt,OneOverZOneMinusZ,
+ info,split,weight);
}
} else {
- z = 1.-exp(-xi);
- mapZJacobian = 1.-z;
+ z = generateZ(xi,pt,OneOverOneMinusZ,
+ info,split,weight);
}
- double s = z*(1.-z);
- double zp = 0.5*(1.+sqrt(1.-sqr(pt/info.hardPt())));
- double zm = 0.5*(1.-sqrt(1.-sqr(pt/info.hardPt())));
+ double y = sqr(pt/info.scale())/(z*(1.-z));
- if ( pt < IRCutoff() ||
- pt > info.hardPt() ||
- z > zp || z < zm ) {
+ if ( z < 0.0 || z > 1.0 ||
+ y < 0.0 || y > 1.0 ) {
jacobian(0.0);
return false;
}
double phi = 2.*Constants::pi*rphi;
- jacobian( 2. * mapZJacobian * (1. - sqr(pt) / (s * sqr(info.scale())) ) *
- log(0.5 * generator()->maximumCMEnergy()/IRCutoff()) );
+ jacobian(weight*(1.-y));
lastPt(pt);
lastZ(z);
lastPhi(phi);
if ( theMCCheck )
theMCCheck->book(1.,1.,info.scale(),info.hardPt(),pt,z,jacobian());
return true;
}
-InvEnergy2 FFLightKinematics::setKinematics(DipoleSplittingInfo& split) const {
-
- Lorentz5Momentum emitter = split.splitEmitter()->momentum();
- Lorentz5Momentum emission = split.emission()->momentum();
- Lorentz5Momentum spectator = split.splitSpectator()->momentum();
-
- split.splittingKinematics(const_cast<FFLightKinematics*>(this));
-
- Energy2 scale = 2.*(emission*emitter + emission*spectator + emitter*spectator);
- split.scale(sqrt(scale));
-
- double y = 2.*emission*emitter / scale;
- double z = emitter*spectator / (emitter*spectator + emission*spectator);
-
- split.lastPt(split.scale() * sqrt(y*z*(1.-z)));
- split.lastZ(z);
-
- split.hardPt(split.lastPt());
-
- if ( split.hardPt() > IRCutoff() ) {
- split.continuesEvolving();
- } else {
- split.didStopEvolving();
- }
-
- return 1./(2.*(emitter*emission));
-
-}
-
-double FFLightKinematics::
-jacobianTimesPropagator(const DipoleSplittingInfo& split,
- Energy scale) const {
-
- Energy pt = split.lastPt();
- double z = split.lastZ();
- double s = z*(1.-z);
- double zp = 0.5*(1.+sqrt(1.-sqr(pt/split.hardPt())));
- double zm = 0.5*(1.-sqrt(1.-sqr(pt/split.hardPt())));
-
- if ( pt < IRCutoff() ||
- pt > split.hardPt() ||
- z > zp || z < zm ) {
- return 0.;
- }
-
- return (2.*scale/pt)*(1.-sqr(pt)/(s*sqr(scale)));
-
-}
-
-
void FFLightKinematics::generateKinematics(const Lorentz5Momentum& pEmitter,
const Lorentz5Momentum& pSpectator,
const DipoleSplittingInfo& dInfo) {
double z = dInfo.lastZ();
Energy pt = dInfo.lastPt();
double y = sqr(pt / (pEmitter+pSpectator).m()) / (z*(1.-z));
Lorentz5Momentum kt =
getKt(pEmitter, pSpectator, pt, dInfo.lastPhi());
Lorentz5Momentum em = z*pEmitter + y*(1.-z)*pSpectator + kt;
em.setMass(0.*GeV);
em.rescaleEnergy();
Lorentz5Momentum emm = (1.-z)*pEmitter + z*y*pSpectator - kt;
emm.setMass(0.*GeV);
emm.rescaleEnergy();
Lorentz5Momentum spe = (1.-y)*pSpectator;
spe.setMass(0.*GeV);
spe.rescaleEnergy();
emitterMomentum(em);
emissionMomentum(emm);
spectatorMomentum(spe);
}
// If needed, insert default implementations of function defined
// in the InterfacedBase class here (using ThePEG-interfaced-impl in Emacs).
void FFLightKinematics::persistentOutput(PersistentOStream & ) const {
}
void FFLightKinematics::persistentInput(PersistentIStream & , int) {
}
ClassDescription<FFLightKinematics> FFLightKinematics::initFFLightKinematics;
// Definition of the static class description member.
void FFLightKinematics::Init() {
static ClassDocumentation<FFLightKinematics> documentation
("FFLightKinematics implements massless splittings "
"off a final-final dipole.");
}
diff --git a/DipoleShower/Kinematics/FFLightKinematics.h b/DipoleShower/Kinematics/FFLightKinematics.h
--- a/DipoleShower/Kinematics/FFLightKinematics.h
+++ b/DipoleShower/Kinematics/FFLightKinematics.h
@@ -1,237 +1,200 @@
// -*- C++ -*-
//
// FFLightKinematics.h is a part of Herwig++ - A multi-purpose Monte Carlo event generator
// Copyright (C) 2002-2007 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.
//
#ifndef HERWIG_FFLightKinematics_H
#define HERWIG_FFLightKinematics_H
//
// This is the declaration of the FFLightKinematics class.
//
#include "DipoleSplittingKinematics.h"
namespace Herwig {
using namespace ThePEG;
/**
* \ingroup DipoleShower
* \author Simon Platzer
*
* \brief FFLightKinematics implements massless splittings
* off a final-final dipole.
*
*/
class FFLightKinematics: public DipoleSplittingKinematics {
public:
/** @name Standard constructors and destructors. */
//@{
/**
* The default constructor.
*/
FFLightKinematics();
/**
* The destructor.
*/
virtual ~FFLightKinematics();
//@}
public:
/**
- * Return the boundaries in between the evolution
- * variable random number is to be sampled; the lower
- * cuoff is assumed to correspond to the infrared cutoff.
- */
- virtual pair<double,double> kappaSupport(const DipoleSplittingInfo& dIndex) const;
-
- /**
- * Return the boundaries in between the momentum
- * fraction random number is to be sampled.
- */
- virtual pair<double,double> xiSupport(const DipoleSplittingInfo& dIndex) const;
-
- /**
- * Return the dipole scale associated to the
- * given pair of emitter and spectator. This
- * should be the invariant mass or absolute value
- * final/final or initial/initial and the absolute
- * value of the momentum transfer for intial/final or
- * final/initial dipoles.
- */
- virtual Energy dipoleScale(const Lorentz5Momentum& pEmitter,
- const Lorentz5Momentum& pSpectator) const;
-
- /**
* Return the maximum pt for the given dipole scale.
*/
virtual Energy ptMax(Energy dScale,
double emX, double specX,
const DipoleIndex& dIndex,
const DipoleSplittingKernel&) const;
/**
* Return the maximum virtuality for the given dipole scale.
*/
virtual Energy QMax(Energy dScale,
double emX, double specX,
- const DipoleIndex& dIndex) const;
+ const DipoleIndex& dIndex,
+ const DipoleSplittingKernel&) const;
/**
* Return the pt given a virtuality.
*/
virtual Energy PtFromQ(Energy scale, const DipoleSplittingInfo&) const;
/**
* Return the virtuality given a pt.
*/
virtual Energy QFromPt(Energy scale, const DipoleSplittingInfo&) const;
/**
- * Return the random number associated to
- * the given pt.
+ * Return the boundaries on the momentum fraction
*/
- virtual double ptToRandom(Energy pt, Energy dScale,
- const DipoleIndex& dIndex) const;
+ virtual pair<double,double> zBoundaries(Energy pt,
+ const DipoleSplittingInfo& dInfo,
+ const DipoleSplittingKernel& split) const;
/**
* Generate splitting variables given three random numbers
* and the momentum fractions of the emitter and spectator.
* Return true on success.
*/
virtual bool generateSplitting(double kappa, double xi, double phi,
- DipoleSplittingInfo& dIndex);
-
- /**
- * For the splitting products present in the given dipole splitting
- * info object calculate the kinematics parameters and return the
- * propagator factor.
- */
- virtual InvEnergy2 setKinematics(DipoleSplittingInfo&) const;
-
- /**
- * For the splitting parameters given in the dipole splitting info
- * object, calculate the phasespace Jacobian times the propagator
- * factor.
- */
- virtual double jacobianTimesPropagator(const DipoleSplittingInfo&,
- Energy) const;
+ DipoleSplittingInfo& dIndex,
+ const DipoleSplittingKernel&);
/**
* Generate the full kinematics given emitter and
* spectator momentum and a previously completeted
* DipoleSplittingInfo object.
*/
virtual void generateKinematics(const Lorentz5Momentum& pEmitter,
const Lorentz5Momentum& pSpectator,
const DipoleSplittingInfo& dInfo);
public:
/** @name Functions used by the persistent I/O system. */
//@{
/**
* Function used to write out object persistently.
* @param os the persistent output stream written to.
*/
void persistentOutput(PersistentOStream & os) const;
/**
* Function used to read in object persistently.
* @param is the persistent input stream read from.
* @param version the version number of the object when written.
*/
void persistentInput(PersistentIStream & is, int version);
//@}
/**
* The standard Init function used to initialize the interfaces.
* Called exactly once for each class by the class description system
* before the main function starts or
* when this class is dynamically loaded.
*/
static void Init();
protected:
/** @name Clone Methods. */
//@{
/**
* Make a simple clone of this object.
* @return a pointer to the new object.
*/
virtual IBPtr clone() const;
/** Make a clone of this object, possibly modifying the cloned object
* to make it sane.
* @return a pointer to the new object.
*/
virtual IBPtr fullclone() const;
//@}
// If needed, insert declarations of virtual function defined in the
// InterfacedBase class here (using ThePEG-interfaced-decl in Emacs).
private:
/**
* The static object used to initialize the description of this class.
* Indicates that this is a concrete class with persistent data.
*/
static ClassDescription<FFLightKinematics> initFFLightKinematics;
/**
* The assignment operator is private and must never be called.
* In fact, it should not even be implemented.
*/
FFLightKinematics & operator=(const FFLightKinematics &);
};
}
#include "ThePEG/Utilities/ClassTraits.h"
namespace ThePEG {
/** @cond TRAITSPECIALIZATIONS */
/** This template specialization informs ThePEG about the
* base classes of FFLightKinematics. */
template <>
struct BaseClassTrait<Herwig::FFLightKinematics,1> {
/** Typedef of the first base class of FFLightKinematics. */
typedef Herwig::DipoleSplittingKinematics NthBase;
};
/** This template specialization informs ThePEG about the name of
* the FFLightKinematics class and the shared object where it is defined. */
template <>
struct ClassTraits<Herwig::FFLightKinematics>
: public ClassTraitsBase<Herwig::FFLightKinematics> {
/** Return a platform-independent class name */
static string className() { return "Herwig::FFLightKinematics"; }
/**
* The name of a file containing the dynamic library where the class
* FFLightKinematics is implemented. It may also include several, space-separated,
* libraries if the class FFLightKinematics depends on other classes (base classes
* excepted). In this case the listed libraries will be dynamically
* linked in the order they are specified.
*/
static string library() { return "HwDipoleShower.so"; }
};
/** @endcond */
}
#endif /* HERWIG_FFLightKinematics_H */
diff --git a/DipoleShower/Kinematics/FFMassiveKinematics.cc b/DipoleShower/Kinematics/FFMassiveKinematics.cc
--- a/DipoleShower/Kinematics/FFMassiveKinematics.cc
+++ b/DipoleShower/Kinematics/FFMassiveKinematics.cc
@@ -1,379 +1,338 @@
// -*- C++ -*-
//
// FFMassiveKinematics.cc is a part of Herwig++ - A multi-purpose Monte Carlo event generator
// Copyright (C) 2002-2007 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 FFMassiveKinematics class.
//
#include "FFMassiveKinematics.h"
#include "ThePEG/Interface/ClassDocumentation.h"
#include "ThePEG/Persistency/PersistentOStream.h"
#include "ThePEG/Persistency/PersistentIStream.h"
#include "ThePEG/Repository/UseRandom.h"
#include "ThePEG/Repository/EventGenerator.h"
#include "Herwig++/DipoleShower/Base/DipoleSplittingInfo.h"
#include "Herwig++/DipoleShower/Kernels/DipoleSplittingKernel.h"
// TODO: remove after verification
// only for checking for NaN or inf
#include <gsl/gsl_math.h>
using namespace Herwig;
FFMassiveKinematics::FFMassiveKinematics()
: DipoleSplittingKinematics() {}
FFMassiveKinematics::~FFMassiveKinematics() {}
IBPtr FFMassiveKinematics::clone() const {
return new_ptr(*this);
}
IBPtr FFMassiveKinematics::fullclone() const {
return new_ptr(*this);
}
pair<double,double> FFMassiveKinematics::kappaSupport(const DipoleSplittingInfo&) const {
return make_pair(0.0,1.0);
}
pair<double,double> FFMassiveKinematics::xiSupport(const DipoleSplittingInfo& split) const {
double c = sqrt(1.-4.*sqr(IRCutoff()/generator()->maximumCMEnergy()));
if ( split.index().emitterData()->id() == ParticleID::g ) {
if ( split.emissionData()->id() != ParticleID::g )
return make_pair(0.5*(1.-c),0.5*(1.+c));
double b = log((1.+c)/(1.-c));
return make_pair(-b,b);
}
return make_pair(-log(0.5*(1.+c)),-log(0.5*(1.-c)));
}
Energy FFMassiveKinematics::dipoleScale(const Lorentz5Momentum& pEmitter,
const Lorentz5Momentum& pSpectator) const {
return (pEmitter+pSpectator).m();
}
Energy FFMassiveKinematics::ptMax(Energy dScale,
double, double,
const DipoleIndex& ind,
const DipoleSplittingKernel& split) const {
double mui2 = sqr( split.emitter(ind)->mass() / dScale );
double mu2 = sqr( split.emission(ind)->mass() / dScale );
double muj2 = sqr( split.spectator(ind)->mass() / dScale );
// stolen from generateSplitting
Energy ptmax = rootOfKallen( mui2, mu2, sqr(1.-sqrt(muj2)) ) /
( 2.-2.*sqrt(muj2) ) * dScale;
return ptmax > 0.*GeV ? ptmax : 0.*GeV;
}
Energy FFMassiveKinematics::QMax(Energy dScale,
double, double,
- const DipoleIndex& ind) const {
+ const DipoleIndex& ind,
+ const DipoleSplittingKernel&) const {
assert(false && "implementation missing");
double Muj = ind.spectatorData()->mass() / dScale;
return dScale * ( 1.-2.*Muj+sqr(Muj) );
}
// relict
Energy FFMassiveKinematics::PtFromQ(Energy, const DipoleSplittingInfo&) const {
assert(false && "implementation missing");
return 0.*GeV;
}
Energy FFMassiveKinematics::QFromPt(Energy, const DipoleSplittingInfo&) const {
assert(false && "implementation missing");
return 0.*GeV;
}
double FFMassiveKinematics::ptToRandom(Energy pt, Energy,
- const DipoleIndex&) const {
+ double,double,
+ const DipoleIndex&,
+ const DipoleSplittingKernel&) const {
return log(pt/IRCutoff()) / log(0.5 * generator()->maximumCMEnergy()/IRCutoff());
}
// own kinematics close to Dinsdale,Ternick,Weinzierl
bool FFMassiveKinematics::generateSplitting(double kappa, double xi, double rphi,
- DipoleSplittingInfo& info) {
+ DipoleSplittingInfo& info,
+ const DipoleSplittingKernel&) {
Energy pt = IRCutoff() * pow(0.5 * generator()->maximumCMEnergy()/IRCutoff(),kappa);
if ( pt > info.hardPt() || pt < IRCutoff() ) {
jacobian(0.0);
return false;
}
double z;
double mapZJacobian;
if ( info.index().emitterData()->id() == ParticleID::g ) {
if ( info.emissionData()->id() != ParticleID::g ) {
z = xi;
mapZJacobian = 1.;
} else {
z = exp(xi)/(1.+exp(xi));
mapZJacobian = z*(1.-z);
}
} else {
z = 1.-exp(-xi);
mapZJacobian = 1.-z;
}
// masses
double mui2 = sqr( info.emitterData()->mass() / info.scale() );
double mu2 = sqr( info.emissionData()->mass() / info.scale() );
double muj2 = sqr( info.spectatorData()->mass() / info.scale() );
double Mui2 = 0.;
if ( info.emitterData()->id() + info.emissionData()->id() == 0 ) Mui2 = 0.; // gluon
else Mui2 = mui2; // (anti)quark
double Muj2 = muj2;
// new: 2011-08-31
// 2011-11-08: this does happen
if( sqrt(mui2)+sqrt(mu2)+sqrt(muj2) > 1. ){
jacobian(0.0);
return false;
}
double bar = 1.-mui2-mu2-muj2;
double y = ( sqr( pt / info.scale() ) + sqr(1.-z)*mui2 + z*z*mu2 ) /
(z*(1.-z)*bar);
// do this here for simplicity
Energy ptmax1 = rootOfKallen( mui2, mu2, sqr(1.-sqrt(muj2)) ) /
( 2.-2.*sqrt(muj2) ) * info.scale();
Energy auxHardPt = ptmax1 > info.hardPt() ? info.hardPt() : ptmax1;
// 2011-11-09
assert(ptmax1>=info.hardPt());
// phasespace constraint to incorporate ptMax
double zp1 = ( 1.+mui2-mu2+muj2-2.*sqrt(muj2) +
rootOfKallen(mui2,mu2,sqr(1-sqrt(muj2))) *
sqrt( 1.-sqr(pt/auxHardPt) ) ) /
( 2.*sqr(1.-sqrt(muj2)) );
double zm1 = ( 1.+mui2-mu2+muj2-2.*sqrt(muj2) -
rootOfKallen(mui2,mu2,sqr(1-sqrt(muj2))) *
sqrt( 1.-sqr(pt/auxHardPt) ) ) /
( 2.*sqr(1.-sqrt(muj2)) );
if ( z > zp1 || z < zm1 ||
pt > auxHardPt) {
jacobian(0.0);
return false;
}
// kinematic phasespace boundaries for (y,z)
// same as in Dittmaier hep-ph/9904440v2 (equivalent to CS)
double ym = 2.*sqrt(mui2)*sqrt(mu2)/bar;
double yp = 1. - 2.*sqrt(muj2)*(1.-sqrt(muj2))/bar;
if ( y < ym || y > yp ) {
jacobian(0.0);
return false;
}
double zm = ( (2.*mui2+bar*y)*(1.-y) - sqrt(y*y-ym*ym)*sqrt(sqr(2.*muj2+bar-bar*y)-4.*muj2) ) /
( 2.*(1.-y)*(mui2+mu2+bar*y) );
double zp = ( (2.*mui2+bar*y)*(1.-y) + sqrt(y*y-ym*ym)*sqrt(sqr(2.*muj2+bar-bar*y)-4.*muj2) ) /
( 2.*(1.-y)*(mui2+mu2+bar*y) );
if ( z < zm || z > zp ) {
jacobian(0.0);
return false;
}
double phi = 2.*Constants::pi*rphi;
jacobian( 2. * mapZJacobian * (1.-y) *
log(0.5 * generator()->maximumCMEnergy()/IRCutoff()) *
bar / rootOfKallen(1.,Mui2,Muj2) );
lastPt(pt);
lastZ(z);
lastPhi(phi);
if ( theMCCheck )
theMCCheck->book(1.,1.,info.scale(),info.hardPt(),pt,z,jacobian());
return true;
}
-InvEnergy2 FFMassiveKinematics::setKinematics(DipoleSplittingInfo& split) const {
-
- // masses
- double mui2 = sqr( split.emitterData()->mass() / split.scale() );
- double mu2 = sqr( split.emissionData()->mass() / split.scale() );
- double muj2 = sqr( split.spectatorData()->mass() / split.scale() );
- double Mui2 = 0.;
- if ( split.emitterData()->id() + split.emissionData()->id() == 0 ) Mui2 = 0.; // gluon
- else Mui2 = mui2; // (anti)quark
-
- split.splittingKinematics(const_cast<FFMassiveKinematics*>(this));
-
- Lorentz5Momentum emitter = split.splitEmitter()->momentum();
- Lorentz5Momentum emission = split.emission()->momentum();
- Lorentz5Momentum spectator = split.splitSpectator()->momentum();
-
- Energy2 scale = (emitter+emission+spectator).m2();
- split.scale(sqrt(scale));
-
- double y = 2.*emission*emitter / scale / (1.-mui2-mu2-muj2);
- double z = emitter*spectator / (emitter*spectator + emission*spectator);
-
- split.lastPt( split.scale() * sqrt( y * (1.-mui2-mu2-muj2) * z*(1.-z) - sqr(1.-z)*mui2 - sqr(z)*mu2 ) );
- split.lastZ(z);
-
- split.hardPt(split.lastPt());
-
- if ( split.hardPt() > IRCutoff() ) {
- split.continuesEvolving();
- } else {
- split.didStopEvolving();
- }
-
- return 1./((emitter+emission).m2()-Mui2*sqr(split.scale()));
-
-}
-
-double FFMassiveKinematics::
-jacobianTimesPropagator(const DipoleSplittingInfo&,
- Energy) const {
- assert(false && "implementation missing");
- return 0.;
-}
-
-
// kinematics close to Dinsdale,Ternick,Weinzierl
// revised 2011-08-22
// revised 2011-11-06
void FFMassiveKinematics::generateKinematics(const Lorentz5Momentum& pEmitter,
const Lorentz5Momentum& pSpectator,
const DipoleSplittingInfo& dInfo) {
double z = dInfo.lastZ();
Energy pt = dInfo.lastPt();
// masses
double mui2 = sqr( dInfo.emitterData()->mass() / dInfo.scale() );
double mu2 = sqr( dInfo.emissionData()->mass() / dInfo.scale() );
double muj2 = sqr( dInfo.spectatorData()->mass() / dInfo.scale() );
double y = ( sqr( pt / dInfo.scale() ) + sqr(1.-z)*mui2 + z*z*mu2 ) /
(z*(1.-z)*(1.-mui2-mu2-muj2));
Energy2 sbar = sqr(dInfo.scale()) *(1.-mui2-mu2-muj2);
// CMF: particle energies
Energy Ei = ( sbar*(1.-(1.-z)*(1.-y)) + 2.*sqr(dInfo.scale())*mui2 ) / (2.*dInfo.scale());
Energy E = ( sbar*(1.- z *(1.-y)) + 2.*sqr(dInfo.scale())*mu2 ) / (2.*dInfo.scale());
Energy Ej = ( sbar*(1.- y ) + 2.*sqr(dInfo.scale())*muj2 ) / (2.*dInfo.scale());
// CMF: momenta in z-direction (axis of pEmitter & pSpectator)
Energy qi3 = (2.*Ei*Ej-z*(1.-y)*sbar ) / 2./sqrt(Ej*Ej-sqr(dInfo.scale())*muj2);
Energy q3 = (2.*E *Ej-(1.-z)*(1.-y)*sbar) / 2./sqrt(Ej*Ej-sqr(dInfo.scale())*muj2);
Energy qj3 = sqrt( sqr(Ej) - sqr(dInfo.scale())*muj2 );
// get z axis in the dipole's CMF which is parallel to pSpectator
Boost toCMF = (pEmitter+pSpectator).findBoostToCM();
Lorentz5Momentum pjAux = pSpectator; pjAux.boost(toCMF);
ThreeVector<double> pjAxis = pjAux.vect().unit();
// set the momenta in this special reference frame
// note that pt might in some cases differ from the physical pt!
// phi is defined exactly as in getKt
Energy ptResc = sqrt( sqr(Ei)-sqr(dInfo.scale())*mui2-sqr(qi3) );
Lorentz5Momentum em ( ptResc*cos(dInfo.lastPhi()), -ptResc*sin(dInfo.lastPhi()), qi3, Ei );
Lorentz5Momentum emm ( -ptResc*cos(dInfo.lastPhi()), ptResc*sin(dInfo.lastPhi()), q3, E );
Lorentz5Momentum spe ( 0.*GeV, 0.*GeV, qj3, Ej );
// output the mismatch between pt and physical pt
// ofstream output1("ptDiffOnPtAxis-uub-m.dat",ofstream::app);
// ofstream output2("ptDiffOnCosAxis-uub-m.dat",ofstream::app);
// if( abs(dInfo.spectatorData()->id())==5 && dInfo.emitterData()->id()+dInfo.emissionData()->id()==0 &&
// abs(dInfo.emitterData()->id())==1 ) {
// output1 << pt/dInfo.scale() << " " << abs(ptResc-pt)/(ptResc+pt) << " " << endl;
// output2 << em.vect().unit()*emm.vect().unit() << " " << abs(ptResc-pt)/(ptResc+pt) << " " << endl;
// }
// output1.close(); output2.close();
// rotate back
em.rotateUz (pjAxis);
emm.rotateUz(pjAxis);
spe.rotateUz(pjAxis);
// boost back
em.boost (-toCMF);
emm.boost(-toCMF);
spe.boost(-toCMF);
// mass shells, rescale energy
em.setMass(dInfo.scale()*sqrt(mui2));
em.rescaleEnergy();
emm.setMass(dInfo.scale()*sqrt(mu2));
emm.rescaleEnergy();
spe.setMass(dInfo.scale()*sqrt(muj2));
spe.rescaleEnergy();
// book
emitterMomentum(em);
emissionMomentum(emm);
spectatorMomentum(spe);
// TODO: remove
// 2011-11-09: never occurred
if(em.t()/GeV>=0. && emm.t()/GeV>=0. && spe.t()/GeV>=0.);
else cout << "FFMassiveKinematics::generateKinematics momenta corrupt" << endl;
// 2011-11-03 LEP run with full masses:
// x,y,t no problem
// z order > 5.e-7 happend 41 times in 10000 runs
// maximum was 2.5e-6
// double order=2.4e-6;
// Lorentz5Momentum pDif=em+emm+spe-pEmitter-pSpectator, pSum=em+emm+spe+pEmitter+pSpectator;
// if(abs(pDif.x()/(pSum.x()==ZERO ? 1.*GeV : pSum.x())) <order || (pDif-pSum).x()==ZERO);
// else cout << "FFMassiveKinematics::generateKinematics momenta corrupt: x " <<
// abs(pDif.x()/(pSum.x()==ZERO ? 1.*GeV : pSum.x())) << endl <<
// " " << em/GeV << " " << emm/GeV << " " << spe/GeV << endl <<
// " " << pEmitter/GeV << " " << pSpectator/GeV << endl;
// if(abs(pDif.y()/(pSum.y()==ZERO ? 1.*GeV : pSum.y())) <order || (pDif-pSum).y()==ZERO);
// else cout << "FFMassiveKinematics::generateKinematics momenta corrupt: y " <<
// abs(pDif.y()/(pSum.y()==ZERO ? 1.*GeV : pSum.y())) << endl;
// if(abs(pDif.z()/(pSum.z()==ZERO ? 1.*GeV : pSum.z())) <order | (pDif-pSum).z()==ZERO);
// else cout << "FFMassiveKinematics::generateKinematics momenta corrupt: z " <<
// abs(pDif.z()/(pSum.z()==ZERO ? 1.*GeV : pSum.z())) << endl <<
// " " << em/GeV << " " << emm/GeV << " " << spe/GeV << endl <<
// " " << pEmitter/GeV << " " << pSpectator/GeV << endl;
// if(abs(pDif.t()/(pSum.t()==ZERO ? 1.*GeV : pSum.t())) <order || (pDif-pSum).t()==ZERO);
// else cout << "FFMassiveKinematics::generateKinematics momenta corrupt: t " <<
// // abs(pDif.t()/(pSum.t()==ZERO ? 1.*GeV : pSum.t())) << endl;
// cout << endl;
}
// If needed, insert default implementations of function defined
// in the InterfacedBase class here (using ThePEG-interfaced-impl in Emacs).
void FFMassiveKinematics::persistentOutput(PersistentOStream & ) const {
}
void FFMassiveKinematics::persistentInput(PersistentIStream & , int) {
}
ClassDescription<FFMassiveKinematics> FFMassiveKinematics::initFFMassiveKinematics;
// Definition of the static class description member.
void FFMassiveKinematics::Init() {
static ClassDocumentation<FFMassiveKinematics> documentation
("FFMassiveKinematics implements massive splittings "
"off a final-final dipole.");
}
diff --git a/DipoleShower/Kinematics/FFMassiveKinematics.h b/DipoleShower/Kinematics/FFMassiveKinematics.h
--- a/DipoleShower/Kinematics/FFMassiveKinematics.h
+++ b/DipoleShower/Kinematics/FFMassiveKinematics.h
@@ -1,263 +1,261 @@
// -*- C++ -*-
//
// FFMassiveKinematics.h is a part of Herwig++ - A multi-purpose Monte Carlo event generator
// Copyright (C) 2002-2007 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.
//
#ifndef HERWIG_FFMassiveKinematics_H
#define HERWIG_FFMassiveKinematics_H
//
// This is the declaration of the FFMassiveKinematics class.
//
#include "DipoleSplittingKinematics.h"
namespace Herwig {
using namespace ThePEG;
/**
* \ingroup DipoleShower
* \author Simon Platzer
*
* \brief FFMassiveKinematics implements massive splittings
* off a final-final dipole.
*
*/
class FFMassiveKinematics: public DipoleSplittingKinematics {
public:
/** @name Standard constructors and destructors. */
//@{
/**
* The default constructor.
*/
FFMassiveKinematics();
/**
* The destructor.
*/
virtual ~FFMassiveKinematics();
//@}
public:
/**
* Return the boundaries in between the evolution
* variable random number is to be sampled; the lower
* cuoff is assumed to correspond to the infrared cutoff.
*/
virtual pair<double,double> kappaSupport(const DipoleSplittingInfo& dIndex) const;
/**
* Return the boundaries in between the momentum
* fraction random number is to be sampled.
*/
virtual pair<double,double> xiSupport(const DipoleSplittingInfo& dIndex) const;
/**
+ * Return the boundaries on the momentum fraction
+ */
+ virtual pair<double,double> zBoundaries(Energy,
+ const DipoleSplittingInfo&,
+ const DipoleSplittingKernel&) const {
+ return make_pair(0.0,1.0);
+ }
+
+ /**
* Return the dipole scale associated to the
* given pair of emitter and spectator. This
* should be the invariant mass or absolute value
* final/final or initial/initial and the absolute
* value of the momentum transfer for intial/final or
* final/initial dipoles.
*/
virtual Energy dipoleScale(const Lorentz5Momentum& pEmitter,
const Lorentz5Momentum& pSpectator) const;
/**
* Return the maximum pt for the given dipole scale.
*/
virtual Energy ptMax(Energy dScale,
double emX, double specX,
const DipoleIndex& ind,
const DipoleSplittingKernel& split) const;
/**
* Return the maximum virtuality for the given dipole scale.
*/
virtual Energy QMax(Energy dScale,
double emX, double specX,
- const DipoleIndex& dIndex) const;
+ const DipoleIndex& dIndex,
+ const DipoleSplittingKernel& split) const;
/**
* Return the pt given a virtuality.
*/
virtual Energy PtFromQ(Energy scale, const DipoleSplittingInfo&) const;
/**
* Return the virtuality given a pt.
*/
virtual Energy QFromPt(Energy scale, const DipoleSplittingInfo&) const;
/**
* Return the random number associated to
* the given pt.
*/
virtual double ptToRandom(Energy pt, Energy dScale,
- const DipoleIndex& dIndex) const;
+ double emX, double specX,
+ const DipoleIndex& dIndex,
+ const DipoleSplittingKernel& split) const;
/**
* Generate splitting variables given three random numbers
* and the momentum fractions of the emitter and spectator.
* Return true on success.
*/
virtual bool generateSplitting(double kappa, double xi, double phi,
- DipoleSplittingInfo& dIndex);
-
- /**
- * For the splitting products present in the given dipole splitting
- * info object calculate the kinematics parameters and return the
- * propagator factor.
- */
- virtual InvEnergy2 setKinematics(DipoleSplittingInfo&) const;
-
- /**
- * For the splitting parameters given in the dipole splitting info
- * object, calculate the phasespace Jacobian times the propagator
- * factor.
- */
- virtual double jacobianTimesPropagator(const DipoleSplittingInfo&,
- Energy) const;
+ DipoleSplittingInfo& dIndex,
+ const DipoleSplittingKernel& split);
/**
* Generate the full kinematics given emitter and
* spectator momentum and a previously completeted
* DipoleSplittingInfo object.
*/
virtual void generateKinematics(const Lorentz5Momentum& pEmitter,
const Lorentz5Momentum& pSpectator,
const DipoleSplittingInfo& dInfo);
public:
/**
* Triangular / Kallen function
*/
template <class T>
inline double rootOfKallen (T a, T b, T c) const {
return sqrt( a*a + b*b + c*c - 2.*( a*b+a*c+b*c ) ); }
/**
* Perform a rotation on both momenta such that the first one will
* point along the (positive) z axis. Rotate back to the original
* reference frame by applying rotateUz(returnedVector) to each momentum.
*/
ThreeVector<double> rotateToZ (Lorentz5Momentum& pTarget, Lorentz5Momentum& p1){
ThreeVector<double> oldAxis = pTarget.vect().unit();
double ct = oldAxis.z(); double st = sqrt( 1.-sqr(ct) ); // cos,sin(theta)
double cp = oldAxis.x()/st; double sp = oldAxis.y()/st; // cos,sin(phi)
pTarget.setZ( pTarget.vect().mag() ); pTarget.setX( 0.*GeV ); pTarget.setY( 0.*GeV );
Lorentz5Momentum p1old = p1;
p1.setX( sp*p1old.x() - cp*p1old.y() );
p1.setY( ct*cp*p1old.x() + ct*sp*p1old.y() - st*p1old.z() );
p1.setZ( st*cp*p1old.x() + st*sp*p1old.y() + ct*p1old.z() );
return oldAxis;
}
public:
/** @name Functions used by the persistent I/O system. */
//@{
/**
* Function used to write out object persistently.
* @param os the persistent output stream written to.
*/
void persistentOutput(PersistentOStream & os) const;
/**
* Function used to read in object persistently.
* @param is the persistent input stream read from.
* @param version the version number of the object when written.
*/
void persistentInput(PersistentIStream & is, int version);
//@}
/**
* The standard Init function used to initialize the interfaces.
* Called exactly once for each class by the class description system
* before the main function starts or
* when this class is dynamically loaded.
*/
static void Init();
protected:
/** @name Clone Methods. */
//@{
/**
* Make a simple clone of this object.
* @return a pointer to the new object.
*/
virtual IBPtr clone() const;
/** Make a clone of this object, possibly modifying the cloned object
* to make it sane.
* @return a pointer to the new object.
*/
virtual IBPtr fullclone() const;
//@}
// If needed, insert declarations of virtual function defined in the
// InterfacedBase class here (using ThePEG-interfaced-decl in Emacs).
private:
/**
* The static object used to initialize the description of this class.
* Indicates that this is a concrete class with persistent data.
*/
static ClassDescription<FFMassiveKinematics> initFFMassiveKinematics;
/**
* The assignment operator is private and must never be called.
* In fact, it should not even be implemented.
*/
FFMassiveKinematics & operator=(const FFMassiveKinematics &);
};
}
#include "ThePEG/Utilities/ClassTraits.h"
namespace ThePEG {
/** @cond TRAITSPECIALIZATIONS */
/** This template specialization informs ThePEG about the
* base classes of FFMassiveKinematics. */
template <>
struct BaseClassTrait<Herwig::FFMassiveKinematics,1> {
/** Typedef of the first base class of FFMassiveKinematics. */
typedef Herwig::DipoleSplittingKinematics NthBase;
};
/** This template specialization informs ThePEG about the name of
* the FFMassiveKinematics class and the shared object where it is defined. */
template <>
struct ClassTraits<Herwig::FFMassiveKinematics>
: public ClassTraitsBase<Herwig::FFMassiveKinematics> {
/** Return a platform-independent class name */
static string className() { return "Herwig::FFMassiveKinematics"; }
/**
* The name of a file containing the dynamic library where the class
* FFMassiveKinematics is implemented. It may also include several, space-separated,
* libraries if the class FFMassiveKinematics depends on other classes (base classes
* excepted). In this case the listed libraries will be dynamically
* linked in the order they are specified.
*/
static string library() { return "HwDipoleShower.so"; }
};
/** @endcond */
}
#endif /* HERWIG_FFMassiveKinematics_H */
diff --git a/DipoleShower/Kinematics/FILightKinematics.cc b/DipoleShower/Kinematics/FILightKinematics.cc
--- a/DipoleShower/Kinematics/FILightKinematics.cc
+++ b/DipoleShower/Kinematics/FILightKinematics.cc
@@ -1,242 +1,180 @@
// -*- C++ -*-
//
// FILightKinematics.cc is a part of Herwig++ - A multi-purpose Monte Carlo event generator
// Copyright (C) 2002-2007 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 FILightKinematics class.
//
#include "FILightKinematics.h"
#include "ThePEG/Interface/ClassDocumentation.h"
#include "ThePEG/Persistency/PersistentOStream.h"
#include "ThePEG/Persistency/PersistentIStream.h"
#include "ThePEG/Repository/UseRandom.h"
#include "ThePEG/Repository/EventGenerator.h"
#include "Herwig++/DipoleShower/Base/DipoleSplittingInfo.h"
using namespace Herwig;
FILightKinematics::FILightKinematics()
: DipoleSplittingKinematics() {}
FILightKinematics::~FILightKinematics() {}
IBPtr FILightKinematics::clone() const {
return new_ptr(*this);
}
IBPtr FILightKinematics::fullclone() const {
return new_ptr(*this);
}
-pair<double,double> FILightKinematics::kappaSupport(const DipoleSplittingInfo&) const {
- return make_pair(0.0,1.0);
-}
-
-pair<double,double> FILightKinematics::xiSupport(const DipoleSplittingInfo& split) const {
- double c = sqrt(1.-4.*sqr(IRCutoff()/generator()->maximumCMEnergy()));
- if ( split.index().emitterData()->id() == ParticleID::g ) {
- if ( split.emissionData()->id() != ParticleID::g )
- return make_pair(0.5*(1.-c),0.5*(1.+c));
- double b = log((1.+c)/(1.-c));
- return make_pair(-b,b);
- }
- return make_pair(-log(0.5*(1.+c)),-log(0.5*(1.-c)));
-}
-
-Energy FILightKinematics::dipoleScale(const Lorentz5Momentum& pEmitter,
- const Lorentz5Momentum& pSpectator) const {
- return sqrt(2.*(pEmitter*pSpectator));
-}
-
Energy FILightKinematics::ptMax(Energy dScale,
double, double specX,
const DipoleIndex&,
const DipoleSplittingKernel&) const {
return dScale * sqrt((1.-specX)/specX) /2.;
}
Energy FILightKinematics::QMax(Energy dScale,
double, double specX,
- const DipoleIndex&) const {
+ const DipoleIndex&,
+ const DipoleSplittingKernel&) const {
return dScale * sqrt((1.-specX)/specX);
}
Energy FILightKinematics::PtFromQ(Energy scale, const DipoleSplittingInfo& split) const {
double z = split.lastZ();
return scale*sqrt(z*(1.-z));
}
Energy FILightKinematics::QFromPt(Energy scale, const DipoleSplittingInfo& split) const {
double z = split.lastZ();
return scale/sqrt(z*(1.-z));
}
-
-double FILightKinematics::ptToRandom(Energy pt, Energy,
- const DipoleIndex&) const {
- return log(pt/IRCutoff()) / log(0.5 * generator()->maximumCMEnergy()/IRCutoff());
+pair<double,double> FILightKinematics::zBoundaries(Energy pt,
+ const DipoleSplittingInfo& dInfo,
+ const DipoleSplittingKernel&) const {
+ double s = sqrt(1.-sqr(pt/dInfo.hardPt()));
+ return make_pair(0.5*(1.-s),0.5*(1.+s));
}
bool FILightKinematics::generateSplitting(double kappa, double xi, double rphi,
- DipoleSplittingInfo& info) {
+ DipoleSplittingInfo& info,
+ const DipoleSplittingKernel& split) {
if ( info.spectatorX() < xMin() ) {
jacobian(0.0);
return false;
}
- Energy pt = IRCutoff() * pow(0.5 * generator()->maximumCMEnergy()/IRCutoff(),kappa);
+ double weight = 1.0;
- if ( pt > info.hardPt() ) {
+ Energy pt = generatePt(kappa,info.scale(),
+ info.emitterX(),info.spectatorX(),
+ info.index(),split,
+ weight);
+
+ if ( pt < IRCutoff() || pt > info.hardPt() ) {
jacobian(0.0);
return false;
}
- double z;
- double mapZJacobian;
+ double z = 0.0;
if ( info.index().emitterData()->id() == ParticleID::g ) {
if ( info.emissionData()->id() != ParticleID::g ) {
- z = xi;
- mapZJacobian = 1.;
+ z = generateZ(xi,pt,FlatZ,
+ info,split,weight);
} else {
- z = exp(xi)/(1.+exp(xi));
- mapZJacobian = z*(1.-z);
+ z = generateZ(xi,pt,OneOverZOneMinusZ,
+ info,split,weight);
}
} else {
- z = 1.-exp(-xi);
- mapZJacobian = 1.-z;
+ z = generateZ(xi,pt,OneOverOneMinusZ,
+ info,split,weight);
}
- double s = z*(1.-z);
+ double x = 1./(1.+sqr(pt/info.scale())/(z*(1.-z)));
- double xs = info.spectatorX();
-
- double x = 1. / ( 1. + sqr(pt/info.scale()) / s );
-
- double zp = 0.5*(1.+sqrt(1.-sqr(pt/info.hardPt())));
- double zm = 0.5*(1.-sqrt(1.-sqr(pt/info.hardPt())));
-
- if ( pt < IRCutoff() ||
- pt > info.hardPt() ||
- z > zp || z < zm ||
- x < xs ) {
+ if ( z < 0.0 || z > 1.0 ||
+ x < info.spectatorX() || x > 1.0 ) {
jacobian(0.0);
return false;
}
double phi = 2.*Constants::pi*rphi;
- jacobian( 2. * mapZJacobian * log(0.5 * generator()->maximumCMEnergy()/IRCutoff()));
+ jacobian(weight);
lastPt(pt);
lastZ(z);
lastPhi(phi);
lastSpectatorZ(x);
if ( theMCCheck )
theMCCheck->book(1.,info.spectatorX(),info.scale(),info.hardPt(),pt,z,jacobian());
return true;
}
-InvEnergy2 FILightKinematics::setKinematics(DipoleSplittingInfo& split) const {
-
- Lorentz5Momentum emitter = split.splitEmitter()->momentum();
- Lorentz5Momentum emission = split.emission()->momentum();
- Lorentz5Momentum spectator = split.splitSpectator()->momentum();
-
- split.splittingKinematics(const_cast<FILightKinematics*>(this));
-
- Energy2 scale = 2.*(- emission*emitter + emission*spectator + emitter*spectator);
- split.scale(sqrt(scale));
-
- double x =
- scale / (2.*(emitter*spectator + emission*spectator));
- double z = emitter*spectator / (emitter*spectator + emission*spectator);
-
- split.lastPt(split.scale() * sqrt(z*(1.-z)*(1.-x)/x));
- split.lastZ(z);
-
- split.hardPt(split.lastPt());
-
- if ( split.hardPt() > IRCutoff() ) {
- split.continuesEvolving();
- } else {
- split.didStopEvolving();
- }
-
- return 1./(2.*x*(emitter*emission));
-
-}
-
-double FILightKinematics::
-jacobianTimesPropagator(const DipoleSplittingInfo&,
- Energy) const {
- assert(false && "implementation missing");
- return 0.;
-}
-
-
void FILightKinematics::generateKinematics(const Lorentz5Momentum& pEmitter,
const Lorentz5Momentum& pSpectator,
const DipoleSplittingInfo& dInfo) {
Energy pt = dInfo.lastPt();
double z = dInfo.lastZ();
+ double x = 1./(1.+sqr(pt/dInfo.scale())/(z*(1.-z)));
Lorentz5Momentum kt =
getKt (pSpectator, pEmitter, pt, dInfo.lastPhi(),true);
- double ratio = sqr(pt/(-(pEmitter-pSpectator).m()));
- double xInv = (1.+ratio/(z*(1.-z)));
-
- Lorentz5Momentum em = z*pEmitter + (ratio/z)*pSpectator + kt;
+ Lorentz5Momentum em = z*pEmitter + (1.-z)*((1.-x)/x)*pSpectator + kt;
em.setMass(0.*GeV);
em.rescaleEnergy();
- Lorentz5Momentum emm = (1.-z)*pEmitter + (ratio/(1.-z))*pSpectator - kt;
+ Lorentz5Momentum emm = (1.-z)*pEmitter + z*((1.-x)/x)*pSpectator - kt;
emm.setMass(0.*GeV);
emm.rescaleEnergy();
- Lorentz5Momentum spe = xInv*pSpectator;
+ Lorentz5Momentum spe = (1./x)*pSpectator;
spe.setMass(0.*GeV);
spe.rescaleEnergy();
emitterMomentum(em);
emissionMomentum(emm);
spectatorMomentum(spe);
}
// If needed, insert default implementations of function defined
// in the InterfacedBase class here (using ThePEG-interfaced-impl in Emacs).
void FILightKinematics::persistentOutput(PersistentOStream & ) const {
}
void FILightKinematics::persistentInput(PersistentIStream & , int) {
}
ClassDescription<FILightKinematics> FILightKinematics::initFILightKinematics;
// Definition of the static class description member.
void FILightKinematics::Init() {
static ClassDocumentation<FILightKinematics> documentation
("FILightKinematics implements massless splittings "
"off a final-initial dipole.");
}
diff --git a/DipoleShower/Kinematics/FILightKinematics.h b/DipoleShower/Kinematics/FILightKinematics.h
--- a/DipoleShower/Kinematics/FILightKinematics.h
+++ b/DipoleShower/Kinematics/FILightKinematics.h
@@ -1,237 +1,200 @@
// -*- C++ -*-
//
// FILightKinematics.h is a part of Herwig++ - A multi-purpose Monte Carlo event generator
// Copyright (C) 2002-2007 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.
//
#ifndef HERWIG_FILightKinematics_H
#define HERWIG_FILightKinematics_H
//
// This is the declaration of the FILightKinematics class.
//
#include "DipoleSplittingKinematics.h"
namespace Herwig {
using namespace ThePEG;
/**
* \ingroup DipoleShower
* \author Simon Platzer
*
* \brief FILightKinematics implements massless splittings
* off a final-initial dipole.
*
*/
class FILightKinematics: public DipoleSplittingKinematics {
public:
/** @name Standard constructors and destructors. */
//@{
/**
* The default constructor.
*/
FILightKinematics();
/**
* The destructor.
*/
virtual ~FILightKinematics();
//@}
public:
/**
- * Return the boundaries in between the evolution
- * variable random number is to be sampled; the lower
- * cuoff is assumed to correspond to the infrared cutoff.
- */
- virtual pair<double,double> kappaSupport(const DipoleSplittingInfo& dIndex) const;
-
- /**
- * Return the boundaries in between the momentum
- * fraction random number is to be sampled.
- */
- virtual pair<double,double> xiSupport(const DipoleSplittingInfo& dIndex) const;
-
- /**
- * Return the dipole scale associated to the
- * given pair of emitter and spectator. This
- * should be the invariant mass or absolute value
- * final/final or initial/initial and the absolute
- * value of the momentum transfer for intial/final or
- * final/initial dipoles.
- */
- virtual Energy dipoleScale(const Lorentz5Momentum& pEmitter,
- const Lorentz5Momentum& pSpectator) const;
-
- /**
* Return the maximum pt for the given dipole scale.
*/
virtual Energy ptMax(Energy dScale,
double emX, double specX,
const DipoleIndex& dIndex,
const DipoleSplittingKernel&) const;
/**
* Return the maximum virtuality for the given dipole scale.
*/
virtual Energy QMax(Energy dScale,
double emX, double specX,
- const DipoleIndex& dIndex) const;
+ const DipoleIndex& dIndex,
+ const DipoleSplittingKernel&) const;
/**
* Return the pt given a virtuality.
*/
virtual Energy PtFromQ(Energy scale, const DipoleSplittingInfo&) const;
/**
* Return the virtuality given a pt.
*/
virtual Energy QFromPt(Energy scale, const DipoleSplittingInfo&) const;
/**
- * Return the random number associated to
- * the given pt.
+ * Return the boundaries on the momentum fraction
*/
- virtual double ptToRandom(Energy pt, Energy dScale,
- const DipoleIndex& dIndex) const;
+ virtual pair<double,double> zBoundaries(Energy pt,
+ const DipoleSplittingInfo& dInfo,
+ const DipoleSplittingKernel& split) const;
/**
* Generate splitting variables given three random numbers
* and the momentum fractions of the emitter and spectator.
* Return true on success.
*/
virtual bool generateSplitting(double kappa, double xi, double phi,
- DipoleSplittingInfo& dIndex);
-
- /**
- * For the splitting products present in the given dipole splitting
- * info object calculate the kinematics parameters and return the
- * propagator factor.
- */
- virtual InvEnergy2 setKinematics(DipoleSplittingInfo&) const;
-
- /**
- * For the splitting parameters given in the dipole splitting info
- * object, calculate the phasespace Jacobian times the propagator
- * factor.
- */
- virtual double jacobianTimesPropagator(const DipoleSplittingInfo&,
- Energy) const;
+ DipoleSplittingInfo& dIndex,
+ const DipoleSplittingKernel&);
/**
* Generate the full kinematics given emitter and
* spectator momentum and a previously completeted
* DipoleSplittingInfo object.
*/
virtual void generateKinematics(const Lorentz5Momentum& pEmitter,
const Lorentz5Momentum& pSpectator,
const DipoleSplittingInfo& dInfo);
public:
/** @name Functions used by the persistent I/O system. */
//@{
/**
* Function used to write out object persistently.
* @param os the persistent output stream written to.
*/
void persistentOutput(PersistentOStream & os) const;
/**
* Function used to read in object persistently.
* @param is the persistent input stream read from.
* @param version the version number of the object when written.
*/
void persistentInput(PersistentIStream & is, int version);
//@}
/**
* The standard Init function used to initialize the interfaces.
* Called exactly once for each class by the class description system
* before the main function starts or
* when this class is dynamically loaded.
*/
static void Init();
protected:
/** @name Clone Methods. */
//@{
/**
* Make a simple clone of this object.
* @return a pointer to the new object.
*/
virtual IBPtr clone() const;
/** Make a clone of this object, possibly modifying the cloned object
* to make it sane.
* @return a pointer to the new object.
*/
virtual IBPtr fullclone() const;
//@}
// If needed, insert declarations of virtual function defined in the
// InterfacedBase class here (using ThePEG-interfaced-decl in Emacs).
private:
/**
* The static object used to initialize the description of this class.
* Indicates that this is a concrete class with persistent data.
*/
static ClassDescription<FILightKinematics> initFILightKinematics;
/**
* The assignment operator is private and must never be called.
* In fact, it should not even be implemented.
*/
FILightKinematics & operator=(const FILightKinematics &);
};
}
#include "ThePEG/Utilities/ClassTraits.h"
namespace ThePEG {
/** @cond TRAITSPECIALIZATIONS */
/** This template specialization informs ThePEG about the
* base classes of FILightKinematics. */
template <>
struct BaseClassTrait<Herwig::FILightKinematics,1> {
/** Typedef of the first base class of FILightKinematics. */
typedef Herwig::DipoleSplittingKinematics NthBase;
};
/** This template specialization informs ThePEG about the name of
* the FILightKinematics class and the shared object where it is defined. */
template <>
struct ClassTraits<Herwig::FILightKinematics>
: public ClassTraitsBase<Herwig::FILightKinematics> {
/** Return a platform-independent class name */
static string className() { return "Herwig::FILightKinematics"; }
/**
* The name of a file containing the dynamic library where the class
* FILightKinematics is implemented. It may also include several, space-separated,
* libraries if the class FILightKinematics depends on other classes (base classes
* excepted). In this case the listed libraries will be dynamically
* linked in the order they are specified.
*/
static string library() { return "HwDipoleShower.so"; }
};
/** @endcond */
}
#endif /* HERWIG_FILightKinematics_H */
diff --git a/DipoleShower/Kinematics/FIMassiveKinematics.cc b/DipoleShower/Kinematics/FIMassiveKinematics.cc
--- a/DipoleShower/Kinematics/FIMassiveKinematics.cc
+++ b/DipoleShower/Kinematics/FIMassiveKinematics.cc
@@ -1,309 +1,268 @@
// -*- C++ -*-
//
// FIMassiveKinematics.cc is a part of Herwig++ - A multi-purpose Monte Carlo event generator
// Copyright (C) 2002-2007 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 FIMassiveKinematics class.
//
#include "FIMassiveKinematics.h"
#include "ThePEG/Interface/ClassDocumentation.h"
#include "ThePEG/Persistency/PersistentOStream.h"
#include "ThePEG/Persistency/PersistentIStream.h"
#include "ThePEG/Repository/UseRandom.h"
#include "ThePEG/Repository/EventGenerator.h"
#include "Herwig++/DipoleShower/Base/DipoleSplittingInfo.h"
#include "Herwig++/DipoleShower/Kernels/DipoleSplittingKernel.h"
using namespace Herwig;
FIMassiveKinematics::FIMassiveKinematics()
: DipoleSplittingKinematics() {}
FIMassiveKinematics::~FIMassiveKinematics() {}
IBPtr FIMassiveKinematics::clone() const {
return new_ptr(*this);
}
IBPtr FIMassiveKinematics::fullclone() const {
return new_ptr(*this);
}
pair<double,double> FIMassiveKinematics::kappaSupport(const DipoleSplittingInfo&) const {
return make_pair(0.0,1.0);
}
pair<double,double> FIMassiveKinematics::xiSupport(const DipoleSplittingInfo& split) const {
double c = sqrt(1.-4.*sqr(IRCutoff()/generator()->maximumCMEnergy()));
if ( split.index().emitterData()->id() == ParticleID::g ) {
if ( split.emissionData()->id() != ParticleID::g )
return make_pair(0.5*(1.-c),0.5*(1.+c));
double b = log((1.+c)/(1.-c));
return make_pair(-b,b);
}
return make_pair(-log(0.5*(1.+c)),-log(0.5*(1.-c)));
}
// sbar
Energy FIMassiveKinematics::dipoleScale(const Lorentz5Momentum& pEmitter,
const Lorentz5Momentum& pSpectator) const {
return sqrt(2.*(pEmitter*pSpectator));
}
Energy FIMassiveKinematics::ptMax(Energy dScale,
double, double specX,
const DipoleIndex& ind,
const DipoleSplittingKernel& split) const {
Energy2 mi2 = sqr(split.emitter(ind)->mass());
Energy2 m2 = sqr(split.emission(ind)->mass());
// Energy2 Mi2 = split.emitter(int)->id() + split.emission(int)->id() == 0 ?
// 0.*GeV2 : mi2;
Energy2 Mi2 = mi2 == m2 ? 0.*GeV2 : mi2;
// s^star/x
Energy2 s = sqr(dScale) * (1.-specX)/specX + Mi2;
Energy ptmax = .5 * sqrt(s) * rootOfKallen( s/s, mi2/s, m2/s );
return ptmax > 0.*GeV ? ptmax : 0.*GeV;
}
// what is this? in FF it is given by y+*dScale = sqrt( 2qi*q / bar )->max
Energy FIMassiveKinematics::QMax(Energy dScale,
double, double specX,
- const DipoleIndex&) const {
+ const DipoleIndex&,
+ const DipoleSplittingKernel&) const {
assert(false && "implementation missing");
cout << "FIMassiveKinematics::QMax called.\n" << flush;
// this is sqrt( 2qi*q ) -> max;
return dScale * sqrt((1.-specX)/specX);
}
Energy FIMassiveKinematics::PtFromQ(Energy, const DipoleSplittingInfo&) const {
assert(false && "add this");
return 0.0*GeV;
}
Energy FIMassiveKinematics::QFromPt(Energy, const DipoleSplittingInfo&) const {
assert(false && "add this");
return 0.0*GeV;
}
double FIMassiveKinematics::ptToRandom(Energy pt, Energy,
- const DipoleIndex&) const {
+ double,double,
+ const DipoleIndex&,
+ const DipoleSplittingKernel&) const {
return log(pt/IRCutoff()) / log(0.5 * generator()->maximumCMEnergy()/IRCutoff());
}
bool FIMassiveKinematics::generateSplitting(double kappa, double xi, double rphi,
- DipoleSplittingInfo& info) {
+ DipoleSplittingInfo& info,
+ const DipoleSplittingKernel&) {
if ( info.spectatorX() < xMin() ) {
jacobian(0.0);
return false;
}
Energy pt = IRCutoff() * pow(0.5 * generator()->maximumCMEnergy()/IRCutoff(),kappa);
if ( pt > info.hardPt() || pt < IRCutoff() ) {
jacobian(0.0);
return false;
}
double z;
double mapZJacobian;
if ( info.index().emitterData()->id() == ParticleID::g ) {
if ( info.emissionData()->id() != ParticleID::g ) {
z = xi;
mapZJacobian = 1.;
} else {
z = exp(xi)/(1.+exp(xi));
mapZJacobian = z*(1.-z);
}
} else {
z = 1.-exp(-xi);
mapZJacobian = 1.-z;
}
// double s = z*(1.-z);
// double xs = info.spectatorX();
// double x = 1. / ( 1. + sqr(pt/info.scale()) / s );
// double zp = 0.5*(1.+sqrt(1.-sqr(pt/info.hardPt())));
// double zm = 0.5*(1.-sqrt(1.-sqr(pt/info.hardPt())));
Energy2 mi2 = sqr(info.emitterData()->mass());
Energy2 m2 = sqr(info.emissionData()->mass());
Energy2 Mi2 = info.emitterData()->id()+info.emissionData()->id() == 0 ?
0.*GeV2 : mi2;
// s^star/x
Energy2 s = sqr(info.scale()) * (1.-info.spectatorX())/info.spectatorX() + Mi2;
double xs = info.spectatorX();
double x = 1. / ( 1. +
( sqr(pt) + (1.-z)*mi2 + z*m2 - z*(1.-z)*Mi2 ) /
( z*(1.-z)*s ) );
double zm1 = .5*( 1.+(mi2-m2)/s - rootOfKallen(s/s,mi2/s,m2/s) *
sqrt( 1.-sqr(pt/info.hardPt()) ) );
double zp1 = .5*( 1.+(mi2-m2)/s + rootOfKallen(s/s,mi2/s,m2/s) *
sqrt( 1.-sqr(pt/info.hardPt()) ) );
if ( // pt < IRCutoff() ||
// pt > info.hardPt() ||
z > zp1 || z < zm1 ||
x < xs ) {
jacobian(0.0);
return false;
}
// additional purely kinematic constraints
double mui2 = x*mi2/sqr(info.scale());
double mu2 = x*m2/sqr(info.scale());
double Mui2 = x*Mi2/sqr(info.scale());
double xp = 1. + Mui2 - sqr(sqrt(mui2)+sqrt(mu2));
double zm = .5*( 1.-x+Mui2+mui2-mui2 -
sqrt( sqr(1.-x+Mui2-mui2-mu2)-4.*mui2*mu2 ) ) /
(1.-x+Mui2);
double zp = .5*( 1.-x+Mui2+mui2-mui2 +
sqrt( sqr(1.-x+Mui2-mui2-mu2)-4.*mui2*mu2 ) ) /
(1.-x+Mui2);
if (x > xp ||
z > zp || z < zm ) {
jacobian(0.0);
return false;
}
double phi = 2.*Constants::pi*rphi;
jacobian( 2. * mapZJacobian * log(0.5 * generator()->maximumCMEnergy()/IRCutoff()));
lastPt(pt);
lastZ(z);
lastPhi(phi);
lastSpectatorZ(x);
if ( theMCCheck )
theMCCheck->book(1.,info.spectatorX(),info.scale(),info.hardPt(),pt,z,jacobian());
return true;
}
-InvEnergy2 FIMassiveKinematics::setKinematics(DipoleSplittingInfo& split) const {
-
- Energy2 mi2 = sqr(split.emitterData()->mass());
- Energy2 m2 = sqr(split.emissionData()->mass());
- Energy2 Mi2 = split.emitterData()->id() + split.emissionData()->id() == 0 ?
- 0.*GeV2 : mi2;
-
- Lorentz5Momentum emitter = split.splitEmitter()->momentum();
- Lorentz5Momentum emission = split.emission()->momentum();
- Lorentz5Momentum spectator = split.splitSpectator()->momentum();
-
- split.splittingKinematics(const_cast<FIMassiveKinematics*>(this));
-
- // sbar is the relevant scale
- // Energy2 scale = 2.*(- emission*emitter + emission*spectator + emitter*spectator);
- Energy2 scale = Mi2 - (emitter+emission-spectator).m2();
- split.scale(sqrt(scale));
-
- double x =
- scale / (2.*(emitter*spectator + emission*spectator));
- double z = emitter*spectator / (emitter*spectator + emission*spectator);
-
- split.lastPt( sqrt( z*(1.-z)*(1.-x)/x*scale -
- ((1.-z)*mi2+z*m2-z*(1.-z)*Mi2) ) );
- split.lastZ(z);
-
- split.hardPt(split.lastPt());
-
- if ( split.hardPt() > IRCutoff() ) {
- split.continuesEvolving();
- } else {
- split.didStopEvolving();
- }
-
- return 1./(2.*x*((emitter+emission).m2()-Mi2));
-
-}
-
-double FIMassiveKinematics::
-jacobianTimesPropagator(const DipoleSplittingInfo&,
- Energy) const {
- assert(false && "implementation missing");
- return 0.;
-}
-
void FIMassiveKinematics::generateKinematics(const Lorentz5Momentum& pEmitter,
const Lorentz5Momentum& pSpectator,
const DipoleSplittingInfo& dInfo) {
Energy pt = dInfo.lastPt();
double z = dInfo.lastZ();
Lorentz5Momentum kt =
getKt (pSpectator, pEmitter, pt, dInfo.lastPhi(),true);
Energy2 mi2 = sqr(dInfo.emitterData()->mass());
Energy2 m2 = sqr(dInfo.emissionData()->mass());
Energy2 Mi2 = dInfo.emitterData()->id() + dInfo.emissionData()->id() == 0 ?
0.*GeV2 : mi2;
double xInv = ( 1. +
(pt*pt+(1.-z)*mi2+z*m2-z*(1.-z)*Mi2) /
(z*(1.-z)*sqr(dInfo.scale())) );
Lorentz5Momentum em = z*pEmitter +
(sqr(pt)+mi2-z*z*Mi2)/(z*sqr(dInfo.scale()))*pSpectator + kt;
em.setMass(sqrt(mi2));
em.rescaleEnergy();
Lorentz5Momentum emm = (1.-z)*pEmitter +
(pt*pt+m2-sqr(1.-z)*Mi2)/((1.-z)*sqr(dInfo.scale()))*pSpectator - kt;
emm.setMass(sqrt(m2));
emm.rescaleEnergy();
Lorentz5Momentum spe = xInv*pSpectator;
spe.setMass(ZERO);
spe.rescaleEnergy();
emitterMomentum(em);
emissionMomentum(emm);
spectatorMomentum(spe);
}
// If needed, insert default implementations of function defined
// in the InterfacedBase class here (using ThePEG-interfaced-impl in Emacs).
void FIMassiveKinematics::persistentOutput(PersistentOStream & ) const {
}
void FIMassiveKinematics::persistentInput(PersistentIStream & , int) {
}
ClassDescription<FIMassiveKinematics> FIMassiveKinematics::initFIMassiveKinematics;
// Definition of the static class description member.
void FIMassiveKinematics::Init() {
static ClassDocumentation<FIMassiveKinematics> documentation
("FIMassiveKinematics implements massless splittings "
"off a final-initial dipole.");
}
diff --git a/DipoleShower/Kinematics/FIMassiveKinematics.h b/DipoleShower/Kinematics/FIMassiveKinematics.h
--- a/DipoleShower/Kinematics/FIMassiveKinematics.h
+++ b/DipoleShower/Kinematics/FIMassiveKinematics.h
@@ -1,246 +1,244 @@
// -*- C++ -*-
//
// FILightKinematics.h is a part of Herwig++ - A multi-purpose Monte Carlo event generator
// Copyright (C) 2002-2007 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.
//
#ifndef HERWIG_FILightKinematics_H
#define HERWIG_FILightKinematics_H
//
// This is the declaration of the FILightKinematics class.
//
#include "DipoleSplittingKinematics.h"
namespace Herwig {
using namespace ThePEG;
/**
* \ingroup DipoleShower
* \author Simon Platzer, Martin Stoll
*
* \brief FIMassiveKinematics implements massless splittings
* off a final-initial dipole.
*
*/
class FIMassiveKinematics: public DipoleSplittingKinematics {
public:
/** @name Standard constructors and destructors. */
//@{
/**
* The default constructor.
*/
FIMassiveKinematics();
/**
* The destructor.
*/
virtual ~FIMassiveKinematics();
//@}
public:
/**
* Return the boundaries in between the evolution
* variable random number is to be sampled; the lower
* cuoff is assumed to correspond to the infrared cutoff.
*/
virtual pair<double,double> kappaSupport(const DipoleSplittingInfo& dIndex) const;
/**
* Return the boundaries in between the momentum
* fraction random number is to be sampled.
*/
virtual pair<double,double> xiSupport(const DipoleSplittingInfo& dIndex) const;
/**
+ * Return the boundaries on the momentum fraction
+ */
+ virtual pair<double,double> zBoundaries(Energy,
+ const DipoleSplittingInfo&,
+ const DipoleSplittingKernel&) const {
+ return make_pair(0.0,1.0);
+ }
+
+ /**
* Return the dipole scale associated to the
* given pair of emitter and spectator. This
* should be the invariant mass or absolute value
* final/final or initial/initial and the absolute
* value of the momentum transfer for intial/final or
* final/initial dipoles.
*/
virtual Energy dipoleScale(const Lorentz5Momentum& pEmitter,
const Lorentz5Momentum& pSpectator) const;
/**
* Return the maximum pt for the given dipole scale.
*/
virtual Energy ptMax(Energy dScale,
double emX, double specX,
const DipoleIndex& dIndex,
const DipoleSplittingKernel&) const;
/**
* Return the maximum virtuality for the given dipole scale.
*/
virtual Energy QMax(Energy dScale,
double emX, double specX,
- const DipoleIndex& dIndex) const;
+ const DipoleIndex& dIndex,
+ const DipoleSplittingKernel&) const;
/**
* Return the pt given a virtuality.
*/
virtual Energy PtFromQ(Energy scale, const DipoleSplittingInfo&) const;
/**
* Return the virtuality given a pt.
*/
virtual Energy QFromPt(Energy scale, const DipoleSplittingInfo&) const;
/**
* Return the random number associated to
* the given pt.
*/
virtual double ptToRandom(Energy pt, Energy dScale,
- const DipoleIndex& dIndex) const;
+ double emX, double specX,
+ const DipoleIndex& dIndex,
+ const DipoleSplittingKernel&) const;
/**
* Generate splitting variables given three random numbers
* and the momentum fractions of the emitter and spectator.
* Return true on success.
*/
virtual bool generateSplitting(double kappa, double xi, double phi,
- DipoleSplittingInfo& dIndex);
-
- /**
- * For the splitting products present in the given dipole splitting
- * info object calculate the kinematics parameters and return the
- * propagator factor.
- */
- virtual InvEnergy2 setKinematics(DipoleSplittingInfo&) const;
-
- /**
- * For the splitting parameters given in the dipole splitting info
- * object, calculate the phasespace Jacobian times the propagator
- * factor.
- */
- virtual double jacobianTimesPropagator(const DipoleSplittingInfo&,
- Energy) const;
+ DipoleSplittingInfo& dIndex,
+ const DipoleSplittingKernel&);
/**
* Generate the full kinematics given emitter and
* spectator momentum and a previously completeted
* DipoleSplittingInfo object.
*/
virtual void generateKinematics(const Lorentz5Momentum& pEmitter,
const Lorentz5Momentum& pSpectator,
const DipoleSplittingInfo& dInfo);
public:
/**
* Triangular / Kallen function
*/
template <class T>
inline double rootOfKallen (T a, T b, T c) const {
return sqrt( a*a + b*b + c*c - 2.*( a*b+a*c+b*c ) ); }
public:
/** @name Functions used by the persistent I/O system. */
//@{
/**
* Function used to write out object persistently.
* @param os the persistent output stream written to.
*/
void persistentOutput(PersistentOStream & os) const;
/**
* Function used to read in object persistently.
* @param is the persistent input stream read from.
* @param version the version number of the object when written.
*/
void persistentInput(PersistentIStream & is, int version);
//@}
/**
* The standard Init function used to initialize the interfaces.
* Called exactly once for each class by the class description system
* before the main function starts or
* when this class is dynamically loaded.
*/
static void Init();
protected:
/** @name Clone Methods. */
//@{
/**
* Make a simple clone of this object.
* @return a pointer to the new object.
*/
virtual IBPtr clone() const;
/** Make a clone of this object, possibly modifying the cloned object
* to make it sane.
* @return a pointer to the new object.
*/
virtual IBPtr fullclone() const;
//@}
// If needed, insert declarations of virtual function defined in the
// InterfacedBase class here (using ThePEG-interfaced-decl in Emacs).
private:
/**
* The static object used to initialize the description of this class.
* Indicates that this is a concrete class with persistent data.
*/
static ClassDescription<FIMassiveKinematics> initFIMassiveKinematics;
/**
* The assignment operator is private and must never be called.
* In fact, it should not even be implemented.
*/
FIMassiveKinematics & operator=(const FIMassiveKinematics &);
};
}
#include "ThePEG/Utilities/ClassTraits.h"
namespace ThePEG {
/** @cond TRAITSPECIALIZATIONS */
/** This template specialization informs ThePEG about the
* base classes of FIMassiveKinematics. */
template <>
struct BaseClassTrait<Herwig::FIMassiveKinematics,1> {
/** Typedef of the first base class of FIMassiveKinematics. */
typedef Herwig::DipoleSplittingKinematics NthBase;
};
/** This template specialization informs ThePEG about the name of
* the FIMassiveKinematics class and the shared object where it is defined. */
template <>
struct ClassTraits<Herwig::FIMassiveKinematics>
: public ClassTraitsBase<Herwig::FIMassiveKinematics> {
/** Return a platform-independent class name */
static string className() { return "Herwig::FIMassiveKinematics"; }
/**
* The name of a file containing the dynamic library where the class
* FIMassiveKinematics is implemented. It may also include several, space-separated,
* libraries if the class FIMassiveKinematics depends on other classes (base classes
* excepted). In this case the listed libraries will be dynamically
* linked in the order they are specified.
*/
static string library() { return "HwDipoleShower.so"; }
};
/** @endcond */
}
#endif /* HERWIG_FIMassiveKinematics_H */
diff --git a/DipoleShower/Kinematics/IFLightKinematics.cc b/DipoleShower/Kinematics/IFLightKinematics.cc
--- a/DipoleShower/Kinematics/IFLightKinematics.cc
+++ b/DipoleShower/Kinematics/IFLightKinematics.cc
@@ -1,324 +1,248 @@
// -*- C++ -*-
//
// IFLightKinematics.cc is a part of Herwig++ - A multi-purpose Monte Carlo event generator
// Copyright (C) 2002-2007 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 IFLightKinematics class.
//
#include "IFLightKinematics.h"
#include "ThePEG/Interface/ClassDocumentation.h"
#include "ThePEG/Interface/Switch.h"
#include "ThePEG/Persistency/PersistentOStream.h"
#include "ThePEG/Persistency/PersistentIStream.h"
#include "ThePEG/Repository/UseRandom.h"
#include "ThePEG/Repository/EventGenerator.h"
#include "Herwig++/DipoleShower/Base/DipoleSplittingInfo.h"
using namespace Herwig;
IFLightKinematics::IFLightKinematics()
: DipoleSplittingKinematics(), theCollinearScheme(false) {}
IFLightKinematics::~IFLightKinematics() {}
IBPtr IFLightKinematics::clone() const {
return new_ptr(*this);
}
IBPtr IFLightKinematics::fullclone() const {
return new_ptr(*this);
}
-pair<double,double> IFLightKinematics::kappaSupport(const DipoleSplittingInfo&) const {
- return make_pair(0.0,1.0);
-}
-
-pair<double,double> IFLightKinematics::xiSupport(const DipoleSplittingInfo& split) const {
-
- double c = sqrt(1.-4.*sqr(IRCutoff()/generator()->maximumCMEnergy()));
-
- if ( split.index().emitterData()->id() == ParticleID::g ) {
- if ( split.emitterData()->id() == ParticleID::g ) {
- double b = log((1.+c)/(1.-c));
- return make_pair(-b,b);
- } else {
- return make_pair(log(0.5*(1.-c)),log(0.5*(1.+c)));
- }
- }
-
- if ( split.index().emitterData()->id() != ParticleID::g &&
- split.emitterData()->id() != ParticleID::g ) {
- return make_pair(-log(0.5*(1.+c)),-log(0.5*(1.-c)));
- }
-
- return make_pair(0.5*(1.-c),0.5*(1.+c));
-
-}
-
-Energy IFLightKinematics::dipoleScale(const Lorentz5Momentum& pEmitter,
- const Lorentz5Momentum& pSpectator) const {
- return sqrt(2.*(pEmitter*pSpectator));
-}
-
Energy IFLightKinematics::ptMax(Energy dScale,
double emX, double,
const DipoleIndex&,
const DipoleSplittingKernel&) const {
return dScale * sqrt((1.-emX)/emX) /2.;
}
Energy IFLightKinematics::QMax(Energy,
double, double,
- const DipoleIndex&) const {
+ const DipoleIndex&,
+ const DipoleSplittingKernel&) const {
assert(false && "add this");
return 0.0*GeV;
}
-Energy IFLightKinematics::PtFromQ(Energy, const DipoleSplittingInfo&) const {
- assert(false && "add this");
- return 0.0*GeV;
+Energy IFLightKinematics::PtFromQ(Energy scale, const DipoleSplittingInfo& split) const {
+ double z = split.lastZ();
+ return scale*sqrt(1.-z);
}
-Energy IFLightKinematics::QFromPt(Energy, const DipoleSplittingInfo&) const {
- assert(false && "add this");
- return 0.0*GeV;
+Energy IFLightKinematics::QFromPt(Energy scale, const DipoleSplittingInfo& split) const {
+ double z = split.lastZ();
+ return scale/sqrt(1.-z);
}
-
-double IFLightKinematics::ptToRandom(Energy pt, Energy,
- const DipoleIndex&) const {
- return log(pt/IRCutoff()) / log(0.5 * generator()->maximumCMEnergy()/IRCutoff());
+pair<double,double> IFLightKinematics::zBoundaries(Energy pt,
+ const DipoleSplittingInfo& dInfo,
+ const DipoleSplittingKernel&) const {
+ double x = dInfo.emitterX();
+ double s = sqrt(1.-sqr(pt/dInfo.hardPt()));
+ return make_pair(0.5*(1.+x-(1.-x)*s),0.5*(1.+x+(1.-x)*s));
}
+
bool IFLightKinematics::generateSplitting(double kappa, double xi, double rphi,
- DipoleSplittingInfo& info) {
+ DipoleSplittingInfo& info,
+ const DipoleSplittingKernel& split) {
if ( info.emitterX() < xMin() ) {
jacobian(0.0);
return false;
}
- Energy pt = IRCutoff() * pow(0.5 * generator()->maximumCMEnergy()/IRCutoff(),kappa);
+ double weight = 1.0;
- if ( sqr(pt) > sqr(info.hardPt())/(1.+4.*sqr(info.hardPt()/info.scale())) ) {
+ Energy pt = generatePt(kappa,info.scale(),
+ info.emitterX(),info.spectatorX(),
+ info.index(),split,
+ weight);
+
+ if ( pt < IRCutoff() || pt > info.hardPt() ) {
jacobian(0.0);
return false;
}
- double z = 0.;
- double mapZJacobian = 0.;
+ double z = 0.0;
if ( info.index().emitterData()->id() == ParticleID::g ) {
if ( info.emitterData()->id() == ParticleID::g ) {
- z = exp(xi)/(1.+exp(xi));
- mapZJacobian = z*(1.-z);
+ z = generateZ(xi,pt,OneOverZOneMinusZ,
+ info,split,weight);
} else {
- z = exp(xi);
- mapZJacobian = z;
+ z = generateZ(xi,pt,OneOverZ,
+ info,split,weight);
}
}
if ( info.index().emitterData()->id() != ParticleID::g ) {
if ( info.emitterData()->id() != ParticleID::g ) {
- z = 1.-exp(-xi);
- mapZJacobian = 1.-z;
+ z = generateZ(xi,pt,OneOverOneMinusZ,
+ info,split,weight);
} else {
- z = xi;
- mapZJacobian = 1.;
+ z = generateZ(xi,pt,FlatZ,
+ info,split,weight);
}
}
double ratio = sqr(pt/info.scale());
- double x = ( z*(1.-z) - ratio ) / ( 1. - z - ratio );
- double u = ratio/(1.-z);
-
- if ( x < 0. || x > 1. || u > 1. ) {
+ double rho = 1. - 4.*ratio*z*(1.-z)/(1.-z+ratio);
+ if ( rho < 0.0 ) {
jacobian(0.0);
return false;
}
- double xe = info.emitterX();
+ double x = 0.5*((1.-z+ratio)/ratio)*(1.+sqrt(rho));
+ double u = 0.5*((1.-z+ratio)/(1.-z))*(1.+sqrt(rho));
- double zpx = 0.5*( 1.+ xe +
- (1.-xe)*sqrt(1.-sqr(2.*pt/info.scale())/(1.-xe) ) );
- double zmx = 0.5*( 1.+ xe -
- (1.-xe)*sqrt(1.-sqr(2.*pt/info.scale())/(1.-xe) ) );
-
- double xq = sqr(pt/info.hardPt());
-
- double zpq = 0.5*( 1.+ xq +
- (1.-xq)*sqrt(1.-sqr(2.*pt/info.scale())/(1.-xq) ) );
- double zmq = 0.5*( 1.+ xq -
- (1.-xq)*sqrt(1.-sqr(2.*pt/info.scale())/(1.-xq) ) );
-
- double zp = min(zpx,zpq);
- double zm = max(zmx,zmq);
-
- if ( pt < IRCutoff() ||
- pt > info.hardPt() ||
- z > zp || z < zm ||
- x < xe ) {
+ if ( x < info.emitterX() || x > 1. ||
+ u < 0. || u > 1. ) {
jacobian(0.0);
return false;
}
double phi = 2.*Constants::pi*rphi;
- jacobian(2. * mapZJacobian * (1.-z)/(z*(1.-z)-ratio) * log(0.5 * generator()->maximumCMEnergy()/IRCutoff()));
+ jacobian(weight*(1./z));
lastPt(pt);
lastZ(z);
lastPhi(phi);
lastEmitterZ(x);
if ( theMCCheck )
theMCCheck->book(info.emitterX(),1.,info.scale(),info.hardPt(),pt,z,jacobian());
return true;
}
-InvEnergy2 IFLightKinematics::setKinematics(DipoleSplittingInfo& split) const {
-
- Lorentz5Momentum emitter = split.splitEmitter()->momentum();
- Lorentz5Momentum emission = split.emission()->momentum();
- Lorentz5Momentum spectator = split.splitSpectator()->momentum();
-
- split.splittingKinematics(const_cast<IFLightKinematics*>(this));
-
- Energy2 scale = 2.*(emission*emitter - emission*spectator + emitter*spectator);
- split.scale(sqrt(scale));
-
- double x =
- scale / (2.*(emitter*emission + emitter*spectator));
- double u = emitter*emission / (emitter*emission + emitter*spectator);
-
- split.lastPt(split.scale() * sqrt(u*(1.-u)*(1.-x)));
- split.lastZ(u+x*(1.-u));
-
- split.hardPt(split.lastPt());
-
- if ( split.hardPt() > IRCutoff() ) {
- split.continuesEvolving();
- } else {
- split.didStopEvolving();
- }
-
- return 1./(2.*x*(emitter*emission));
-
-}
-
-double IFLightKinematics::
-jacobianTimesPropagator(const DipoleSplittingInfo&,
- Energy) const {
- assert(false && "implementation missing");
- return 0.;
-}
-
void IFLightKinematics::generateKinematics(const Lorentz5Momentum& pEmitter,
const Lorentz5Momentum& pSpectator,
const DipoleSplittingInfo& dInfo) {
Energy pt = dInfo.lastPt();
- double ratio = sqr(pt/-(pEmitter-pSpectator).m());
double z = dInfo.lastZ();
- double x = (z*(1.-z)-ratio)/(1.-z-ratio);
- double u = ratio / (1.-z);
- pt = -(pEmitter-pSpectator).m()*sqrt(u*(1.-u)*(1.-x)/x);
+ double ratio = sqr(pt)/(2.*pEmitter*pSpectator);
+ double rho = 1. - 4.*ratio*z*(1.-z)/(1.-z+ratio);
+
+ double x = 0.5*((1.-z+ratio)/ratio)*(1.+sqrt(rho));
+ double u = 0.5*((1.-z+ratio)/(1.-z))*(1.+sqrt(rho));
Lorentz5Momentum kt =
getKt (pEmitter, pSpectator, pt, dInfo.lastPhi(),true);
Lorentz5Momentum em;
Lorentz5Momentum emm;
Lorentz5Momentum spe;
if ( !theCollinearScheme &&
x > u && (1.-x)/(x-u) < 1. ) {
em =
((1.-u)/(x-u))*pEmitter + ((u/x)*(1.-x)/(x-u))*pSpectator - kt/(x-u);
em.setMass(0.*GeV);
em.rescaleEnergy();
emm =
((1.-x)/(x-u))*pEmitter + ((u/x)*(1.-u)/(x-u))*pSpectator - kt/(x-u);
emm.setMass(0.*GeV);
emm.rescaleEnergy();
spe =
(1.-u/x)*pSpectator;
spe.setMass(0.*GeV);
spe.rescaleEnergy();
} else {
em = (1./x)*pEmitter;
emm = ((1.-x)*(1.-u)/x)*pEmitter + u*pSpectator + kt;
emm.setMass(0.*GeV);
emm.rescaleEnergy();
spe = ((1.-x)*u/x)*pEmitter + (1.-u)*pSpectator - kt;
spe.setMass(0.*GeV);
spe.rescaleEnergy();
}
emitterMomentum(em);
emissionMomentum(emm);
spectatorMomentum(spe);
}
// If needed, insert default implementations of function defined
// in the InterfacedBase class here (using ThePEG-interfaced-impl in Emacs).
void IFLightKinematics::persistentOutput(PersistentOStream & os) const {
os << theCollinearScheme;
}
void IFLightKinematics::persistentInput(PersistentIStream & is, int) {
is >> theCollinearScheme;
}
ClassDescription<IFLightKinematics> IFLightKinematics::initIFLightKinematics;
// Definition of the static class description member.
void IFLightKinematics::Init() {
static ClassDocumentation<IFLightKinematics> documentation
("IFLightKinematics implements massless splittings "
"off a initial-final dipole.");
static Switch<IFLightKinematics,bool> interfaceCollinearScheme
("CollinearScheme",
"[experimental] Switch on or off the collinear scheme",
&IFLightKinematics::theCollinearScheme, false, false, false);
static SwitchOption interfaceCollinearSchemeOn
(interfaceCollinearScheme,
"On",
"Switch on the collinear scheme.",
true);
static SwitchOption interfaceCollinearSchemeOff
(interfaceCollinearScheme,
"Off",
"Switch off the collinear scheme",
false);
interfaceCollinearScheme.rank(-1);
}
diff --git a/DipoleShower/Kinematics/IFLightKinematics.h b/DipoleShower/Kinematics/IFLightKinematics.h
--- a/DipoleShower/Kinematics/IFLightKinematics.h
+++ b/DipoleShower/Kinematics/IFLightKinematics.h
@@ -1,246 +1,209 @@
// -*- C++ -*-
//
// IFLightKinematics.h is a part of Herwig++ - A multi-purpose Monte Carlo event generator
// Copyright (C) 2002-2007 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.
//
#ifndef HERWIG_IFLightKinematics_H
#define HERWIG_IFLightKinematics_H
//
// This is the declaration of the IFLightKinematics class.
//
#include "DipoleSplittingKinematics.h"
namespace Herwig {
using namespace ThePEG;
/**
* \ingroup DipoleShower
* \author Simon Platzer
*
* \brief IFLightKinematics implements massless splittings
* off an initial-final dipole.
*
* @see \ref IFLightKinematicsInterfaces "The interfaces"
* defined for IFLightKinematics.
*/
class IFLightKinematics: public DipoleSplittingKinematics {
public:
/** @name Standard constructors and destructors. */
//@{
/**
* The default constructor.
*/
IFLightKinematics();
/**
* The destructor.
*/
virtual ~IFLightKinematics();
//@}
public:
/**
- * Return the boundaries in between the evolution
- * variable random number is to be sampled; the lower
- * cuoff is assumed to correspond to the infrared cutoff.
- */
- virtual pair<double,double> kappaSupport(const DipoleSplittingInfo& dIndex) const;
-
- /**
- * Return the boundaries in between the momentum
- * fraction random number is to be sampled.
- */
- virtual pair<double,double> xiSupport(const DipoleSplittingInfo& dIndex) const;
-
- /**
- * Return the dipole scale associated to the
- * given pair of emitter and spectator. This
- * should be the invariant mass or absolute value
- * final/final or initial/initial and the absolute
- * value of the momentum transfer for intial/final or
- * final/initial dipoles.
- */
- virtual Energy dipoleScale(const Lorentz5Momentum& pEmitter,
- const Lorentz5Momentum& pSpectator) const;
-
- /**
* Return the maximum pt for the given dipole scale.
*/
virtual Energy ptMax(Energy dScale,
double emX, double specX,
const DipoleIndex&,
const DipoleSplittingKernel&) const;
/**
* Return the maximum virtuality for the given dipole scale.
*/
virtual Energy QMax(Energy dScale,
double emX, double specX,
- const DipoleIndex& dIndex) const;
+ const DipoleIndex& dIndex,
+ const DipoleSplittingKernel&) const;
/**
* Return the pt given a virtuality.
*/
virtual Energy PtFromQ(Energy scale, const DipoleSplittingInfo&) const;
/**
* Return the virtuality given a pt.
*/
virtual Energy QFromPt(Energy scale, const DipoleSplittingInfo&) const;
/**
- * Return the random number associated to
- * the given pt.
+ * Return the boundaries on the momentum fraction
*/
- virtual double ptToRandom(Energy pt, Energy dScale,
- const DipoleIndex& dIndex) const;
+ virtual pair<double,double> zBoundaries(Energy pt,
+ const DipoleSplittingInfo& dInfo,
+ const DipoleSplittingKernel& split) const;
/**
* Generate splitting variables given three random numbers
* and the momentum fractions of the emitter and spectator.
* Return true on success.
*/
virtual bool generateSplitting(double kappa, double xi, double phi,
- DipoleSplittingInfo& dIndex);
-
- /**
- * For the splitting products present in the given dipole splitting
- * info object calculate the kinematics parameters and return the
- * propagator factor.
- */
- virtual InvEnergy2 setKinematics(DipoleSplittingInfo&) const;
-
- /**
- * For the splitting parameters given in the dipole splitting info
- * object, calculate the phasespace Jacobian times the propagator
- * factor.
- */
- virtual double jacobianTimesPropagator(const DipoleSplittingInfo&,
- Energy) const;
+ DipoleSplittingInfo& dIndex,
+ const DipoleSplittingKernel&);
/**
* Generate the full kinematics given emitter and
* spectator momentum and a previously completeted
* DipoleSplittingInfo object.
*/
virtual void generateKinematics(const Lorentz5Momentum& pEmitter,
const Lorentz5Momentum& pSpectator,
const DipoleSplittingInfo& dInfo);
public:
/** @name Functions used by the persistent I/O system. */
//@{
/**
* Function used to write out object persistently.
* @param os the persistent output stream written to.
*/
void persistentOutput(PersistentOStream & os) const;
/**
* Function used to read in object persistently.
* @param is the persistent input stream read from.
* @param version the version number of the object when written.
*/
void persistentInput(PersistentIStream & is, int version);
//@}
/**
* The standard Init function used to initialize the interfaces.
* Called exactly once for each class by the class description system
* before the main function starts or
* when this class is dynamically loaded.
*/
static void Init();
protected:
/** @name Clone Methods. */
//@{
/**
* Make a simple clone of this object.
* @return a pointer to the new object.
*/
virtual IBPtr clone() const;
/** Make a clone of this object, possibly modifying the cloned object
* to make it sane.
* @return a pointer to the new object.
*/
virtual IBPtr fullclone() const;
//@}
// If needed, insert declarations of virtual function defined in the
// InterfacedBase class here (using ThePEG-interfaced-decl in Emacs).
private:
/**
* The static object used to initialize the description of this class.
* Indicates that this is a concrete class with persistent data.
*/
static ClassDescription<IFLightKinematics> initIFLightKinematics;
/**
* The assignment operator is private and must never be called.
* In fact, it should not even be implemented.
*/
IFLightKinematics & operator=(const IFLightKinematics &);
private:
/**
* Wether or not to choose the `collinear' scheme
*/
bool theCollinearScheme;
};
}
#include "ThePEG/Utilities/ClassTraits.h"
namespace ThePEG {
/** @cond TRAITSPECIALIZATIONS */
/** This template specialization informs ThePEG about the
* base classes of IFLightKinematics. */
template <>
struct BaseClassTrait<Herwig::IFLightKinematics,1> {
/** Typedef of the first base class of IFLightKinematics. */
typedef Herwig::DipoleSplittingKinematics NthBase;
};
/** This template specialization informs ThePEG about the name of
* the IFLightKinematics class and the shared object where it is defined. */
template <>
struct ClassTraits<Herwig::IFLightKinematics>
: public ClassTraitsBase<Herwig::IFLightKinematics> {
/** Return a platform-independent class name */
static string className() { return "Herwig::IFLightKinematics"; }
/**
* The name of a file containing the dynamic library where the class
* IFLightKinematics is implemented. It may also include several, space-separated,
* libraries if the class IFLightKinematics depends on other classes (base classes
* excepted). In this case the listed libraries will be dynamically
* linked in the order they are specified.
*/
static string library() { return "HwDipoleShower.so"; }
};
/** @endcond */
}
#endif /* HERWIG_IFLightKinematics_H */
diff --git a/DipoleShower/Kinematics/IFMassiveKinematics.cc b/DipoleShower/Kinematics/IFMassiveKinematics.cc
--- a/DipoleShower/Kinematics/IFMassiveKinematics.cc
+++ b/DipoleShower/Kinematics/IFMassiveKinematics.cc
@@ -1,353 +1,318 @@
// -*- C++ -*-
//
// IFMassiveKinematics.cc is a part of Herwig++ - A multi-purpose Monte Carlo event generator
// Copyright (C) 2002-2007 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 IFMassiveKinematics class.
//
#include "IFMassiveKinematics.h"
#include "ThePEG/Interface/ClassDocumentation.h"
#include "ThePEG/Interface/Switch.h"
#include "ThePEG/Persistency/PersistentOStream.h"
#include "ThePEG/Persistency/PersistentIStream.h"
#include "ThePEG/Repository/UseRandom.h"
#include "ThePEG/Repository/EventGenerator.h"
#include "Herwig++/DipoleShower/Base/DipoleSplittingInfo.h"
using namespace Herwig;
IFMassiveKinematics::IFMassiveKinematics()
: DipoleSplittingKinematics(), theCollinearScheme(false) {}
IFMassiveKinematics::~IFMassiveKinematics() {}
IBPtr IFMassiveKinematics::clone() const {
return new_ptr(*this);
}
IBPtr IFMassiveKinematics::fullclone() const {
return new_ptr(*this);
}
pair<double,double> IFMassiveKinematics::kappaSupport(const DipoleSplittingInfo&) const {
return make_pair(0.0,1.0);
}
pair<double,double> IFMassiveKinematics::xiSupport(const DipoleSplittingInfo& split) const {
double c = sqrt(1.-4.*sqr(IRCutoff()/generator()->maximumCMEnergy()));
if ( split.index().emitterData()->id() == ParticleID::g ) {
if ( split.emitterData()->id() == ParticleID::g ) {
double b = log((1.+c)/(1.-c));
return make_pair(-b,b);
} else {
return make_pair(log(0.5*(1.-c)),log(0.5*(1.+c)));
}
}
if ( split.index().emitterData()->id() != ParticleID::g &&
split.emitterData()->id() != ParticleID::g ) {
return make_pair(-log(0.5*(1.+c)),-log(0.5*(1.-c)));
}
return make_pair(0.5*(1.-c),0.5*(1.+c));
}
// sbar
Energy IFMassiveKinematics::dipoleScale(const Lorentz5Momentum& pEmitter,
const Lorentz5Momentum& pSpectator) const {
return sqrt(2.*(pEmitter*pSpectator));
}
Energy IFMassiveKinematics::ptMax(Energy dScale,
double emX, double,
const DipoleIndex&,
const DipoleSplittingKernel&) const {
return dScale * sqrt(1.-emX) /2.;
}
Energy IFMassiveKinematics::QMax(Energy,
- double, double,
- const DipoleIndex&) const {
+ double, double,
+ const DipoleIndex&,
+ const DipoleSplittingKernel&) const {
assert(false && "add this");
return 0.0*GeV;
}
Energy IFMassiveKinematics::PtFromQ(Energy, const DipoleSplittingInfo&) const {
assert(false && "add this");
return 0.0*GeV;
}
Energy IFMassiveKinematics::QFromPt(Energy, const DipoleSplittingInfo&) const {
assert(false && "add this");
return 0.0*GeV;
}
double IFMassiveKinematics::ptToRandom(Energy pt, Energy,
- const DipoleIndex&) const {
+ double,double,
+ const DipoleIndex&,
+ const DipoleSplittingKernel&) const {
return log(pt/IRCutoff()) / log(0.5 * generator()->maximumCMEnergy()/IRCutoff());
}
bool IFMassiveKinematics::generateSplitting(double kappa, double xi, double rphi,
- DipoleSplittingInfo& info) {
+ DipoleSplittingInfo& info,
+ const DipoleSplittingKernel&) {
if ( info.emitterX() < xMin() ) {
jacobian(0.0);
return false;
}
Energy pt = IRCutoff() * pow(0.5 * generator()->maximumCMEnergy()/IRCutoff(),kappa);
if ( pt > info.hardPt() ) {
jacobian(0.0);
return false;
}
double z = 0.;
double mapZJacobian = 0.;
if ( info.index().emitterData()->id() == ParticleID::g ) {
if ( info.emitterData()->id() == ParticleID::g ) {
z = exp(xi)/(1.+exp(xi));
mapZJacobian = z*(1.-z);
} else {
z = exp(xi);
mapZJacobian = z;
}
}
if ( info.index().emitterData()->id() != ParticleID::g ) {
if ( info.emitterData()->id() != ParticleID::g ) {
z = 1.-exp(-xi);
mapZJacobian = 1.-z;
} else {
z = xi;
mapZJacobian = 1.;
}
}
double ratio = sqr(pt/info.scale());
double alpha = 1. - 2.*sqr(info.spectatorData()->mass()/info.scale());
double x = alpha == 1. ? ( z*(1.-z) - ratio ) / ( 1. - z - ratio ) :
( sqr(alpha)*ratio + 2.*z - alpha*(1.+z) +
alpha*sqrt( sqr(1.-z+alpha*ratio) - 4.*ratio*(1.-z) ) ) /
(2.*(1.-alpha));
double u = ( 1.-z + alpha*ratio -
sqrt( sqr(1.-z+alpha*ratio) - 4.*ratio*(1.-z) ) ) /
(2.*(1.-z));
// double x = ( z*(1.-z) - ratio ) / ( 1. - z - ratio );
// double u = ratio/(1.-z);
double up = (1.-x) /
( 1.-x + x*sqr(info.spectatorData()->mass()/info.scale()) );
if ( x < 0. || x > 1. || u > up ) {
jacobian(0.0);
return false;
}
double xe = info.emitterX();
double zp = 0.5*( alpha + xe - (alpha-1.)*xe +
alpha*(1.-xe)*sqrt(1.-sqr(pt/info.hardPt()) ) );
double zm = 0.5*( alpha + xe - (alpha-1.)*xe +
alpha*(1.-xe)*sqrt(1.-sqr(pt/info.hardPt()) ) );
if ( pt < IRCutoff() ||
pt > info.hardPt() ||
z > zp || z < zm ||
x < xe ) {
jacobian(0.0);
return false;
}
double phi = 2.*Constants::pi*rphi;
jacobian(2. * mapZJacobian / x * log(0.5 * generator()->maximumCMEnergy()/IRCutoff()) * (1.-u)/(1.-2.*u+u*u*alpha) );
lastPt(pt);
lastZ(z);
lastPhi(phi);
lastEmitterZ(x);
if ( theMCCheck )
theMCCheck->book(info.emitterX(),1.,info.scale(),info.hardPt(),pt,z,jacobian());
return true;
}
-InvEnergy2 IFMassiveKinematics::setKinematics(DipoleSplittingInfo& split) const {
-
- Lorentz5Momentum emitter = split.splitEmitter()->momentum();
- Lorentz5Momentum emission = split.emission()->momentum();
- Lorentz5Momentum spectator = split.splitSpectator()->momentum();
-
- split.splittingKinematics(const_cast<IFMassiveKinematics*>(this));
-
- // sbar
- Energy2 scale = 2.*(emission*emitter - emission*spectator + emitter*spectator);
- split.scale(sqrt(scale));
-
- double x =
- scale / (2.*(emitter*emission + emitter*spectator));
- double u = emitter*emission / (emitter*emission + emitter*spectator);
-
- split.lastPt(split.scale() * sqrt(u*(1.-u)*(1.-x)));
- split.lastZ( x+u*(1.-x) *
- ( 1. - 2.*sqr(split.spectatorData()->mass())/scale ) );
-
- split.hardPt(split.lastPt());
-
- if ( split.hardPt() > IRCutoff() ) {
- split.continuesEvolving();
- } else {
- split.didStopEvolving();
- }
-
- return 1./(2.*x*(emitter*emission));
-
-}
-
-double IFMassiveKinematics::
-jacobianTimesPropagator(const DipoleSplittingInfo&,
- Energy) const {
- assert(false && "implementation missing");
- return 0.;
-}
-
void IFMassiveKinematics::generateKinematics(const Lorentz5Momentum& pEmitter,
const Lorentz5Momentum& pSpectator,
const DipoleSplittingInfo& dInfo) {
Energy2 sbar = 2.*pEmitter*pSpectator;
Energy pt = dInfo.lastPt();
double ratio = pt*pt/sbar;
double z = dInfo.lastZ();
double x = (z*(1.-z)-ratio)/(1.-z-ratio);
double u = ratio / (1.-z);
pt = sqrt(sbar*u*(1.-u)*(1.-x)/x);
Lorentz5Momentum kt =
getKt (pEmitter, pSpectator, pt, dInfo.lastPhi(),true);
Lorentz5Momentum em;
Lorentz5Momentum emm;
Lorentz5Momentum spe;
Energy2 mj2 = dInfo.spectatorData()->mass()*dInfo.spectatorData()->mass();
double alpha = 1. - 2.*mj2/sbar;
// TODO: adjust phasespace boundary condition
if ( !theCollinearScheme &&
x > u && (1.-x)/(x-u) < 1. ) {
double fkt = sqrt(sqr(x-u)+4.*x*u*mj2/sbar);
// em =
// ((1.-u)/(x-u))*pEmitter + ((u/x)*(1.-x)/(x-u))*pSpectator - kt/(x-u);
Energy2 fa = (sbar*(x+u-2.*x*z)+2.*mj2*x*u) / sqrt(sqr(x-u)+4.*x*u*mj2/sbar);
double a = (-sbar+fa) / (2.*x*(sbar-mj2));
double ap = (sbar+alpha*fa) / (2.*x*(sbar-mj2));
em = ap*pEmitter + a*pSpectator - fkt*kt;
em.setMass(ZERO);
em.rescaleEnergy();
// emm =
// ((1.-x)/(x-u))*pEmitter + ((u/x)*(1.-u)/(x-u))*pSpectator - kt/(x-u);
Energy2 fb = abs(sbar*(u*(1.-u)-x*(1.-x))+2.*mj2*x*u) / sqrt(sqr(x-u)+4.*x*u*mj2/sbar);
double b = (-sbar*(1.-x-u)+fb) / (2.*x*(sbar-mj2));
double bp = (sbar*(1.-x-u)+alpha*fb) / (2.*x*(sbar-mj2));
emm = bp*pEmitter + b*pSpectator + fkt*kt;
emm.setMass(ZERO);
emm.rescaleEnergy();
// spe =
// (1.-u/x)*pSpectator;
Energy2 fc = sqrt(sqr(sbar*(x-u))+4.*sbar*mj2*x*u);
double c = (sbar*(x-u)-2.*x*mj2+fc) / (2.*x*(sbar-mj2));
double cp = (-sbar*(x-u)+2.*x*mj2+alpha*fc) / (2.*x*(sbar-mj2));
spe = cp*pEmitter + c*pSpectator;
spe.setMass(dInfo.spectatorData()->mass());
spe.rescaleEnergy();
} else {
em = (1./x)*pEmitter;
em.setMass(ZERO);
em.rescaleEnergy();
// emm = ((1.-x)*(1.-u)/x)*pEmitter + u*pSpectator + kt;
emm = (pt*pt-u*u*mj2)/(u*sbar)*pEmitter +
u*pSpectator + kt;
emm.setMass(ZERO);
emm.rescaleEnergy();
// spe = ((1.-x)*u/x)*pEmitter + (1.-u)*pSpectator - kt;
spe = (pt*pt+mj2-sqr(1.-u)*mj2)/((1.-u)*sbar)*pEmitter +
(1.-u)*pSpectator - kt;
spe.setMass(dInfo.spectatorData()->mass());
spe.rescaleEnergy();
}
emitterMomentum(em);
emissionMomentum(emm);
spectatorMomentum(spe);
}
// If needed, insert default implementations of function defined
// in the InterfacedBase class here (using ThePEG-interfaced-impl in Emacs).
void IFMassiveKinematics::persistentOutput(PersistentOStream & os) const {
os << theCollinearScheme;
}
void IFMassiveKinematics::persistentInput(PersistentIStream & is, int) {
is >> theCollinearScheme;
}
ClassDescription<IFMassiveKinematics> IFMassiveKinematics::initIFMassiveKinematics;
// Definition of the static class description member.
void IFMassiveKinematics::Init() {
static ClassDocumentation<IFMassiveKinematics> documentation
("IFMassiveKinematics implements massless splittings "
"off a initial-final dipole.");
static Switch<IFMassiveKinematics,bool> interfaceCollinearScheme
("CollinearScheme",
"[experimental] Switch on or off the collinear scheme",
&IFMassiveKinematics::theCollinearScheme, false, false, false);
static SwitchOption interfaceCollinearSchemeOn
(interfaceCollinearScheme,
"On",
"Switch on the collinear scheme.",
true);
static SwitchOption interfaceCollinearSchemeOff
(interfaceCollinearScheme,
"Off",
"Switch off the collinear scheme",
false);
interfaceCollinearScheme.rank(-1);
}
diff --git a/DipoleShower/Kinematics/IFMassiveKinematics.h b/DipoleShower/Kinematics/IFMassiveKinematics.h
--- a/DipoleShower/Kinematics/IFMassiveKinematics.h
+++ b/DipoleShower/Kinematics/IFMassiveKinematics.h
@@ -1,246 +1,244 @@
// -*- C++ -*-
//
// IFLightKinematics.h is a part of Herwig++ - A multi-purpose Monte Carlo event generator
// Copyright (C) 2002-2007 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.
//
#ifndef HERWIG_IFLightKinematics_H
#define HERWIG_IFLightKinematics_H
//
// This is the declaration of the IFLightKinematics class.
//
#include "DipoleSplittingKinematics.h"
namespace Herwig {
using namespace ThePEG;
/**
* \ingroup DipoleShower
* \author Simon Platzer, Martin Stoll
*
* \brief IFMassiveKinematics implements massless splittings
* off an initial-final dipole.
*
* @see \ref IFMassiveKinematicsInterfaces "The interfaces"
* defined for IFMassiveKinematics.
*/
class IFMassiveKinematics: public DipoleSplittingKinematics {
public:
/** @name Standard constructors and destructors. */
//@{
/**
* The default constructor.
*/
IFMassiveKinematics();
/**
* The destructor.
*/
virtual ~IFMassiveKinematics();
//@}
public:
/**
* Return the boundaries in between the evolution
* variable random number is to be sampled; the lower
* cuoff is assumed to correspond to the infrared cutoff.
*/
virtual pair<double,double> kappaSupport(const DipoleSplittingInfo& dIndex) const;
/**
* Return the boundaries in between the momentum
* fraction random number is to be sampled.
*/
virtual pair<double,double> xiSupport(const DipoleSplittingInfo& dIndex) const;
/**
+ * Return the boundaries on the momentum fraction
+ */
+ virtual pair<double,double> zBoundaries(Energy,
+ const DipoleSplittingInfo&,
+ const DipoleSplittingKernel&) const {
+ return make_pair(0.0,1.0);
+ }
+
+ /**
* Return the dipole scale associated to the
* given pair of emitter and spectator. This
* should be the invariant mass or absolute value
* final/final or initial/initial and the absolute
* value of the momentum transfer for intial/final or
* final/initial dipoles.
*/
virtual Energy dipoleScale(const Lorentz5Momentum& pEmitter,
const Lorentz5Momentum& pSpectator) const;
/**
* Return the maximum pt for the given dipole scale.
*/
virtual Energy ptMax(Energy dScale,
double emX, double specX,
const DipoleIndex&,
const DipoleSplittingKernel&) const;
/**
* Return the maximum virtuality for the given dipole scale.
*/
virtual Energy QMax(Energy dScale,
double emX, double specX,
- const DipoleIndex& dIndex) const;
+ const DipoleIndex& dIndex,
+ const DipoleSplittingKernel&) const;
/**
* Return the pt given a virtuality.
*/
virtual Energy PtFromQ(Energy scale, const DipoleSplittingInfo&) const;
/**
* Return the virtuality given a pt.
*/
virtual Energy QFromPt(Energy scale, const DipoleSplittingInfo&) const;
/**
* Return the random number associated to
* the given pt.
*/
virtual double ptToRandom(Energy pt, Energy dScale,
- const DipoleIndex& dIndex) const;
+ double emX, double specX,
+ const DipoleIndex& dIndex,
+ const DipoleSplittingKernel&) const;
/**
* Generate splitting variables given three random numbers
* and the momentum fractions of the emitter and spectator.
* Return true on success.
*/
virtual bool generateSplitting(double kappa, double xi, double phi,
- DipoleSplittingInfo& dIndex);
-
- /**
- * For the splitting products present in the given dipole splitting
- * info object calculate the kinematics parameters and return the
- * propagator factor.
- */
- virtual InvEnergy2 setKinematics(DipoleSplittingInfo&) const;
-
- /**
- * For the splitting parameters given in the dipole splitting info
- * object, calculate the phasespace Jacobian times the propagator
- * factor.
- */
- virtual double jacobianTimesPropagator(const DipoleSplittingInfo&,
- Energy) const;
+ DipoleSplittingInfo& dIndex,
+ const DipoleSplittingKernel&);
/**
* Generate the full kinematics given emitter and
* spectator momentum and a previously completeted
* DipoleSplittingInfo object.
*/
virtual void generateKinematics(const Lorentz5Momentum& pEmitter,
const Lorentz5Momentum& pSpectator,
const DipoleSplittingInfo& dInfo);
public:
/** @name Functions used by the persistent I/O system. */
//@{
/**
* Function used to write out object persistently.
* @param os the persistent output stream written to.
*/
void persistentOutput(PersistentOStream & os) const;
/**
* Function used to read in object persistently.
* @param is the persistent input stream read from.
* @param version the version number of the object when written.
*/
void persistentInput(PersistentIStream & is, int version);
//@}
/**
* The standard Init function used to initialize the interfaces.
* Called exactly once for each class by the class description system
* before the main function starts or
* when this class is dynamically loaded.
*/
static void Init();
protected:
/** @name Clone Methods. */
//@{
/**
* Make a simple clone of this object.
* @return a pointer to the new object.
*/
virtual IBPtr clone() const;
/** Make a clone of this object, possibly modifying the cloned object
* to make it sane.
* @return a pointer to the new object.
*/
virtual IBPtr fullclone() const;
//@}
// If needed, insert declarations of virtual function defined in the
// InterfacedBase class here (using ThePEG-interfaced-decl in Emacs).
private:
/**
* The static object used to initialize the description of this class.
* Indicates that this is a concrete class with persistent data.
*/
static ClassDescription<IFMassiveKinematics> initIFMassiveKinematics;
/**
* The assignment operator is private and must never be called.
* In fact, it should not even be implemented.
*/
IFMassiveKinematics & operator=(const IFMassiveKinematics &);
private:
/**
* Wether or not to choose the `collinear' scheme
*/
bool theCollinearScheme;
};
}
#include "ThePEG/Utilities/ClassTraits.h"
namespace ThePEG {
/** @cond TRAITSPECIALIZATIONS */
/** This template specialization informs ThePEG about the
* base classes of IFMassiveKinematics. */
template <>
struct BaseClassTrait<Herwig::IFMassiveKinematics,1> {
/** Typedef of the first base class of IFMassiveKinematics. */
typedef Herwig::DipoleSplittingKinematics NthBase;
};
/** This template specialization informs ThePEG about the name of
* the IFMassiveKinematics class and the shared object where it is defined. */
template <>
struct ClassTraits<Herwig::IFMassiveKinematics>
: public ClassTraitsBase<Herwig::IFMassiveKinematics> {
/** Return a platform-independent class name */
static string className() { return "Herwig::IFMassiveKinematics"; }
/**
* The name of a file containing the dynamic library where the class
* IFMassiveKinematics is implemented. It may also include several, space-separated,
* libraries if the class IFMassiveKinematics depends on other classes (base classes
* excepted). In this case the listed libraries will be dynamically
* linked in the order they are specified.
*/
static string library() { return "HwDipoleShower.so"; }
};
/** @endcond */
}
#endif /* HERWIG_IFMassiveKinematics_H */
diff --git a/DipoleShower/Kinematics/IILightKinematics.cc b/DipoleShower/Kinematics/IILightKinematics.cc
--- a/DipoleShower/Kinematics/IILightKinematics.cc
+++ b/DipoleShower/Kinematics/IILightKinematics.cc
@@ -1,364 +1,278 @@
// -*- C++ -*-
//
// IILightKinematics.cc is a part of Herwig++ - A multi-purpose Monte Carlo event generator
// Copyright (C) 2002-2007 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 IILightKinematics class.
//
#include "IILightKinematics.h"
#include "ThePEG/Interface/ClassDocumentation.h"
#include "ThePEG/Interface/Switch.h"
#include "ThePEG/Persistency/PersistentOStream.h"
#include "ThePEG/Persistency/PersistentIStream.h"
#include "ThePEG/Repository/UseRandom.h"
#include "ThePEG/Repository/EventGenerator.h"
#include "Herwig++/DipoleShower/Base/DipoleSplittingInfo.h"
using namespace Herwig;
IILightKinematics::IILightKinematics()
: DipoleSplittingKinematics(), theCollinearScheme(false), didCollinear(false) {}
IILightKinematics::~IILightKinematics() {}
IBPtr IILightKinematics::clone() const {
return new_ptr(*this);
}
IBPtr IILightKinematics::fullclone() const {
return new_ptr(*this);
}
-pair<double,double> IILightKinematics::kappaSupport(const DipoleSplittingInfo&) const {
- return make_pair(0.0,1.0);
-}
-
-pair<double,double> IILightKinematics::xiSupport(const DipoleSplittingInfo& split) const {
-
- double c = sqrt(1.-4.*sqr(IRCutoff()/generator()->maximumCMEnergy()));
-
- if ( split.index().emitterData()->id() == ParticleID::g ) {
- if ( split.emitterData()->id() == ParticleID::g ) {
- double b = log((1.+c)/(1.-c));
- return make_pair(-b,b);
- } else {
- return make_pair(log(0.5*(1.-c)),log(0.5*(1.+c)));
- }
- }
-
- if ( split.index().emitterData()->id() != ParticleID::g &&
- split.emitterData()->id() != ParticleID::g ) {
- return make_pair(-log(0.5*(1.+c)),-log(0.5*(1.-c)));
- }
-
- return make_pair(0.5*(1.-c),0.5*(1.+c));
-
-}
-
-Energy IILightKinematics::dipoleScale(const Lorentz5Momentum& pEmitter,
- const Lorentz5Momentum& pSpectator) const {
- return sqrt(2.*(pEmitter*pSpectator));
-}
-
Energy IILightKinematics::ptMax(Energy dScale,
double emX, double specX,
const DipoleIndex&,
const DipoleSplittingKernel&) const {
double tau = emX*specX;
return (1.-tau) * dScale / (2.*sqrt(tau));
}
Energy IILightKinematics::QMax(Energy,
double, double,
- const DipoleIndex&) const {
+ const DipoleIndex&,
+ const DipoleSplittingKernel&) const {
assert(false && "add this");
return 0.0*GeV;
}
-Energy IILightKinematics::PtFromQ(Energy, const DipoleSplittingInfo&) const {
- assert(false && "add this");
- return 0.0*GeV;
+Energy IILightKinematics::PtFromQ(Energy scale, const DipoleSplittingInfo& split) const {
+ double z = split.lastZ();
+ return scale*sqrt(1.-z);
}
-Energy IILightKinematics::QFromPt(Energy, const DipoleSplittingInfo&) const {
- assert(false && "add this");
- return 0.0*GeV;
+Energy IILightKinematics::QFromPt(Energy scale, const DipoleSplittingInfo& split) const {
+ double z = split.lastZ();
+ return scale/sqrt(1.-z);
}
-
-double IILightKinematics::ptToRandom(Energy pt, Energy,
- const DipoleIndex&) const {
- return log(pt/IRCutoff()) / log(0.5 * generator()->maximumCMEnergy()/IRCutoff());
+pair<double,double> IILightKinematics::zBoundaries(Energy pt,
+ const DipoleSplittingInfo& dInfo,
+ const DipoleSplittingKernel&) const {
+ double x = dInfo.emitterX()*dInfo.spectatorX();
+ double s = sqrt(1.-sqr(pt/dInfo.hardPt()));
+ return make_pair(0.5*(1.+x-(1.-x)*s),0.5*(1.+x+(1.-x)*s));
}
bool IILightKinematics::generateSplitting(double kappa, double xi, double rphi,
- DipoleSplittingInfo& info) {
+ DipoleSplittingInfo& info,
+ const DipoleSplittingKernel& split) {
if ( info.emitterX() < xMin() ||
info.spectatorX() < xMin() ) {
jacobian(0.0);
return false;
}
- Energy pt = IRCutoff() * pow(0.5 * generator()->maximumCMEnergy()/IRCutoff(),kappa);
+ double weight = 1.0;
- double r = sqr(info.hardPt()/info.scale());
- if ( sqr(pt) > sqr(info.hardPt())*r*((2.+1./r)-2.*sqrt(1.+1./r)) ) {
+ Energy pt = generatePt(kappa,info.scale(),
+ info.emitterX(),info.spectatorX(),
+ info.index(),split,
+ weight);
+
+ if ( pt < IRCutoff() || pt > info.hardPt() ) {
jacobian(0.0);
return false;
}
- double z = 0.;
- double mapZJacobian = 0.;
+ double z = 0.0;
if ( info.index().emitterData()->id() == ParticleID::g ) {
if ( info.emitterData()->id() == ParticleID::g ) {
- z = exp(xi)/(1.+exp(xi));
- mapZJacobian = z*(1.-z);
+ z = generateZ(xi,pt,OneOverZOneMinusZ,
+ info,split,weight);
} else {
- z = exp(xi);
- mapZJacobian = z;
+ z = generateZ(xi,pt,OneOverZ,
+ info,split,weight);
}
}
if ( info.index().emitterData()->id() != ParticleID::g ) {
if ( info.emitterData()->id() != ParticleID::g ) {
- z = 1.-exp(-xi);
- mapZJacobian = (1.-z);
+ z = generateZ(xi,pt,OneOverOneMinusZ,
+ info,split,weight);
} else {
- z = xi;
- mapZJacobian = 1.;
+ z = generateZ(xi,pt,FlatZ,
+ info,split,weight);
}
}
double ratio = sqr(pt/info.scale());
- double x = ( z*(1.-z) - ratio ) / ( 1. - z );
- double v = ratio / (1.-z);
+ double x = z*(1.-z)/(1.-z+ratio);
+ double v = ratio*z /(1.-z+ratio);
- if ( x < 0. || x > 1. || v > 1. || v > 1.-x ) {
- jacobian(0.0);
- return false;
- }
-
- double tau = info.emitterX()*info.spectatorX();
-
- double zpx = 0.5*( 1.+ tau +
- (1.-tau)*sqrt(1.-sqr(2.*pt/((1.-tau)*info.scale()))) );
- double zmx = 0.5*( 1.+ tau -
- (1.-tau)*sqrt(1.-sqr(2.*pt/((1.-tau)*info.scale()))) );
-
- double xq = sqr(pt/info.hardPt());
-
- double zpq = 0.5*( 1.+ xq +
- (1.-xq)*sqrt(1.-sqr(2.*pt/((1.-xq)*info.scale()))) );
- double zmq = 0.5*( 1.+ xq -
- (1.-xq)*sqrt(1.-sqr(2.*pt/((1.-xq)*info.scale()))) );
-
- double zp = min(zpx,zpq);
- double zm = max(zmx,zmq);
-
- if ( pt < IRCutoff() ||
- pt > info.hardPt() ||
- z > zp || z < zm ) {
+ if ( x < 0. || x > 1. || v < 0. || v > 1.-x ) {
jacobian(0.0);
return false;
}
if ( !theCollinearScheme &&
(1.-v-x)/(v+x) < 1. ) {
if ( (x+v) < info.emitterX() ||
x/(x+v) < info.spectatorX() ) {
jacobian(0.0);
return false;
}
} else {
if ( x < info.emitterX() ) {
jacobian(0.0);
return false;
}
}
double phi = 2.*Constants::pi*rphi;
- jacobian(2. * mapZJacobian * (1.-z)/(z*(1.-z)-ratio) * log(0.5 * generator()->maximumCMEnergy()/IRCutoff()));
+ jacobian(weight*(1./z));
lastPt(pt);
lastZ(z);
lastPhi(phi);
if ( !theCollinearScheme &&
(1.-v-x)/(v+x) < 1. ) {
lastEmitterZ(x+v);
lastSpectatorZ(x/(x+v));
} else {
lastEmitterZ(x);
lastSpectatorZ(1.);
}
if ( theMCCheck )
theMCCheck->book(info.emitterX(),info.spectatorX(),info.scale(),info.hardPt(),pt,z,jacobian());
return true;
}
-InvEnergy2 IILightKinematics::setKinematics(DipoleSplittingInfo& split) const {
-
- Lorentz5Momentum emitter = split.splitEmitter()->momentum();
- Lorentz5Momentum emission = split.emission()->momentum();
- Lorentz5Momentum spectator = split.splitSpectator()->momentum();
-
- split.splittingKinematics(const_cast<IILightKinematics*>(this));
-
- Energy2 scale = 2.*(-emission*emitter - emission*spectator + emitter*spectator);
- split.scale(sqrt(scale));
-
- double x = scale/(2.*(emitter*spectator));
- double v = (emitter*emission)/(emitter*spectator);
-
- split.lastZ(v+x);
- split.lastPt(split.scale() * sqrt(v*(1.-x-v)));
-
- split.hardPt(split.lastPt());
-
- if ( split.hardPt() > IRCutoff() ) {
- split.continuesEvolving();
- } else {
- split.didStopEvolving();
- }
-
- return 1./(2.*x*(emitter*emission));
-
-}
-
-double IILightKinematics::
-jacobianTimesPropagator(const DipoleSplittingInfo&,
- Energy) const {
- assert(false && "implementation missing");
- return 0.;
-}
-
void IILightKinematics::generateKinematics(const Lorentz5Momentum& pEmitter,
const Lorentz5Momentum& pSpectator,
const DipoleSplittingInfo& dInfo) {
Energy pt = dInfo.lastPt();
double z = dInfo.lastZ();
- double ratio = sqr(pt/(pEmitter+pSpectator).m());
+ double ratio = sqr(pt)/(2.*pEmitter*pSpectator);
- double x = ( z*(1.-z) - ratio ) / ( 1. - z );
- double v = ratio / (1.-z);
-
- pt = sqrt(v*(1.-x-v)/x) * (pEmitter+pSpectator).m();
+ double x = z*(1.-z)/(1.-z+ratio);
+ double v = ratio*z /(1.-z+ratio);
Lorentz5Momentum kt =
getKt (pEmitter, pSpectator, pt, dInfo.lastPhi());
if ( !theCollinearScheme &&
(1.-v-x)/(v+x) < 1. ) {
Lorentz5Momentum em =
(1./(v+x))*pEmitter+(v*(1.-v-x)/(x*(x+v)))*pSpectator+kt/(x+v);
em.setMass(0.*GeV);
em.rescaleEnergy();
Lorentz5Momentum emm =
((1.-v-x)/(v+x))*pEmitter+(v/(x*(x+v)))*pSpectator+kt/(x+v);
emm.setMass(0.*GeV);
emm.rescaleEnergy();
Lorentz5Momentum spe =
(1.+v/x)*pSpectator;
spe.setMass(0.*GeV);
spe.rescaleEnergy();
emitterMomentum(em);
emissionMomentum(emm);
spectatorMomentum(spe);
didCollinear = false;
} else {
Lorentz5Momentum em =
(1./x)*pEmitter;
em.setMass(0.*GeV);
em.rescaleEnergy();
Lorentz5Momentum emm =
((1.-x-v)/x)*pEmitter+v*pSpectator+kt;
emm.setMass(0.*GeV);
emm.rescaleEnergy();
Lorentz5Momentum spe =
pSpectator;
emitterMomentum(em);
emissionMomentum(emm);
spectatorMomentum(spe);
K = em + spe - emm;
K2 = K.m2();
Ktilde = pEmitter + pSpectator;
KplusKtilde = K + Ktilde;
KplusKtilde2 = KplusKtilde.m2();
didCollinear = true;
}
}
// If needed, insert default implementations of function defined
// in the InterfacedBase class here (using ThePEG-interfaced-impl in Emacs).
void IILightKinematics::persistentOutput(PersistentOStream & os) const {
os << theCollinearScheme;
}
void IILightKinematics::persistentInput(PersistentIStream & is, int) {
is >> theCollinearScheme;
}
ClassDescription<IILightKinematics> IILightKinematics::initIILightKinematics;
// Definition of the static class description member.
void IILightKinematics::Init() {
static ClassDocumentation<IILightKinematics> documentation
("IILightKinematics implements massless splittings "
"off an initial-initial dipole.");
static Switch<IILightKinematics,bool> interfaceCollinearScheme
("CollinearScheme",
"[experimental] Switch on or off the collinear scheme",
&IILightKinematics::theCollinearScheme, false, false, false);
static SwitchOption interfaceCollinearSchemeOn
(interfaceCollinearScheme,
"On",
"Switch on the collinear scheme.",
true);
static SwitchOption interfaceCollinearSchemeOff
(interfaceCollinearScheme,
"Off",
"Switch off the collinear scheme",
false);
interfaceCollinearScheme.rank(-1);
}
diff --git a/DipoleShower/Kinematics/IILightKinematics.h b/DipoleShower/Kinematics/IILightKinematics.h
--- a/DipoleShower/Kinematics/IILightKinematics.h
+++ b/DipoleShower/Kinematics/IILightKinematics.h
@@ -1,269 +1,232 @@
// -*- C++ -*-
//
// IILightKinematics.h is a part of Herwig++ - A multi-purpose Monte Carlo event generator
// Copyright (C) 2002-2007 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.
//
#ifndef HERWIG_IILightKinematics_H
#define HERWIG_IILightKinematics_H
//
// This is the declaration of the IILightKinematics class.
//
#include "DipoleSplittingKinematics.h"
namespace Herwig {
using namespace ThePEG;
/**
* \ingroup DipoleShower
* \author Simon Platzer
*
* \brief IILightKinematics implements massless splittings
* off an initial-initial dipole.
*
* @see \ref IILightKinematicsInterfaces "The interfaces"
* defined for IILightKinematics.
*/
class IILightKinematics: public DipoleSplittingKinematics {
public:
/** @name Standard constructors and destructors. */
//@{
/**
* The default constructor.
*/
IILightKinematics();
/**
* The destructor.
*/
virtual ~IILightKinematics();
//@}
public:
/**
- * Return the boundaries in between the evolution
- * variable random number is to be sampled; the lower
- * cuoff is assumed to correspond to the infrared cutoff.
- */
- virtual pair<double,double> kappaSupport(const DipoleSplittingInfo& dIndex) const;
-
- /**
- * Return the boundaries in between the momentum
- * fraction random number is to be sampled.
- */
- virtual pair<double,double> xiSupport(const DipoleSplittingInfo& dIndex) const;
-
- /**
- * Return the dipole scale associated to the
- * given pair of emitter and spectator. This
- * should be the invariant mass or absolute value
- * final/final or initial/initial and the absolute
- * value of the momentum transfer for intial/final or
- * final/initial dipoles.
- */
- virtual Energy dipoleScale(const Lorentz5Momentum& pEmitter,
- const Lorentz5Momentum& pSpectator) const;
-
- /**
* Return the maximum pt for the given dipole scale.
*/
virtual Energy ptMax(Energy dScale,
double emX, double specX,
const DipoleIndex&,
const DipoleSplittingKernel&) const;
/**
* Return the maximum virtuality for the given dipole scale.
*/
virtual Energy QMax(Energy dScale,
double emX, double specX,
- const DipoleIndex& dIndex) const;
+ const DipoleIndex& dIndex,
+ const DipoleSplittingKernel&) const;
/**
* Return the pt given a virtuality.
*/
virtual Energy PtFromQ(Energy scale, const DipoleSplittingInfo&) const;
/**
* Return the virtuality given a pt.
*/
virtual Energy QFromPt(Energy scale, const DipoleSplittingInfo&) const;
/**
- * Return the random number associated to
- * the given pt.
+ * Return the boundaries on the momentum fraction
*/
- virtual double ptToRandom(Energy pt, Energy dScale,
- const DipoleIndex& dIndex) const;
+ virtual pair<double,double> zBoundaries(Energy pt,
+ const DipoleSplittingInfo& dInfo,
+ const DipoleSplittingKernel& split) const;
/**
* Generate splitting variables given three random numbers
* and the momentum fractions of the emitter and spectator.
* Return true on success.
*/
virtual bool generateSplitting(double kappa, double xi, double phi,
- DipoleSplittingInfo& dIndex);
-
- /**
- * For the splitting products present in the given dipole splitting
- * info object calculate the kinematics parameters and return the
- * propagator factor.
- */
- virtual InvEnergy2 setKinematics(DipoleSplittingInfo&) const;
-
- /**
- * For the splitting parameters given in the dipole splitting info
- * object, calculate the phasespace Jacobian times the propagator
- * factor.
- */
- virtual double jacobianTimesPropagator(const DipoleSplittingInfo&,
- Energy) const;
+ DipoleSplittingInfo& dIndex,
+ const DipoleSplittingKernel&);
/**
* Generate the full kinematics given emitter and
* spectator momentum and a previously completeted
* DipoleSplittingInfo object.
*/
virtual void generateKinematics(const Lorentz5Momentum& pEmitter,
const Lorentz5Momentum& pSpectator,
const DipoleSplittingInfo& dInfo);
/*
* Return true, if there is a transformation which should
* be applied to all other final state particles except the ones
* involved in the splitting after having performed the splitting
*/
virtual bool doesTransform () const { return theCollinearScheme || didCollinear; }
/*
* perform the transformation, if existing
*/
virtual Lorentz5Momentum transform (const Lorentz5Momentum& p) const {
if ( !theCollinearScheme && !didCollinear ) return p;
return p-(2.*(KplusKtilde*p)/KplusKtilde2)*KplusKtilde+(2.*(Ktilde*p)/K2)*K;
}
public:
/** @name Functions used by the persistent I/O system. */
//@{
/**
* Function used to write out object persistently.
* @param os the persistent output stream written to.
*/
void persistentOutput(PersistentOStream & os) const;
/**
* Function used to read in object persistently.
* @param is the persistent input stream read from.
* @param version the version number of the object when written.
*/
void persistentInput(PersistentIStream & is, int version);
//@}
/**
* The standard Init function used to initialize the interfaces.
* Called exactly once for each class by the class description system
* before the main function starts or
* when this class is dynamically loaded.
*/
static void Init();
protected:
/** @name Clone Methods. */
//@{
/**
* Make a simple clone of this object.
* @return a pointer to the new object.
*/
virtual IBPtr clone() const;
/** Make a clone of this object, possibly modifying the cloned object
* to make it sane.
* @return a pointer to the new object.
*/
virtual IBPtr fullclone() const;
//@}
// If needed, insert declarations of virtual function defined in the
// InterfacedBase class here (using ThePEG-interfaced-decl in Emacs).
private:
/**
* The static object used to initialize the description of this class.
* Indicates that this is a concrete class with persistent data.
*/
static ClassDescription<IILightKinematics> initIILightKinematics;
/**
* The assignment operator is private and must never be called.
* In fact, it should not even be implemented.
*/
IILightKinematics & operator=(const IILightKinematics &);
private:
/**
* Wether or not to choose the `collinear' scheme
*/
bool theCollinearScheme;
bool didCollinear;
Lorentz5Momentum K;
Energy2 K2;
Lorentz5Momentum Ktilde;
Lorentz5Momentum KplusKtilde;
Energy2 KplusKtilde2;
};
}
#include "ThePEG/Utilities/ClassTraits.h"
namespace ThePEG {
/** @cond TRAITSPECIALIZATIONS */
/** This template specialization informs ThePEG about the
* base classes of IILightKinematics. */
template <>
struct BaseClassTrait<Herwig::IILightKinematics,1> {
/** Typedef of the first base class of IILightKinematics. */
typedef Herwig::DipoleSplittingKinematics NthBase;
};
/** This template specialization informs ThePEG about the name of
* the IILightKinematics class and the shared object where it is defined. */
template <>
struct ClassTraits<Herwig::IILightKinematics>
: public ClassTraitsBase<Herwig::IILightKinematics> {
/** Return a platform-independent class name */
static string className() { return "Herwig::IILightKinematics"; }
/**
* The name of a file containing the dynamic library where the class
* IILightKinematics is implemented. It may also include several, space-separated,
* libraries if the class IILightKinematics depends on other classes (base classes
* excepted). In this case the listed libraries will be dynamically
* linked in the order they are specified.
*/
static string library() { return "HwDipoleShower.so"; }
};
/** @endcond */
}
#endif /* HERWIG_IILightKinematics_H */
diff --git a/MatrixElement/Matchbox/Matching/ShowerApproximation.cc b/MatrixElement/Matchbox/Matching/ShowerApproximation.cc
--- a/MatrixElement/Matchbox/Matching/ShowerApproximation.cc
+++ b/MatrixElement/Matchbox/Matching/ShowerApproximation.cc
@@ -1,547 +1,556 @@
// -*- C++ -*-
//
// ShowerApproximation.cc is a part of Herwig++ - A multi-purpose Monte Carlo event generator
// Copyright (C) 2002-2012 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 ShowerApproximation class.
//
#include "ShowerApproximation.h"
#include "ThePEG/Interface/ClassDocumentation.h"
#include "ThePEG/Interface/Switch.h"
#include "ThePEG/Interface/Parameter.h"
#include "ThePEG/EventRecord/Particle.h"
#include "ThePEG/Repository/UseRandom.h"
#include "ThePEG/Repository/EventGenerator.h"
#include "ThePEG/Utilities/DescribeClass.h"
#include "ThePEG/Persistency/PersistentOStream.h"
#include "ThePEG/Persistency/PersistentIStream.h"
#include "Herwig++/MatrixElement/Matchbox/Dipoles/SubtractionDipole.h"
using namespace Herwig;
ShowerApproximation::ShowerApproximation()
: HandlerBase(), theBelowCutoff(false),
theFFPtCut(1.0*GeV), theFFScreeningScale(ZERO),
theFIPtCut(1.0*GeV), theFIScreeningScale(ZERO),
theIIPtCut(1.0*GeV), theIIScreeningScale(ZERO),
theRestrictPhasespace(true), theHardScaleFactor(1.0),
theRenormalizationScaleFactor(1.0), theFactorizationScaleFactor(1.0),
theExtrapolationX(0.65),
theRealEmissionScaleInSubtraction(showerScale),
theBornScaleInSubtraction(showerScale),
theEmissionScaleInSubtraction(showerScale),
theRealEmissionScaleInSplitting(showerScale),
theBornScaleInSplitting(showerScale),
theEmissionScaleInSplitting(showerScale),
theRenormalizationScaleFreeze(1.*GeV),
theFactorizationScaleFreeze(1.*GeV),
theProfileScales(true),
theProfileRho(0.3) {}
ShowerApproximation::~ShowerApproximation() {}
void ShowerApproximation::setDipole(Ptr<SubtractionDipole>::tcptr dip) { theDipole = dip; }
Ptr<SubtractionDipole>::tcptr ShowerApproximation::dipole() const { return theDipole; }
bool ShowerApproximation::isAboveCutoff() const {
if ( dipole()->bornEmitter() > 1 &&
dipole()->bornSpectator() > 1 ) {
return dipole()->lastPt() >= ffPtCut();
} else if ( ( dipole()->bornEmitter() > 1 &&
dipole()->bornSpectator() < 2 ) ||
( dipole()->bornEmitter() < 2 &&
dipole()->bornSpectator() > 1 ) ) {
return dipole()->lastPt() >= fiPtCut();
} else {
assert(dipole()->bornEmitter() < 2 &&
dipole()->bornSpectator() < 2);
return dipole()->lastPt() >= iiPtCut();
}
return true;
}
Energy ShowerApproximation::hardScale() const {
+ if ( !bornCXComb()->mePartonData()[0]->coloured() &&
+ !bornCXComb()->mePartonData()[1]->coloured() ) {
+ Energy maxPt = (bornCXComb()->meMomenta()[0] + bornCXComb()->meMomenta()[1]).m();
+ maxPt *= hardScaleFactor();
+ return maxPt;
+ }
Energy maxPt = generator()->maximumCMEnergy();
vector<Lorentz5Momentum>::const_iterator p =
bornCXComb()->meMomenta().begin() + 2;
cPDVector::const_iterator pp =
bornCXComb()->mePartonData().begin() + 2;
for ( ; p != bornCXComb()->meMomenta().end(); ++p, ++pp )
if ( (**pp).coloured() )
maxPt = min(maxPt,p->perp());
if ( maxPt == generator()->maximumCMEnergy() )
maxPt = (bornCXComb()->meMomenta()[0] + bornCXComb()->meMomenta()[1]).m();
maxPt *= hardScaleFactor();
return maxPt;
}
double ShowerApproximation::hardScaleProfile(Energy hard, Energy soft) const {
+ if ( !bornCXComb()->mePartonData()[0]->coloured() &&
+ !bornCXComb()->mePartonData()[1]->coloured() )
+ return 1;
double x = soft/hard;
if ( theProfileScales ) {
if ( x > 1. ) {
return 0.;
} else if ( x <= 1. && x > 1. - theProfileRho ) {
return sqr(1.-x)/(2.*sqr(theProfileRho));
} else if ( x <= 1. - theProfileRho &&
x > 1. - 2.*theProfileRho ) {
return 1. - sqr(1.-2.*theProfileRho-x)/(2.*sqr(theProfileRho));
} else {
return 1.;
}
}
if ( x <= 1. )
return 1.;
return 0.;
}
bool ShowerApproximation::isInShowerPhasespace() const {
if ( !isAboveCutoff() )
return false;
if ( !restrictPhasespace() )
return true;
return dipole()->lastPt() <= hardScale();
}
Energy2 ShowerApproximation::showerEmissionScale() const {
Energy2 mur = sqr(dipole()->lastPt());
if ( dipole()->bornEmitter() > 1 &&
dipole()->bornSpectator() > 1 ) {
return mur + sqr(ffScreeningScale());
} else if ( ( dipole()->bornEmitter() > 1 &&
dipole()->bornSpectator() < 2 ) ||
( dipole()->bornEmitter() < 2 &&
dipole()->bornSpectator() > 1 ) ) {
return mur + sqr(fiScreeningScale());
} else {
assert(dipole()->bornEmitter() < 2 &&
dipole()->bornSpectator() < 2);
return mur + sqr(iiScreeningScale());
}
return mur;
}
Energy2 ShowerApproximation::bornRenormalizationScale() const {
return
sqr(dipole()->underlyingBornME()->renormalizationScaleFactor()) *
dipole()->underlyingBornME()->renormalizationScale();
}
Energy2 ShowerApproximation::bornFactorizationScale() const {
return
sqr(dipole()->underlyingBornME()->factorizationScaleFactor()) *
dipole()->underlyingBornME()->factorizationScale();
}
Energy2 ShowerApproximation::realRenormalizationScale() const {
return
sqr(dipole()->realEmissionME()->renormalizationScaleFactor()) *
dipole()->realEmissionME()->renormalizationScale();
}
Energy2 ShowerApproximation::realFactorizationScale() const {
return
sqr(dipole()->realEmissionME()->factorizationScaleFactor()) *
dipole()->realEmissionME()->factorizationScale();
}
double ShowerApproximation::bornPDFWeight(Energy2 muf) const {
if ( !bornCXComb()->mePartonData()[0]->coloured() &&
!bornCXComb()->mePartonData()[1]->coloured() )
return 1.;
if ( muf < sqr(theFactorizationScaleFreeze) )
muf = sqr(theFactorizationScaleFreeze);
double pdfweight = 1.;
if ( bornCXComb()->mePartonData()[0]->coloured() &&
dipole()->underlyingBornME()->havePDFWeight1() )
pdfweight *= dipole()->underlyingBornME()->pdf1(muf,theExtrapolationX);
if ( bornCXComb()->mePartonData()[1]->coloured() &&
dipole()->underlyingBornME()->havePDFWeight2() )
pdfweight *= dipole()->underlyingBornME()->pdf2(muf,theExtrapolationX);
return pdfweight;
}
double ShowerApproximation::realPDFWeight(Energy2 muf) const {
if ( !realCXComb()->mePartonData()[0]->coloured() &&
!realCXComb()->mePartonData()[1]->coloured() )
return 1.;
if ( muf < sqr(theFactorizationScaleFreeze) )
muf = sqr(theFactorizationScaleFreeze);
double pdfweight = 1.;
if ( realCXComb()->mePartonData()[0]->coloured() &&
dipole()->realEmissionME()->havePDFWeight1() )
pdfweight *= dipole()->realEmissionME()->pdf1(muf,theExtrapolationX);
if ( realCXComb()->mePartonData()[1]->coloured() &&
dipole()->realEmissionME()->havePDFWeight2() )
pdfweight *= dipole()->realEmissionME()->pdf2(muf,theExtrapolationX);
return pdfweight;
}
double ShowerApproximation::scaleWeight(int rScale, int bScale, int eScale) const {
double emissionAlpha = 1.;
Energy2 emissionScale = ZERO;
Energy2 showerscale = ZERO;
if ( eScale == showerScale || bScale == showerScale || eScale == showerScale ) {
showerscale = showerRenormalizationScale();
if ( showerscale < sqr(theRenormalizationScaleFreeze) )
showerscale = sqr(theFactorizationScaleFreeze);
}
if ( eScale == showerScale ) {
emissionAlpha = SM().alphaS(showerscale);
emissionScale = showerFactorizationScale();
} else if ( eScale == realScale ) {
emissionAlpha = dipole()->realEmissionME()->lastXComb().lastAlphaS();
emissionScale = dipole()->realEmissionME()->lastScale();
} else if ( eScale == bornScale ) {
emissionAlpha = dipole()->underlyingBornME()->lastXComb().lastAlphaS();
emissionScale = dipole()->underlyingBornME()->lastScale();
}
double emissionPDF = realPDFWeight(emissionScale);
double couplingFactor = 1.;
if ( bScale != rScale ) {
double bornAlpha = 1.;
if ( bScale == showerScale ) {
bornAlpha = SM().alphaS(showerscale);
} else if ( bScale == realScale ) {
bornAlpha = dipole()->realEmissionME()->lastXComb().lastAlphaS();
} else if ( bScale == bornScale ) {
bornAlpha = dipole()->underlyingBornME()->lastXComb().lastAlphaS();
}
double realAlpha = 1.;
if ( rScale == showerScale ) {
realAlpha = SM().alphaS(showerscale);
} else if ( rScale == realScale ) {
realAlpha = dipole()->realEmissionME()->lastXComb().lastAlphaS();
} else if ( rScale == bornScale ) {
realAlpha = dipole()->underlyingBornME()->lastXComb().lastAlphaS();
}
couplingFactor *=
pow(realAlpha/bornAlpha,(double)(dipole()->underlyingBornME()->orderInAlphaS()));
}
Energy2 hardScale = ZERO;
if ( bScale == showerScale ) {
hardScale = showerFactorizationScale();
} else if ( bScale == realScale ) {
hardScale = dipole()->realEmissionME()->lastScale();
} else if ( bScale == bornScale ) {
hardScale = dipole()->underlyingBornME()->lastScale();
}
double bornPDF = bornPDFWeight(hardScale);
if ( bornPDF < 1e-8 )
bornPDF = 0.0;
if ( emissionPDF < 1e-8 )
emissionPDF = 0.0;
if ( emissionPDF == 0.0 || bornPDF == 0.0 )
return 0.0;
return
emissionAlpha * emissionPDF *
couplingFactor / bornPDF;
}
// If needed, insert default implementations of virtual function defined
// in the InterfacedBase class here (using ThePEG-interfaced-impl in Emacs).
void ShowerApproximation::persistentOutput(PersistentOStream & os) const {
os << theBornXComb << theRealXComb << theTildeXCombs << theDipole << theBelowCutoff
<< ounit(theFFPtCut,GeV) << ounit(theFFScreeningScale,GeV)
<< ounit(theFIPtCut,GeV) << ounit(theFIScreeningScale,GeV)
<< ounit(theIIPtCut,GeV) << ounit(theIIScreeningScale,GeV)
<< theRestrictPhasespace << theHardScaleFactor
<< theRenormalizationScaleFactor << theFactorizationScaleFactor
<< theExtrapolationX
<< theRealEmissionScaleInSubtraction << theBornScaleInSubtraction
<< theEmissionScaleInSubtraction << theRealEmissionScaleInSplitting
<< theBornScaleInSplitting << theEmissionScaleInSplitting
<< ounit(theRenormalizationScaleFreeze,GeV)
<< ounit(theFactorizationScaleFreeze,GeV)
<< theProfileScales << theProfileRho;
}
void ShowerApproximation::persistentInput(PersistentIStream & is, int) {
is >> theBornXComb >> theRealXComb >> theTildeXCombs >> theDipole >> theBelowCutoff
>> iunit(theFFPtCut,GeV) >> iunit(theFFScreeningScale,GeV)
>> iunit(theFIPtCut,GeV) >> iunit(theFIScreeningScale,GeV)
>> iunit(theIIPtCut,GeV) >> iunit(theIIScreeningScale,GeV)
>> theRestrictPhasespace >> theHardScaleFactor
>> theRenormalizationScaleFactor >> theFactorizationScaleFactor
>> theExtrapolationX
>> theRealEmissionScaleInSubtraction >> theBornScaleInSubtraction
>> theEmissionScaleInSubtraction >> theRealEmissionScaleInSplitting
>> theBornScaleInSplitting >> theEmissionScaleInSplitting
>> iunit(theRenormalizationScaleFreeze,GeV)
>> iunit(theFactorizationScaleFreeze,GeV)
>> theProfileScales >> theProfileRho;
}
// *** Attention *** The following static variable is needed for the type
// description system in ThePEG. Please check that the template arguments
// are correct (the class and its base class), and that the constructor
// arguments are correct (the class name and the name of the dynamically
// loadable library where the class implementation can be found).
DescribeAbstractClass<ShowerApproximation,HandlerBase>
describeHerwigShowerApproximation("Herwig::ShowerApproximation", "HwMatchbox.so");
void ShowerApproximation::Init() {
static ClassDocumentation<ShowerApproximation> documentation
("ShowerApproximation describes the shower emission to be used "
"in NLO matching.");
static Parameter<ShowerApproximation,Energy> interfaceFFPtCut
("FFPtCut",
"Set the pt infrared cutoff",
&ShowerApproximation::theFFPtCut, GeV, 1.0*GeV, 0.0*GeV, 0*GeV,
false, false, Interface::lowerlim);
static Parameter<ShowerApproximation,Energy> interfaceFIPtCut
("FIPtCut",
"Set the pt infrared cutoff",
&ShowerApproximation::theFIPtCut, GeV, 1.0*GeV, 0.0*GeV, 0*GeV,
false, false, Interface::lowerlim);
static Parameter<ShowerApproximation,Energy> interfaceIIPtCut
("IIPtCut",
"Set the pt infrared cutoff",
&ShowerApproximation::theIIPtCut, GeV, 1.0*GeV, 0.0*GeV, 0*GeV,
false, false, Interface::lowerlim);
static Parameter<ShowerApproximation,Energy> interfaceFFScreeningScale
("FFScreeningScale",
"Set the screening scale",
&ShowerApproximation::theFFScreeningScale, GeV, 0.0*GeV, 0.0*GeV, 0*GeV,
false, false, Interface::lowerlim);
static Parameter<ShowerApproximation,Energy> interfaceFIScreeningScale
("FIScreeningScale",
"Set the screening scale",
&ShowerApproximation::theFIScreeningScale, GeV, 0.0*GeV, 0.0*GeV, 0*GeV,
false, false, Interface::lowerlim);
static Parameter<ShowerApproximation,Energy> interfaceIIScreeningScale
("IIScreeningScale",
"Set the screening scale",
&ShowerApproximation::theIIScreeningScale, GeV, 0.0*GeV, 0.0*GeV, 0*GeV,
false, false, Interface::lowerlim);
static Switch<ShowerApproximation,bool> interfaceRestrictPhasespace
("RestrictPhasespace",
"Switch on or off phasespace restrictions",
&ShowerApproximation::theRestrictPhasespace, true, false, false);
static SwitchOption interfaceRestrictPhasespaceOn
(interfaceRestrictPhasespace,
"On",
"Perform phasespace restrictions",
true);
static SwitchOption interfaceRestrictPhasespaceOff
(interfaceRestrictPhasespace,
"Off",
"Do not perform phasespace restrictions",
false);
static Parameter<ShowerApproximation,double> interfaceHardScaleFactor
("HardScaleFactor",
"The hard scale factor.",
&ShowerApproximation::theHardScaleFactor, 1.0, 0.0, 0,
false, false, Interface::lowerlim);
static Parameter<ShowerApproximation,double> interfaceRenormalizationScaleFactor
("RenormalizationScaleFactor",
"The hard scale factor.",
&ShowerApproximation::theRenormalizationScaleFactor, 1.0, 0.0, 0,
false, false, Interface::lowerlim);
static Parameter<ShowerApproximation,double> interfaceFactorizationScaleFactor
("FactorizationScaleFactor",
"The hard scale factor.",
&ShowerApproximation::theFactorizationScaleFactor, 1.0, 0.0, 0,
false, false, Interface::lowerlim);
static Parameter<ShowerApproximation,double> interfaceExtrapolationX
("ExtrapolationX",
"The x from which on extrapolation should be performed.",
&ShowerApproximation::theExtrapolationX, 0.65, 0.0, 1.0,
false, false, Interface::limited);
static Switch<ShowerApproximation,int> interfaceRealEmissionScaleInSubtraction
("RealEmissionScaleInSubtraction",
"Set the scale choice for the real emission cross section in the matching subtraction.",
&ShowerApproximation::theRealEmissionScaleInSubtraction, showerScale, false, false);
static SwitchOption interfaceRealEmissionScaleInSubtractionRealScale
(interfaceRealEmissionScaleInSubtraction,
"RealScale",
"Use the real emission scale.",
realScale);
static SwitchOption interfaceRealEmissionScaleInSubtractionBornScale
(interfaceRealEmissionScaleInSubtraction,
"BornScale",
"Use the Born scale.",
bornScale);
static SwitchOption interfaceRealEmissionScaleInSubtractionShowerScale
(interfaceRealEmissionScaleInSubtraction,
"ShowerScale",
"Use the shower scale",
showerScale);
static Switch<ShowerApproximation,int> interfaceBornScaleInSubtraction
("BornScaleInSubtraction",
"Set the scale choice for the Born cross section in the matching subtraction.",
&ShowerApproximation::theBornScaleInSubtraction, showerScale, false, false);
static SwitchOption interfaceBornScaleInSubtractionRealScale
(interfaceBornScaleInSubtraction,
"RealScale",
"Use the real emission scale.",
realScale);
static SwitchOption interfaceBornScaleInSubtractionBornScale
(interfaceBornScaleInSubtraction,
"BornScale",
"Use the Born scale.",
bornScale);
static SwitchOption interfaceBornScaleInSubtractionShowerScale
(interfaceBornScaleInSubtraction,
"ShowerScale",
"Use the shower scale",
showerScale);
static Switch<ShowerApproximation,int> interfaceEmissionScaleInSubtraction
("EmissionScaleInSubtraction",
"Set the scale choice for the emission in the matching subtraction.",
&ShowerApproximation::theEmissionScaleInSubtraction, showerScale, false, false);
static SwitchOption interfaceEmissionScaleInSubtractionRealScale
(interfaceEmissionScaleInSubtraction,
"RealScale",
"Use the real emission scale.",
realScale);
static SwitchOption interfaceEmissionScaleInSubtractionEmissionScale
(interfaceEmissionScaleInSubtraction,
"BornScale",
"Use the Born scale.",
bornScale);
static SwitchOption interfaceEmissionScaleInSubtractionShowerScale
(interfaceEmissionScaleInSubtraction,
"ShowerScale",
"Use the shower scale",
showerScale);
static Switch<ShowerApproximation,int> interfaceRealEmissionScaleInSplitting
("RealEmissionScaleInSplitting",
"Set the scale choice for the real emission cross section in the splitting.",
&ShowerApproximation::theRealEmissionScaleInSplitting, showerScale, false, false);
static SwitchOption interfaceRealEmissionScaleInSplittingRealScale
(interfaceRealEmissionScaleInSplitting,
"RealScale",
"Use the real emission scale.",
realScale);
static SwitchOption interfaceRealEmissionScaleInSplittingBornScale
(interfaceRealEmissionScaleInSplitting,
"BornScale",
"Use the Born scale.",
bornScale);
static SwitchOption interfaceRealEmissionScaleInSplittingShowerScale
(interfaceRealEmissionScaleInSplitting,
"ShowerScale",
"Use the shower scale",
showerScale);
static Switch<ShowerApproximation,int> interfaceBornScaleInSplitting
("BornScaleInSplitting",
"Set the scale choice for the Born cross section in the splitting.",
&ShowerApproximation::theBornScaleInSplitting, showerScale, false, false);
static SwitchOption interfaceBornScaleInSplittingRealScale
(interfaceBornScaleInSplitting,
"RealScale",
"Use the real emission scale.",
realScale);
static SwitchOption interfaceBornScaleInSplittingBornScale
(interfaceBornScaleInSplitting,
"BornScale",
"Use the Born scale.",
bornScale);
static SwitchOption interfaceBornScaleInSplittingShowerScale
(interfaceBornScaleInSplitting,
"ShowerScale",
"Use the shower scale",
showerScale);
static Switch<ShowerApproximation,int> interfaceEmissionScaleInSplitting
("EmissionScaleInSplitting",
"Set the scale choice for the emission in the splitting.",
&ShowerApproximation::theEmissionScaleInSplitting, showerScale, false, false);
static SwitchOption interfaceEmissionScaleInSplittingRealScale
(interfaceEmissionScaleInSplitting,
"RealScale",
"Use the real emission scale.",
realScale);
static SwitchOption interfaceEmissionScaleInSplittingEmissionScale
(interfaceEmissionScaleInSplitting,
"BornScale",
"Use the Born scale.",
bornScale);
static SwitchOption interfaceEmissionScaleInSplittingShowerScale
(interfaceEmissionScaleInSplitting,
"ShowerScale",
"Use the shower scale",
showerScale);
static Parameter<ShowerApproximation,Energy> interfaceRenormalizationScaleFreeze
("RenormalizationScaleFreeze",
"The freezing scale for the renormalization scale.",
&ShowerApproximation::theRenormalizationScaleFreeze, GeV, 1.0*GeV, 0.0*GeV, 0*GeV,
false, false, Interface::lowerlim);
static Parameter<ShowerApproximation,Energy> interfaceFactorizationScaleFreeze
("FactorizationScaleFreeze",
"The freezing scale for the factorization scale.",
&ShowerApproximation::theFactorizationScaleFreeze, GeV, 1.0*GeV, 0.0*GeV, 0*GeV,
false, false, Interface::lowerlim);
static Switch<ShowerApproximation,bool> interfaceProfileScales
("ProfileScales",
"Switch on or off use of profile scales.",
&ShowerApproximation::theProfileScales, true, false, false);
static SwitchOption interfaceProfileScalesYes
(interfaceProfileScales,
"Yes",
"Use profile scales.",
true);
static SwitchOption interfaceProfileScalesNo
(interfaceProfileScales,
"No",
"Use a hard cutoff.",
false);
static Parameter<ShowerApproximation,double> interfaceProfileRho
("ProfileRho",
"The rho parameter of the profile scales.",
&ShowerApproximation::theProfileRho, 0.3, 0.0, 1.0,
false, false, Interface::limited);
}

File Metadata

Mime Type
text/x-diff
Expires
Wed, May 14, 11:09 AM (17 h, 46 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
5092916
Default Alt Text
(222 KB)

Event Timeline