Page Menu
Home
HEPForge
Search
Configure Global Search
Log In
Files
F8725592
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Award Token
Flag For Later
Size
24 KB
Subscribers
None
View Options
diff --git a/MatrixElement/Matchbox/Phasespace/FlatInvertiblePhasespace.cc b/MatrixElement/Matchbox/Phasespace/FlatInvertiblePhasespace.cc
new file mode 100644
--- /dev/null
+++ b/MatrixElement/Matchbox/Phasespace/FlatInvertiblePhasespace.cc
@@ -0,0 +1,419 @@
+// -*- C++ -*-
+//
+// FlatInvertiblePhasespace.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 FlatInvertiblePhasespace class.
+//
+
+#include "FlatInvertiblePhasespace.h"
+#include "ThePEG/Interface/ClassDocumentation.h"
+#include "ThePEG/Interface/Switch.h"
+#include "ThePEG/EventRecord/Particle.h"
+#include "ThePEG/Repository/UseRandom.h"
+#include "ThePEG/Repository/EventGenerator.h"
+#include "ThePEG/Utilities/DescribeClass.h"
+#include "Herwig++/Utilities/GSLBisection.h"
+#include "ThePEG/Cuts/Cuts.h"
+
+#include "ThePEG/Persistency/PersistentOStream.h"
+#include "ThePEG/Persistency/PersistentIStream.h"
+
+using namespace Herwig;
+
+FlatInvertiblePhasespace::FlatInvertiblePhasespace() {}
+
+FlatInvertiblePhasespace::~FlatInvertiblePhasespace() {}
+
+IBPtr FlatInvertiblePhasespace::clone() const {
+ return new_ptr(*this);
+}
+
+IBPtr FlatInvertiblePhasespace::fullclone() const {
+ return new_ptr(*this);
+}
+
+void FlatInvertiblePhasespace::prepare(tStdXCombPtr xc, bool) {
+ theLastXComb = xc;
+}
+
+double FlatInvertiblePhasespace::bisect(double v, double n,
+ double target, double maxLevel) const {
+
+ if ( v != 0.0 && v != 1.0 ) {
+
+ double level = 0;
+ double left = 0;
+ double right = 1;
+
+ double checkV = -1.;
+ double u = -1;
+
+ while ( level < maxLevel ) {
+
+ u = (left+right)*pow(0.5,level+1.);
+ checkV =
+ pow(u,n+1.)*(n+2.-(n+1.)*u);
+
+ if ( log10(abs(1.-checkV/v)) <= target )
+ break;
+
+ left *= 2.;
+ right *= 2.;
+
+ if ( v <= checkV ) {
+ right -= 1.;
+ ++level;
+ }
+
+ if ( v > checkV ) {
+ left += 1.;
+ ++level;
+ }
+
+ }
+
+ return u;
+
+ }
+
+ return v;
+
+}
+
+static double flatWeights[7] = {
+
+ -1.,-1.,
+ 0.039788735772973833942,
+ 0.00012598255637968550463,
+ 1.3296564302788840628E-7,
+ 7.0167897579949011130E-11,
+ 2.2217170114046130768E-14
+
+};
+
+double FlatInvertiblePhasespace::generateIntermediates(vector<Energy>& K,
+ const double* r) const {
+
+ size_t n = K.size() + 1;
+ for ( size_t i = 2; i <= n-1; ++i ) {
+ double u = bisect(r[i-2],n-1-i);
+ K[i-1] = sqrt(u*sqr(K[i-2]));
+ }
+
+ return flatWeights[n];
+
+}
+
+double FlatInvertiblePhasespace::invertIntermediates(const vector<Energy>& K,
+ double* r) const {
+
+ size_t n = K.size() + 1;
+ for ( size_t i = 2; i <= n-1; ++i ) {
+ double u = sqr(K[i-1]/K[i-2]);
+ r[i-2] = (n+1-i)*pow(u,(double)(n-i)) - (n-i)*pow(u,(double)(n+1-i));
+ }
+
+ return flatWeights[n];
+
+}
+
+double FlatInvertiblePhasespace::generateIntermediates(vector<Energy>& M,
+ const vector<Energy>& m,
+ const double* r) const {
+
+ size_t n = M.size() + 1;
+
+ vector<Energy> K = M;
+ for ( size_t i = 1; i <= n; ++i )
+ K[0] -= m[i-1];
+
+ double w0 = generateIntermediates(K,r);
+
+ M = K;
+ for ( size_t i = 1; i <= n-1; ++i ) {
+ for ( size_t k = i; k <= n; ++k )
+ M[i-1] += m[k-1];
+ }
+
+ double weight = 8.*w0*rho(M[n-2],m[n-1],m[n-2]);
+
+ for ( size_t i = 2; i <= n-1; ++i ) {
+ weight *=
+ (rho(M[i-2],M[i-1],m[i-2])/rho(K[i-2],K[i-1],ZERO)) * (M[i-1]/K[i-1]);
+ }
+
+ weight *= pow(K[0]/M[0],2.*n-4.);
+
+ return weight;
+
+}
+
+double FlatInvertiblePhasespace::invertIntermediates(const vector<Energy>& M,
+ const vector<Energy>& m,
+ double* r) const {
+
+ size_t n = M.size() + 1;
+
+ vector<Energy> K = M;
+ for ( size_t i = 1; i <= n-1; ++i ) {
+ for ( size_t k = i; k <= n; ++k )
+ K[i-1] -= m[k-1];
+ }
+
+ double w0 = invertIntermediates(K,r);
+
+ double weight = 8.*w0*rho(M[n-2],m[n-1],m[n-2]);
+
+ for ( size_t i = 2; i <= n-1; ++i ) {
+ weight *=
+ (rho(M[i-2],M[i-1],m[i-2])/rho(K[i-2],K[i-1],ZERO)) * (M[i-1]/K[i-1]);
+ }
+
+ weight *= pow(K[0]/M[0],2.*n-4.);
+
+ return weight;
+
+}
+
+
+double FlatInvertiblePhasespace::generateKinematics(vector<Lorentz5Momentum>& P,
+ Energy Ecm,
+ const double* r) const {
+
+ vector<Energy> m;
+ for ( vector<Lorentz5Momentum>::const_iterator p =
+ P.begin(); p != P.end(); ++p )
+ m.push_back(p->mass());
+
+ size_t n = P.size();
+ vector<Energy> M(n-1);
+ M[0] = Ecm;
+
+ double weight = generateIntermediates(M,m,r);
+
+ M.push_back(m.back());
+
+ Lorentz5Momentum Q(M[0]);
+ Lorentz5Momentum nextQ;
+
+ for ( size_t i = 2; i <= n; ++i ) {
+
+ Energy q = 4.*M[i-2]*rho(M[i-2],M[i-1],m[i-2]);
+
+ double c = 2.*r[n-6+2*i]-1.;
+ double s = sqrt(1.-sqr(c));
+ double phi = 2.*Constants::pi*r[n-5+2*i];
+ double cphi = cos(phi);
+ double sphi = sqrt(1.-sqr(cphi));
+ if ( phi > Constants::pi )
+ sphi = -sphi;
+
+ P[i-2].setX(q*cphi*s);
+ P[i-2].setY(q*sphi*s);
+ P[i-2].setZ(q*c);
+ P[i-2].rescaleEnergy();
+ P[i-2].boost(Q.boostVector());
+ P[i-2].rescaleEnergy();
+
+ nextQ = Q - P[i-2];
+ nextQ.setMass(M[i-1]);
+ nextQ.rescaleEnergy();
+
+ Q = nextQ;
+
+ }
+
+ P.back() = Q;
+
+ return weight;
+
+}
+
+double FlatInvertiblePhasespace::invertKinematics(const vector<Lorentz5Momentum>& P,
+ Energy Ecm,
+ double* r) const {
+
+ vector<Energy> m;
+ for ( vector<Lorentz5Momentum>::const_iterator p =
+ P.begin(); p != P.end(); ++p )
+ m.push_back(p->mass());
+
+ size_t n = P.size();
+ vector<Energy> M(n-1);
+ M[0] = Ecm;
+
+ vector<Lorentz5Momentum> Q(n-1);
+ Q[0] = Lorentz5Momentum(M[0]);
+
+ for ( size_t i = 2; i <= n-1; ++i ) {
+ for ( size_t k = i; k <= n; ++k )
+ Q[i-1] += P[k-1];
+ M[i-1] = Q[i-1].m();
+ }
+
+ double weight = invertIntermediates(M,m,r);
+
+ for ( size_t i = 2; i <= n; ++i ) {
+ Lorentz5Momentum p = P[i-2];
+ p.boost(-Q[i-2].boostVector());
+ r[n-6+2*i] = (p.cosTheta()+1.)/2.;
+ double phi = p.phi();
+ if ( phi < 0. )
+ phi = 2.*Constants::pi + phi;
+ r[n-5+2*i] = phi/(2.*Constants::pi);
+ }
+
+ return weight;
+
+}
+
+
+double FlatInvertiblePhasespace::generateKinematics(const double* r,
+ vector<Lorentz5Momentum>& momenta) {
+
+ cPDVector::const_iterator pd = mePartonData().begin();
+ vector<Lorentz5Momentum>::iterator p = momenta.begin();
+ for ( ; pd != mePartonData().end(); ++pd, ++p )
+ p->setMass((**pd).mass());
+
+ Energy ECMMin = ZERO;
+ pd = mePartonData().begin() + 2;
+ for ( ; pd != mePartonData().end(); ++pd )
+ ECMMin += (**pd).mass();
+
+ double weight = 1.;
+
+ double tauMin = sqr(ECMMin)/lastXCombPtr()->lastS();
+ double tau = 1.;
+
+ if ( momenta.size() > 3 ) {
+ tau = tauMin + r[1]*(1.-tauMin);
+ } else {
+ tau = tauMin;
+ }
+
+ double ltau = log(tau)/2.;
+ weight *= -2.*ltau;
+
+ if ( momenta.size() > 3 ) {
+ weight *= 1.-tauMin;
+ } else {
+ weight *= 2.*Constants::pi;
+ }
+
+ double y = ltau - 2.*r[0]*ltau;
+ double x1 = sqrt(tau)*exp(y);
+ double x2 = sqrt(tau)*exp(-y);
+
+ ThreeVector<Energy> p1 =
+ x1*(lastXCombPtr()->lastParticles().first->momentum().vect());
+
+ ThreeVector<Energy> p2 =
+ x2*(lastXCombPtr()->lastParticles().second->momentum().vect());
+
+ momenta[0] = Lorentz5Momentum(momenta[0].mass(),p1);
+ momenta[1] = Lorentz5Momentum(momenta[1].mass(),p2);
+
+ lastXCombPtr()->lastX1X2(make_pair(x1,x2));
+ lastXCombPtr()->lastSHat((momenta[0]+momenta[1]).m2());
+
+ if ( momenta.size() == 3 ) {
+ ThreeVector<Energy> q = p1 + p2;
+ momenta[2] = Lorentz5Momentum(momenta[2].mass(),q);
+ return weight;
+ }
+
+ vector<Lorentz5Momentum> cmMomenta;
+ copy(momenta.begin()+2,momenta.end(),back_inserter(cmMomenta));
+
+ weight *= generateKinematics(cmMomenta,sqrt(lastXCombPtr()->lastSHat()),r+2);
+
+ Boost toLab = (momenta[0]+momenta[1]).boostVector();
+
+ vector<Lorentz5Momentum>::iterator pcm = cmMomenta.begin();
+ vector<Lorentz5Momentum>::iterator plab = momenta.begin() + 2;
+
+ for ( ; pcm != cmMomenta.end(); ++pcm, ++plab )
+ *plab = pcm->boost(toLab);
+
+ return weight;
+
+}
+
+double FlatInvertiblePhasespace::invertKinematics(const vector<Lorentz5Momentum>& momenta,
+ double* r) const {
+
+ Energy ECMMin = ZERO;
+ cPDVector::const_iterator pd = mePartonData().begin() + 2;
+ for ( ; pd != mePartonData().end(); ++pd )
+ ECMMin += (**pd).mass();
+
+ double weight = 1.;
+
+ double tauMin = sqr(ECMMin)/lastXCombPtr()->lastS();
+ double tau = lastXCombPtr()->lastTau();
+
+ if ( momenta.size() > 3 ) {
+ r[1] = (tau - tauMin)/(1.-tauMin);
+ }
+
+ double ltau = log(tau)/2.;
+ weight *= -2.*ltau;
+
+ if ( momenta.size() > 3 ) {
+ weight *= 1.-tauMin;
+ } else {
+ weight *= 2.*Constants::pi;
+ }
+
+ double y = lastXCombPtr()->lastY();
+ r[0] = (ltau - y)/(2.*ltau);
+
+ if ( momenta.size() == 3 )
+ return weight;
+
+ vector<Lorentz5Momentum> cmMomenta;
+ copy(momenta.begin()+2,momenta.end(),back_inserter(cmMomenta));
+
+ Boost toCM = -(momenta[0]+momenta[1]).boostVector();
+
+ for ( vector<Lorentz5Momentum>::iterator p = cmMomenta.begin();
+ p != cmMomenta.end(); ++p )
+ p->boost(toCM);
+
+ weight *= invertKinematics(cmMomenta,sqrt(lastXCombPtr()->lastSHat()),r+2);
+
+ return weight;
+
+}
+
+// If needed, insert default implementations of virtual function defined
+// in the InterfacedBase class here (using ThePEG-interfaced-impl in Emacs).
+
+
+void FlatInvertiblePhasespace::persistentOutput(PersistentOStream &) const {}
+
+void FlatInvertiblePhasespace::persistentInput(PersistentIStream &, int) {}
+
+
+// *** 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).
+DescribeClass<FlatInvertiblePhasespace,MatchboxPhasespace>
+ describeHerwigFlatInvertiblePhasespace("Herwig::FlatInvertiblePhasespace", "HwMatchbox.so");
+
+void FlatInvertiblePhasespace::Init() {
+
+ static ClassDocumentation<FlatInvertiblePhasespace> documentation
+ ("FlatInvertiblePhasespace implements flat, invertible phase space generation.");
+
+}
+
diff --git a/MatrixElement/Matchbox/Phasespace/FlatInvertiblePhasespace.h b/MatrixElement/Matchbox/Phasespace/FlatInvertiblePhasespace.h
new file mode 100644
--- /dev/null
+++ b/MatrixElement/Matchbox/Phasespace/FlatInvertiblePhasespace.h
@@ -0,0 +1,209 @@
+// -*- C++ -*-
+//
+// FlatInvertiblePhasespace.h 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.
+//
+#ifndef Herwig_FlatInvertiblePhasespace_H
+#define Herwig_FlatInvertiblePhasespace_H
+//
+// This is the declaration of the FlatInvertiblePhasespace class.
+//
+
+#include "Herwig++/MatrixElement/Matchbox/Phasespace/MatchboxPhasespace.h"
+
+namespace Herwig {
+
+using namespace ThePEG;
+
+/**
+ * \ingroup Matchbox
+ * \author Simon Platzer
+ *
+ * \brief FlatInvertiblePhasespace implements flat, invertible phase space generation.
+ *
+ */
+class FlatInvertiblePhasespace: public MatchboxPhasespace {
+
+public:
+
+ /** @name Standard constructors and destructors. */
+ //@{
+ /**
+ * The default constructor.
+ */
+ FlatInvertiblePhasespace();
+
+ /**
+ * The destructor.
+ */
+ virtual ~FlatInvertiblePhasespace();
+ //@}
+
+public:
+
+ /**
+ * Prepare a phase space generator for the given xcomb object.
+ */
+ virtual void prepare(tStdXCombPtr, bool verbose = false);
+
+ /**
+ * Generate a phase space point and return its weight.
+ */
+ virtual double generateKinematics(const double*,
+ vector<Lorentz5Momentum>& momenta);
+
+ /**
+ * Return the number of random numbers required to produce a given
+ * multiplicity final state.
+ */
+ virtual int nDim(int nFinal) const {
+ if ( nFinal == 1 )
+ return 1;
+ return 3*nFinal - 2;
+ }
+
+ /**
+ * Return true, if this phasespace generator will generate incoming
+ * partons itself.
+ */
+ virtual bool haveX1X2() const { return true; }
+
+ /**
+ * Return true, if this phase space generator expects
+ * the incoming partons in their center-of-mass system
+ */
+ virtual bool wantCMS() const { return false; }
+
+public:
+
+ /**
+ * Return true, if this phase space generator is invertible
+ */
+ virtual bool isInvertible() const { return true; }
+
+ /**
+ * Invert the given phase space point to the random numbers which
+ * would have generated it.
+ */
+ virtual double invertKinematics(const vector<Lorentz5Momentum>&,
+ double*) const;
+
+private:
+
+ /**
+ * Solve v = (n+2) * u^(n+1) - (n+1) * u^(n+2) for u
+ */
+ double bisect(double v, double n,
+ double target = -16., double maxLevel = 80.) const;
+
+ /**
+ * Return rho
+ */
+ double rho(Energy M, Energy N, Energy m) const {
+ return sqrt((sqr(M)-sqr(N+m))*(sqr(M)-sqr(N-m)))/(8.*sqr(M));
+ }
+
+ /**
+ * Generate intermediate masses for a massless final state
+ */
+ double generateIntermediates(vector<Energy>& K,
+ const double* r) const;
+
+ /**
+ * Invert intermediate masses for a massless final state
+ */
+ double invertIntermediates(const vector<Energy>& K,
+ double* r) const;
+
+ /**
+ * Generate intermediate masses for a massive final state
+ */
+ double generateIntermediates(vector<Energy>& M,
+ const vector<Energy>& m,
+ const double* r) const;
+
+ /**
+ * Invert intermediate masses for a massive final state
+ */
+ double invertIntermediates(const vector<Energy>& M,
+ const vector<Energy>& m,
+ double* r) const;
+
+ /**
+ * Generate momenta in the CMS
+ */
+ double generateKinematics(vector<Lorentz5Momentum>& P,
+ Energy Ecm,
+ const double* r) const;
+
+ /**
+ * Invert momenta in the CMS
+ */
+ double invertKinematics(const vector<Lorentz5Momentum>& P,
+ Energy Ecm,
+ double* r) const;
+
+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 assignment operator is private and must never be called.
+ * In fact, it should not even be implemented.
+ */
+ FlatInvertiblePhasespace & operator=(const FlatInvertiblePhasespace &);
+
+};
+
+}
+
+#endif /* Herwig_FlatInvertiblePhasespace_H */
diff --git a/MatrixElement/Matchbox/Phasespace/Makefile.am b/MatrixElement/Matchbox/Phasespace/Makefile.am
--- a/MatrixElement/Matchbox/Phasespace/Makefile.am
+++ b/MatrixElement/Matchbox/Phasespace/Makefile.am
@@ -1,50 +1,52 @@
if WANT_DIPOLE
noinst_LTLIBRARIES = libHwMatchboxPhasespace.la
endif
libHwMatchboxPhasespace_la_SOURCES = \
FFLightInvertedTildeKinematics.cc \
FFLightInvertedTildeKinematics.h \
FFLightTildeKinematics.cc \
FFLightTildeKinematics.h \
FFMassiveInvertedTildeKinematics.cc \
FFMassiveInvertedTildeKinematics.h \
FFMassiveTildeKinematics.cc \
FFMassiveTildeKinematics.h \
FILightInvertedTildeKinematics.cc \
FILightInvertedTildeKinematics.h \
FILightTildeKinematics.cc \
FILightTildeKinematics.h \
FIMassiveInvertedTildeKinematics.cc \
FIMassiveInvertedTildeKinematics.h \
FIMassiveTildeKinematics.cc \
FIMassiveTildeKinematics.h \
IFLightInvertedTildeKinematics.cc \
IFLightInvertedTildeKinematics.h \
IFLightTildeKinematics.cc \
IFLightTildeKinematics.h \
IFMassiveInvertedTildeKinematics.cc \
IFMassiveInvertedTildeKinematics.h \
IFMassiveTildeKinematics.cc \
IFMassiveTildeKinematics.h \
IILightInvertedTildeKinematics.cc \
IILightInvertedTildeKinematics.h \
IILightTildeKinematics.cc \
IILightTildeKinematics.h \
InvertedTildeKinematics.cc \
InvertedTildeKinematics.h \
MatchboxPhasespace.cc \
MatchboxPhasespace.h \
MatchboxRambo.cc \
MatchboxRambo.h \
PhasespaceHelpers.cc \
PhasespaceHelpers.h \
RandomHelpers.h \
TildeKinematics.cc \
TildeKinematics.h \
TreePhasespace.cc \
TreePhasespace.h \
TreePhasespaceChannels.cc \
TreePhasespaceChannels.h \
MatchboxReference.h \
-MatchboxReference.cc
+MatchboxReference.cc \
+FlatInvertiblePhasespace.h \
+FlatInvertiblePhasespace.cc
diff --git a/MatrixElement/Matchbox/Phasespace/MatchboxPhasespace.h b/MatrixElement/Matchbox/Phasespace/MatchboxPhasespace.h
--- a/MatrixElement/Matchbox/Phasespace/MatchboxPhasespace.h
+++ b/MatrixElement/Matchbox/Phasespace/MatchboxPhasespace.h
@@ -1,260 +1,276 @@
// -*- C++ -*-
//
// MatchboxPhasespace.h 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.
//
#ifndef HERWIG_MatchboxPhasespace_H
#define HERWIG_MatchboxPhasespace_H
//
// This is the declaration of the MatchboxPhasespace class.
//
#include "ThePEG/Handlers/StandardXComb.h"
#include "ThePEG/Handlers/HandlerBase.h"
#include "ThePEG/MatrixElement/Tree2toNDiagram.h"
namespace Herwig {
using namespace ThePEG;
/**
* \ingroup Matchbox
* \author Simon Platzer
*
* \brief Wrap around a vector of random numbers to behave as a stream
* of those.
*/
struct StreamingRnd {
/**
* The random numbers
*/
const double* numbers;
/**
* The number of random numbers available.
*/
size_t nRnd;
/**
* Default constructor.
*/
StreamingRnd()
: numbers(0), nRnd(0) {}
/**
* Construct from random numbers.
*/
explicit StreamingRnd(const double* newNumbers,
size_t n)
: numbers(newNumbers), nRnd(n) {}
/**
* Return next random number
*/
inline double operator()() {
assert(numbers && nRnd > 0);
const double ret = numbers[0];
++numbers; --nRnd;
return ret;
}
};
/**
* \ingroup Matchbox
* \author Simon Platzer
*
* \brief MatchboxPhasespace defines an abstract interface to a phase
* space generator.
*
*/
class MatchboxPhasespace:
public HandlerBase, public LastXCombInfo<StandardXComb> {
public:
/** @name Standard constructors and destructors. */
//@{
/**
* The default constructor.
*/
MatchboxPhasespace();
/**
* The destructor.
*/
virtual ~MatchboxPhasespace();
//@}
public:
/**
* Prepare a phase space generator for the given xcomb object.
*/
virtual void prepare(tStdXCombPtr, bool verbose = false) = 0;
/**
* Generate a phase space point and return its weight.
*/
virtual double generateKinematics(const double*,
vector<Lorentz5Momentum>& momenta) = 0;
/**
* Return the number of random numbers required to produce a given
* multiplicity final state.
*/
virtual int nDim(int nFinal) const = 0;
/**
* Return true, if this phasespace generator will generate incoming
* partons itself.
*/
virtual bool haveX1X2() const { return false; }
/**
* Return true, if this phase space generator expects
* the incoming partons in their center-of-mass system
*/
virtual bool wantCMS() const { return true; }
/**
* Fill a diagram selector for the last phase space point.
*/
virtual Selector<MEBase::DiagramIndex> selectDiagrams(const MEBase::DiagramVector&) const;
/**
* Return the momentum and weight appropriate to the given timelike
* branch of the diagram.
*/
pair<double,Lorentz5Momentum> timeLikeWeight(const Tree2toNDiagram& diag,
int branch, double flatCut) const;
/**
* Return the weight appropriate to the given spacelike branch of
* the diagram.
*/
double spaceLikeWeight(const Tree2toNDiagram& diag,
const Lorentz5Momentum& incoming,
int branch, double flatCut) const;
/**
* Return the weight appropriate to the given diagram.
*/
double diagramWeight(const Tree2toNDiagram& diag) const {
assert( !diagramWeights.empty() );
return diagramWeights.find(diag.id())->second;
}
/**
* Fill the diagram weights.
*/
void fillDiagramWeights(double flatCut = 0.0);
/**
* Clone this phase space generator.
*/
Ptr<MatchboxPhasespace>::ptr cloneMe() const {
return dynamic_ptr_cast<Ptr<MatchboxPhasespace>::ptr>(clone());
}
/**
* Clone the dependencies, using a given prefix.
*/
virtual void cloneDependencies(const std::string& prefix = "");
public:
/**
+ * Return true, if this phase space generator is invertible
+ */
+ virtual bool isInvertible() const { return false; }
+
+ /**
+ * Invert the given phase space point to the random numbers which
+ * would have generated it.
+ */
+ virtual double invertKinematics(const vector<Lorentz5Momentum>&,
+ double*) const {
+ return 0.;
+ }
+
+public:
+
+ /**
* Limit phasespace generation to a given collinear or soft limit.
*/
void singularLimit(size_t i, size_t j) {
if ( i > j )
swap(i,j);
singularLimits.insert(make_pair(i,j));
}
/**
* Return the last matched singular limit.
*/
const pair<size_t,size_t>& lastSingularLimit() const {
assert(theLastSingularLimit != singularLimits.end());
return *theLastSingularLimit;
}
/**
* Return true, if constraints on phasespace generation have been met.
*/
bool matchConstraints(const vector<Lorentz5Momentum>& momenta);
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);
//@}
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();
// If needed, insert declarations of virtual function defined in the
// InterfacedBase class here (using ThePEG-interfaced-decl in Emacs).
private:
/**
* The diagram weights indexed by diagram id.
*/
map<int,double> diagramWeights;
/**
* If not empty, the entries here serve to limit phasespace
* generation to the corresponding collinear limits, or soft limits
* if both pair entries are equal.
*/
set<pair<size_t,size_t> > singularLimits;
/**
* The last matched singular limit.
*/
set<pair<size_t,size_t> >::const_iterator theLastSingularLimit;
/**
* A cutoff below which a region is considered singular.
*/
Energy singularCutoff;
/**
* The assignment operator is private and must never be called.
* In fact, it should not even be implemented.
*/
MatchboxPhasespace & operator=(const MatchboxPhasespace &);
};
}
#endif /* HERWIG_MatchboxPhasespace_H */
File Metadata
Details
Attached
Mime Type
text/x-diff
Expires
Tue, Jan 21, 1:59 AM (1 d, 14 h)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
4243581
Default Alt Text
(24 KB)
Attached To
rHERWIGHG herwighg
Event Timeline
Log In to Comment