diff --git a/Hadronization/GluonMassGenerator.cc b/Hadronization/GluonMassGenerator.cc --- a/Hadronization/GluonMassGenerator.cc +++ b/Hadronization/GluonMassGenerator.cc @@ -1,63 +1,59 @@ // -*- C++ -*- // // GluonMassGenerator.cc is a part of Herwig - A multi-purpose Monte Carlo event generator // Copyright (C) 2002-2019 The Herwig Collaboration // // Herwig is licenced under version 3 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 GluonMassGenerator class. // #include "GluonMassGenerator.h" #include "ThePEG/Interface/ClassDocumentation.h" #include "ThePEG/EventRecord/Particle.h" #include "ThePEG/Repository/UseRandom.h" #include "ThePEG/Repository/EventGenerator.h" #include "ThePEG/Utilities/DescribeClass.h" #include "ThePEG/StandardModel/StandardModelBase.h" #include "ClusterHadronizationHandler.h" #include "ThePEG/Persistency/PersistentOStream.h" #include "ThePEG/Persistency/PersistentIStream.h" using namespace Herwig; -GluonMassGenerator::GluonMassGenerator() {} - -GluonMassGenerator::~GluonMassGenerator() {} - IBPtr GluonMassGenerator::clone() const { return new_ptr(*this); } IBPtr GluonMassGenerator::fullclone() const { return new_ptr(*this); } // If needed, insert default implementations of virtual function defined // in the InterfacedBase class here (using ThePEG-interfaced-impl in Emacs). void GluonMassGenerator::persistentOutput(PersistentOStream &) const {} void GluonMassGenerator::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 describeHerwigGluonMassGenerator("Herwig::GluonMassGenerator", ""); void GluonMassGenerator::Init() { static ClassDocumentation documentation ("Dynamic gluon mass generation"); } diff --git a/Hadronization/GluonMassGenerator.h b/Hadronization/GluonMassGenerator.h --- a/Hadronization/GluonMassGenerator.h +++ b/Hadronization/GluonMassGenerator.h @@ -1,171 +1,151 @@ // -*- C++ -*- // // GluonMassGenerator.h is a part of Herwig - A multi-purpose Monte Carlo event generator // Copyright (C) 2002-2019 The Herwig Collaboration // // Herwig is licenced under version 3 of the GPL, see COPYING for details. // Please respect the MCnet academic guidelines, see GUIDELINES for details. // #ifndef Herwig_GluonMassGenerator_H #define Herwig_GluonMassGenerator_H // // This is the declaration of the GluonMassGenerator class. // #include "ThePEG/Handlers/HandlerBase.h" #include "ThePEG/EventRecord/Particle.h" namespace Herwig { using namespace ThePEG; /** * \ingroup Hadronization * \brief Dynamic gluon mass generator; the default returns a constant mass. * * @see \ref GluonMassGeneratorInterfaces "The interfaces" * defined for GluonMassGenerator. */ class GluonMassGenerator: public HandlerBase { public: - /** @name Standard constructors and destructors. */ - //@{ - /** - * The default constructor. - */ - GluonMassGenerator(); - - /** - * The destructor. - */ - virtual ~GluonMassGenerator(); - //@} - -public: - /** * Generate a single gluon mass with possible reference to a hard * scale Q and up to a maximum value */ virtual Energy generate(Energy, Energy) const { return generate(); } /** * Generate a single gluon mass with possible reference to a hard * scale Q */ virtual Energy generate(Energy) const { return generate(); } /** * Generate a single gluon mass without further constraints */ virtual Energy generate() const { return getParticleData(ThePEG::ParticleID::g)->constituentMass(); } /** * Generate a list of n gluon masses, with a maximum available energy */ list generateMany(size_t n, Energy QMax) const { list res; Energy m0, mu, md, ms, mg, mgmax, summg; mu=getParticleData(ThePEG::ParticleID::u)->constituentMass(); md=getParticleData(ThePEG::ParticleID::d)->constituentMass(); ms=getParticleData(ThePEG::ParticleID::s)->constituentMass(); m0=md; if(mu QMax - 2.0*m0*(n-k-1) ){ repeat=true; break; } } } return res; } 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. */ - GluonMassGenerator & operator=(const GluonMassGenerator &); + GluonMassGenerator & operator=(const GluonMassGenerator &) = delete; }; } #endif /* Herwig_GluonMassGenerator_H */ diff --git a/MatrixElement/MEMultiChannel.cc b/MatrixElement/MEMultiChannel.cc --- a/MatrixElement/MEMultiChannel.cc +++ b/MatrixElement/MEMultiChannel.cc @@ -1,146 +1,146 @@ // -*- C++ -*- // // This is the implementation of the non-inlined, non-templated member // functions of the MEMultiChannel class. // #include "MEMultiChannel.h" #include "Herwig/Decay/DecayIntegrator.fh" #include "Herwig/Decay/PhaseSpaceMode.h" #include "ThePEG/Interface/ClassDocumentation.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 "ThePEG/PDT/EnumParticles.h" #include "ThePEG/MatrixElement/Tree2toNDiagram.h" #include "ThePEG/Cuts/Cuts.h" using namespace Herwig; MEMultiChannel::~MEMultiChannel() {} void MEMultiChannel::getDiagrams() const { int ndiag=0; channelMap_.clear(); for(PhaseSpaceModePtr mode : modes_) { channelMap_.push_back(map()); for(unsigned int ix=0;ixchannels().size();++ix) { ThePEG::Ptr::pointer diag = mode->channels()[ix].createDiagram(); ndiag+=1; diag = new_ptr((*diag,-ndiag)); channelMap_.back()[ndiag]= ix; add(diag); } } } Energy2 MEMultiChannel::scale() const { return sHat(); } int MEMultiChannel::nDim() const { return 0; // return modes_[0]->nRand(); } -bool MEMultiChannel::generateKinematics(const double * r) { +bool MEMultiChannel::generateKinematics(const double * ) { // first find the mode int imode = -1; for(unsigned int ix=0;ixoutgoing().size();++iy) { if(mePartonData()[iy+2]!=modes_[ix]->outgoing()[iy]) { matched=false; break; } } if(matched) { imode=ix; break; } } assert(imode>=0); // fill the stack of random numbers modes_[imode]->fillStack(); //modes_[imode]->fillStack(r); // generate the momenta int ichan; vector momenta(meMomenta().size()-2); Lorentz5Momentum pcm=meMomenta()[0]+meMomenta()[1]; Energy wgt = modes_[imode]->weight(ichan,pcm,momenta); // set the jacobian jacobian(wgt/sqrt(sHat())); // and momenta for(unsigned int ix=0;ix out(meMomenta().size()-2); for(unsigned int ix=2;ix MEMultiChannel::diagrams(const DiagramVector & diags) const { Selector sel; for ( DiagramIndex i = 0; i < diags.size(); ++i ) { double wgt = me2(channelMap_[iMode_][-diags[i]->id()] ); sel.insert(wgt, i); } return sel; } Selector MEMultiChannel::colourGeometries(tcDiagPtr ) const { static ColourLines none(""); Selector sel; sel.insert(1.0, &none); return sel; } void MEMultiChannel::persistentOutput(PersistentOStream & os) const { os << modes_ << channelMap_; } void MEMultiChannel::persistentInput(PersistentIStream & is, int) { is >> modes_ >> channelMap_; } // The following static variable is needed for the type // description system in ThePEG. DescribeAbstractClass describeHerwigMEMultiChannel("Herwig::MEMultiChannel", "Herwig.so"); void MEMultiChannel::Init() { static ClassDocumentation documentation ("There is no documentation for the MEMultiChannel class"); } void MEMultiChannel::doinit() { MEBase::doinit(); for(tPhaseSpaceModePtr mode : modes_) mode->init(); } void MEMultiChannel::doinitrun() { MEBase::doinitrun(); for(tPhaseSpaceModePtr mode : modes_) mode->initrun(); } diff --git a/MatrixElement/Matchbox/Dipoles/FFMggxDipole.cc b/MatrixElement/Matchbox/Dipoles/FFMggxDipole.cc --- a/MatrixElement/Matchbox/Dipoles/FFMggxDipole.cc +++ b/MatrixElement/Matchbox/Dipoles/FFMggxDipole.cc @@ -1,150 +1,148 @@ // -*- C++ -*- // // FFMggxDipole.cc is a part of Herwig - A multi-purpose Monte Carlo event generator // Copyright (C) 2002-2019 The Herwig Collaboration // // Herwig is licenced under version 3 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 FFMggxDipole class. // #include "FFMggxDipole.h" #include "ThePEG/Interface/ClassDocumentation.h" #include "ThePEG/Utilities/DescribeClass.h" #include "ThePEG/MatrixElement/Tree2toNDiagram.h" #include "ThePEG/StandardModel/StandardModelBase.h" #include "ThePEG/Persistency/PersistentOStream.h" #include "ThePEG/Persistency/PersistentIStream.h" #include "Herwig/MatrixElement/Matchbox/Base/DipoleRepository.h" #include "Herwig/MatrixElement/Matchbox/Utility/SpinCorrelationTensor.h" #include "Herwig/MatrixElement/Matchbox/Phasespace/FFMassiveTildeKinematics.h" #include "Herwig/MatrixElement/Matchbox/Phasespace/FFMassiveInvertedTildeKinematics.h" using namespace Herwig; FFMggxDipole::FFMggxDipole() : SubtractionDipole() {} -FFMggxDipole::~FFMggxDipole() {} - IBPtr FFMggxDipole::clone() const { return new_ptr(*this); } IBPtr FFMggxDipole::fullclone() const { return new_ptr(*this); } bool FFMggxDipole::canHandle(const cPDVector& partons, int emitter, int emission, int spectator) const { return emitter > 1 && spectator > 1 && partons[emission]->id() == ParticleID::g && partons[emitter]->id() == ParticleID::g && partons[spectator]->hardProcessMass() != ZERO; } double FFMggxDipole::me2Avg(double ccme2) const { if ( jacobian() == 0.0 ) return 0.0; double y = subtractionParameters()[0]; double z = subtractionParameters()[1]; // masses, g->gg all masses zero except spectator double muj2 = sqr( realEmissionME()->lastXComb().mePartonData()[realSpectator()]->hardProcessMass() / lastDipoleScale() ); // massive extra terms, viji = 1 double vijk = sqrt( sqr(2.*muj2+(1.-muj2)*(1.-y))-4.*muj2 ) / ((1.-muj2)*(1.-y)); Energy2 prop = 2.*((realEmissionME()->lastXComb().meMomenta()[realEmitter()])* (realEmissionME()->lastXComb().meMomenta()[realEmission()])); double zp = 0.5*(1.+vijk); double zm = 0.5*(1.-vijk); double res = -ccme2; // extra mass terms all = 0. res *= 16.*Constants::pi*SM().Nc()*(realEmissionME()->lastXComb().lastSHat())* (underlyingBornME()->lastXComb().lastAlphaS())/prop; res *= (1./(1-z*(1-y))+1./(1-(1.-z)*(1.-y))+(z*(1.-z)-zm*zp-2.)/vijk); res *= realEmissionME()->finalStateSymmetry() / underlyingBornME()->finalStateSymmetry(); return res; } double FFMggxDipole::me2() const { if ( jacobian() == 0.0 ) return 0.0; double y = subtractionParameters()[0]; double z = subtractionParameters()[1]; // masses, g->gg all masses zero except spectator double muj2 = sqr( realEmissionME()->lastXComb().mePartonData()[realSpectator()]->hardProcessMass() / lastDipoleScale() ); // massive extra terms double vijk = sqrt( sqr(2.*muj2+(1.-muj2)*(1.-y))-4.*muj2 ) / ((1.-muj2)*(1.-y)); Energy2 prop = 2.*((realEmissionME()->lastXComb().meMomenta()[realEmitter()])* (realEmissionME()->lastXComb().meMomenta()[realEmission()])); double diag = 1./(1-z*(1-y))+1./(1-(1.-z)*(1.-y))-2./vijk; // kappa=0 double zim = z-0.5*(1.-vijk), zjm = (1.-z)-0.5*(1.-vijk); Lorentz5Momentum pc = zim*realEmissionME()->lastXComb().meMomenta()[realEmitter()] - zjm*realEmissionME()->lastXComb().meMomenta()[realEmission()]; SpinCorrelationTensor corr(-diag,pc,prop/2.*vijk); double res = -underlyingBornME()->spinColourCorrelatedME2(make_pair(bornEmitter(),bornSpectator()), corr); // extra mass terms all = 0. res *= 16.*Constants::pi*SM().Nc()*(realEmissionME()->lastXComb().lastSHat())* (underlyingBornME()->lastXComb().lastAlphaS())/prop; res *= realEmissionME()->finalStateSymmetry() / underlyingBornME()->finalStateSymmetry(); return res; } void FFMggxDipole::persistentOutput(PersistentOStream &) const { } void FFMggxDipole::persistentInput(PersistentIStream &, int) { } void FFMggxDipole::Init() { static ClassDocumentation documentation ("FFMggxDipole"); DipoleRepository::registerDipole<0,FFMggxDipole,FFMassiveTildeKinematics,FFMassiveInvertedTildeKinematics> ("FFMggxDipole","FFMassiveTildeKinematics","FFMassiveInvertedTildeKinematics"); } // *** 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 describeHerwigFFMggxDipole("Herwig::FFMggxDipole", "Herwig.so"); diff --git a/MatrixElement/Matchbox/Dipoles/FFMggxDipole.h b/MatrixElement/Matchbox/Dipoles/FFMggxDipole.h --- a/MatrixElement/Matchbox/Dipoles/FFMggxDipole.h +++ b/MatrixElement/Matchbox/Dipoles/FFMggxDipole.h @@ -1,166 +1,158 @@ // -*- C++ -*- // // FFMggxDipole.h is a part of Herwig - A multi-purpose Monte Carlo event generator // Copyright (C) 2002-2019 The Herwig Collaboration // // Herwig is licenced under version 3 of the GPL, see COPYING for details. // Please respect the MCnet academic guidelines, see GUIDELINES for details. // #ifndef HERWIG_FFMggxDipole_H #define HERWIG_FFMggxDipole_H // // This is the declaration of the FFMggxDipole class. // #include "Herwig/MatrixElement/Matchbox/Dipoles/SubtractionDipole.h" namespace Herwig { using namespace ThePEG; /** * \ingroup Matchbox * \author Simon Platzer, Martin Stoll * * \brief FFMggxDipole implements the D_{g,g;k} subtraction dipole. * */ class FFMggxDipole: public SubtractionDipole { public: - /** @name Standard constructors and destructors. */ - //@{ /** * The default constructor. */ FFMggxDipole(); - /** - * The destructor. - */ - virtual ~FFMggxDipole(); - //@} - public: /** * Return true, if this dipole can possibly handle the indicated * emitter. */ virtual bool canHandleEmitter(const cPDVector& partons, int emitter) const { return emitter > 1 && partons[emitter]->id() == ParticleID::g; } /** * Return true, if this dipole can possibly handle the indicated * splitting. */ virtual bool canHandleSplitting(const cPDVector& partons, int emitter, int emission) const { return canHandleEmitter(partons,emitter) && partons[emission]->id() == ParticleID::g; } /** * Return true, if this dipole can possibly handle the indicated * spectator. */ virtual bool canHandleSpectator(const cPDVector& partons, int spectator) const { return spectator > 1 && partons[spectator]->coloured(); } /** * Return true, if this dipole applies to the selected * configuration. */ virtual bool canHandle(const cPDVector& partons, int emitter, int emission, int spectator) const; /** * Return true, if this dipole is symmetric with respect to emitter * and emission. */ virtual bool isSymmetric() const { return true; } /** * How to sample the z-distribution. * FlatZ = 1 * OneOverZ = 2 * OneOverOneMinusZ = 3 * OneOverZOneMinusZ = 4 */ virtual int samplingZ() const {return 4;} /** * Return the matrix element for the kinematical configuation * previously provided by the last call to setKinematics(), suitably * scaled by sHat() to give a dimension-less number. */ virtual double me2() const; /** * Return the matrix element averaged over spin correlations. */ virtual double me2Avg(double ccme2) 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. */ FFMggxDipole & operator=(const FFMggxDipole &) = delete; }; } #endif /* HERWIG_FFMggxDipole_H */ diff --git a/MatrixElement/Matchbox/Dipoles/FFMqgxDipole.cc b/MatrixElement/Matchbox/Dipoles/FFMqgxDipole.cc --- a/MatrixElement/Matchbox/Dipoles/FFMqgxDipole.cc +++ b/MatrixElement/Matchbox/Dipoles/FFMqgxDipole.cc @@ -1,156 +1,154 @@ // -*- C++ -*- // // FFMqgxDipole.cc is a part of Herwig - A multi-purpose Monte Carlo event generator // Copyright (C) 2002-2019 The Herwig Collaboration // // Herwig is licenced under version 3 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 FFMqgxDipole class. // #include "FFMqgxDipole.h" #include "ThePEG/Interface/ClassDocumentation.h" #include "ThePEG/Utilities/DescribeClass.h" #include "ThePEG/MatrixElement/Tree2toNDiagram.h" #include "ThePEG/StandardModel/StandardModelBase.h" #include "ThePEG/Persistency/PersistentOStream.h" #include "ThePEG/Persistency/PersistentIStream.h" #include "Herwig/MatrixElement/Matchbox/Base/DipoleRepository.h" #include "Herwig/MatrixElement/Matchbox/Phasespace/FFMassiveTildeKinematics.h" #include "Herwig/MatrixElement/Matchbox/Phasespace/FFMassiveInvertedTildeKinematics.h" using namespace Herwig; FFMqgxDipole::FFMqgxDipole() : SubtractionDipole() {} -FFMqgxDipole::~FFMqgxDipole() {} - IBPtr FFMqgxDipole::clone() const { return new_ptr(*this); } IBPtr FFMqgxDipole::fullclone() const { return new_ptr(*this); } bool FFMqgxDipole::canHandle(const cPDVector& partons, int emitter, int emission, int spectator) const { return emitter > 1 && spectator > 1 && partons[emission]->id() == ParticleID::g && // abs(partons[emitter]->id()) < 7 && ( abs(partons[emitter]->id()) < 7 || abs(partons[emitter]->id()) == 1000021 ) && !(partons[emitter]->hardProcessMass() == ZERO && partons[spectator]->hardProcessMass() == ZERO); } double FFMqgxDipole::me2Avg(double ccme2) const { if ( jacobian() == 0.0 ) return 0.0; double y = subtractionParameters()[0]; double z = subtractionParameters()[1]; // masses double muQ2 = sqr( realEmissionME()->lastXComb().mePartonData()[realEmitter()]->hardProcessMass() / lastDipoleScale() ); double muj2 = sqr( realEmissionME()->lastXComb().mePartonData()[realSpectator()]->hardProcessMass() / lastDipoleScale() ); // massive extra terms double vijk = sqrt( sqr(2.*muj2+(1.-muQ2-muj2)*(1.-y))-4.*muj2 ) / ((1.-muQ2-muj2)*(1.-y)); double vbar = sqrt( 1.+sqr(muQ2)+sqr(muj2)-2.*(muQ2+muj2+muQ2*muj2) ) / (1.-muQ2-muj2); Energy2 prop = 2.*((realEmissionME()->lastXComb().meMomenta()[realEmitter()])* (realEmissionME()->lastXComb().meMomenta()[realEmission()])); double CF = (SM().Nc()*SM().Nc()-1.)/(2.*SM().Nc()); if ( realEmissionME()->lastXComb().mePartonData()[realEmitter()]->id() == 1000021 ) CF = SM().Nc(); // For the SUSY D_{gluino,g;k} subtraction dipole we need to replace CF by CA=Nc // extra mass terms cancel: mi2+m2-Mi2 = mQ2+0-mQ2 double res = 8.*Constants::pi*CF*(realEmissionME()->lastXComb().lastSHat())* (underlyingBornME()->lastXComb().lastAlphaS())/prop; res *= ( 2./(1.-z*(1.-y)) - vbar/vijk * ( (1.+z) + muQ2*sqr(lastDipoleScale())*2./prop ) ); res *= -ccme2; res *= realEmissionME()->finalStateSymmetry() / underlyingBornME()->finalStateSymmetry(); return res; } double FFMqgxDipole::me2() const { if ( jacobian() == 0.0 ) return 0.0; double y = subtractionParameters()[0]; double z = subtractionParameters()[1]; // masses double muQ2 = sqr( realEmissionME()->lastXComb().mePartonData()[realEmitter()]->hardProcessMass() / lastDipoleScale() ); double muj2 = sqr( realEmissionME()->lastXComb().mePartonData()[realSpectator()]->hardProcessMass() / lastDipoleScale() ); // massive extra terms double vijk = sqrt( sqr(2.*muj2+(1.-muQ2-muj2)*(1.-y))-4.*muj2 ) / ((1.-muQ2-muj2)*(1.-y)); double vbar = sqrt( 1.+sqr(muQ2)+sqr(muj2)-2.*(muQ2+muj2+muQ2*muj2) ) / (1.-muQ2-muj2); Energy2 prop = 2.*((realEmissionME()->lastXComb().meMomenta()[realEmitter()])* (realEmissionME()->lastXComb().meMomenta()[realEmission()])); double CF = (SM().Nc()*SM().Nc()-1.)/(2.*SM().Nc()); if ( realEmissionME()->lastXComb().mePartonData()[realEmitter()]->id() == 1000021 ) CF = SM().Nc(); // For the SUSY D_{gluino,g;k} subtraction dipole we need to replace CF by CA=Nc // extra mass terms cancel: mi2+m2-Mi2 = mQ2+0-mQ2 double res = 8.*Constants::pi*CF*(realEmissionME()->lastXComb().lastSHat())* (underlyingBornME()->lastXComb().lastAlphaS())/prop; res *= ( 2./(1.-z*(1.-y)) - vbar/vijk * ( (1.+z) + muQ2*sqr(lastDipoleScale())*2./prop ) ); res *= -underlyingBornME()->colourCorrelatedME2(make_pair(bornEmitter(),bornSpectator())); res *= realEmissionME()->finalStateSymmetry() / underlyingBornME()->finalStateSymmetry(); return res; } void FFMqgxDipole::persistentOutput(PersistentOStream &) const { } void FFMqgxDipole::persistentInput(PersistentIStream &, int) { } void FFMqgxDipole::Init() { static ClassDocumentation documentation ("FFMqgxDipole"); DipoleRepository::registerDipole<0,FFMqgxDipole,FFMassiveTildeKinematics,FFMassiveInvertedTildeKinematics> ("FFMqgxDipole","FFMassiveTildeKinematics","FFMassiveInvertedTildeKinematics"); } // *** 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 describeHerwigFFMqgxDipole("Herwig::FFMqgxDipole", "Herwig.so"); diff --git a/MatrixElement/Matchbox/Dipoles/FFMqgxDipole.h b/MatrixElement/Matchbox/Dipoles/FFMqgxDipole.h --- a/MatrixElement/Matchbox/Dipoles/FFMqgxDipole.h +++ b/MatrixElement/Matchbox/Dipoles/FFMqgxDipole.h @@ -1,161 +1,153 @@ // -*- C++ -*- // // FFMqgxDipole.h is a part of Herwig - A multi-purpose Monte Carlo event generator // Copyright (C) 2002-2019 The Herwig Collaboration // // Herwig is licenced under version 3 of the GPL, see COPYING for details. // Please respect the MCnet academic guidelines, see GUIDELINES for details. // #ifndef HERWIG_FFMqgxDipole_H #define HERWIG_FFMqgxDipole_H // // This is the declaration of the FFMqgxDipole class. // #include "Herwig/MatrixElement/Matchbox/Dipoles/SubtractionDipole.h" namespace Herwig { using namespace ThePEG; /** * \ingroup Matchbox * \author Simon Platzer, Martin Stoll, Christian Reuschle * * \brief FFMqgxDipole implements the D_{Q,g;k} subtraction dipole, * as well as the D_{gluino,g;k} subtraction dipole. * */ class FFMqgxDipole: public SubtractionDipole { public: - /** @name Standard constructors and destructors. */ - //@{ /** * The default constructor. */ FFMqgxDipole(); - /** - * The destructor. - */ - virtual ~FFMqgxDipole(); - //@} - public: /** * Return true, if this dipole can possibly handle the indicated * emitter. */ virtual bool canHandleEmitter(const cPDVector& partons, int emitter) const { return emitter > 1 && abs(partons[emitter]->id()) < 7; } /** * Return true, if this dipole can possibly handle the indicated * splitting. */ virtual bool canHandleSplitting(const cPDVector& partons, int emitter, int emission) const { return canHandleEmitter(partons,emitter) && partons[emission]->id() == ParticleID::g; } /** * Return true, if this dipole can possibly handle the indicated * spectator. */ virtual bool canHandleSpectator(const cPDVector& partons, int spectator) const { return spectator > 1 && partons[spectator]->coloured(); } /** * Return true, if this dipole applies to the selected * configuration. */ virtual bool canHandle(const cPDVector& partons, int emitter, int emission, int spectator) const; /** * How to sample the z-distribution. * FlatZ = 1 * OneOverZ = 2 * OneOverOneMinusZ = 3 * OneOverZOneMinusZ = 4 */ virtual int samplingZ() const {return 3;} /** * Return the matrix element for the kinematical configuation * previously provided by the last call to setKinematics(), suitably * scaled by sHat() to give a dimension-less number. */ virtual double me2() const; /** * Return the matrix element averaged over spin correlations. */ virtual double me2Avg(double ccme2) 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. */ FFMqgxDipole & operator=(const FFMqgxDipole &) = delete; }; } #endif /* HERWIG_FFMqgxDipole_H */ diff --git a/MatrixElement/Matchbox/Dipoles/FFMqqxDipole.cc b/MatrixElement/Matchbox/Dipoles/FFMqqxDipole.cc --- a/MatrixElement/Matchbox/Dipoles/FFMqqxDipole.cc +++ b/MatrixElement/Matchbox/Dipoles/FFMqqxDipole.cc @@ -1,159 +1,157 @@ // -*- C++ -*- // // FFMqqxDipole.cc is a part of Herwig - A multi-purpose Monte Carlo event generator // Copyright (C) 2002-2019 The Herwig Collaboration // // Herwig is licenced under version 3 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 FFMqqxDipole class. // #include "FFMqqxDipole.h" #include "ThePEG/Interface/ClassDocumentation.h" #include "ThePEG/Utilities/DescribeClass.h" #include "ThePEG/MatrixElement/Tree2toNDiagram.h" #include "ThePEG/StandardModel/StandardModelBase.h" #include "ThePEG/Persistency/PersistentOStream.h" #include "ThePEG/Persistency/PersistentIStream.h" #include "Herwig/MatrixElement/Matchbox/Base/DipoleRepository.h" #include "Herwig/MatrixElement/Matchbox/Utility/SpinCorrelationTensor.h" #include "Herwig/MatrixElement/Matchbox/Phasespace/FFMassiveTildeKinematics.h" #include "Herwig/MatrixElement/Matchbox/Phasespace/FFMassiveInvertedTildeKinematics.h" using namespace Herwig; FFMqqxDipole::FFMqqxDipole() : SubtractionDipole() {} -FFMqqxDipole::~FFMqqxDipole() {} - IBPtr FFMqqxDipole::clone() const { return new_ptr(*this); } IBPtr FFMqqxDipole::fullclone() const { return new_ptr(*this); } bool FFMqqxDipole::canHandle(const cPDVector& partons, int emitter, int emission, int spectator) const { return emitter > 1 && spectator > 1 && abs(partons[emission]->id()) < 7 && abs(partons[emitter]->id()) < 7 && partons[emission]->id() + partons[emitter]->id() == 0 && !(partons[emission]->hardProcessMass() == ZERO && partons[emitter]->hardProcessMass() == ZERO && partons[spectator]->hardProcessMass() == ZERO); } double FFMqqxDipole::me2Avg(double ccme2) const { if ( jacobian() == 0.0 ) return 0.0; double y = subtractionParameters()[0]; double z = subtractionParameters()[1]; // masses double muQ2 = sqr( realEmissionME()->lastXComb().mePartonData()[realEmission()]->hardProcessMass() / lastDipoleScale() ); double muj2 = sqr( realEmissionME()->lastXComb().mePartonData()[realSpectator()]->hardProcessMass() / lastDipoleScale() ); Energy2 mQ2 = sqr( realEmissionME()->lastXComb().mePartonData()[realEmission()]->hardProcessMass() ); // massive extra terms double t = 1.-2.*muQ2-muj2; double vijk = sqrt( sqr(2.*muj2+t*(1.-y))-4.*muj2 ) / (t*(1.-y)); double viji = sqrt( sqr(t*y) - 4.*sqr(muQ2) ) / ( t*y + 2.*muQ2); Energy2 prop = 2.*((realEmissionME()->lastXComb().meMomenta()[realEmitter()])* (realEmissionME()->lastXComb().meMomenta()[realEmission()])); double zp = 0.5*(1.+viji*vijk); double zm = 0.5*(1.-viji*vijk); // kappa=0 -- otherwise: extra term double res = -ccme2; res *= (1.-2.*(z*(1-z)-zp*zm)); res *= 4.*Constants::pi*(realEmissionME()->lastXComb().lastSHat())* (underlyingBornME()->lastXComb().lastAlphaS())/ ((prop+2.*mQ2)*vijk); res *= realEmissionME()->finalStateSymmetry() / underlyingBornME()->finalStateSymmetry(); return res; } double FFMqqxDipole::me2() const { if ( jacobian() == 0.0 ) return 0.0; double y = subtractionParameters()[0]; double z = subtractionParameters()[1]; // masses double muQ2 = sqr( realEmissionME()->lastXComb().mePartonData()[realEmission()]->hardProcessMass() / lastDipoleScale() ); double muj2 = sqr( realEmissionME()->lastXComb().mePartonData()[realSpectator()]->hardProcessMass() / lastDipoleScale() ); Energy2 mQ2 = sqr( realEmissionME()->lastXComb().mePartonData()[realEmission()]->hardProcessMass() ); // massive extra terms double vijk = sqrt( sqr(2.*muj2+(1.-2.*muQ2-muj2)*(1.-y))-4.*muj2 ) / ((1.-2.*muQ2-muj2)*(1.-y)); Energy2 prop = 2.*((realEmissionME()->lastXComb().meMomenta()[realEmitter()])* (realEmissionME()->lastXComb().meMomenta()[realEmission()])); double zim = z-0.5*(1.-vijk), zjm = (1.-z)-0.5*(1.-vijk); Lorentz5Momentum pc = zim*realEmissionME()->lastXComb().meMomenta()[realEmitter()] - zjm*realEmissionME()->lastXComb().meMomenta()[realEmission()]; // kappa=0 -- otherwise: extra diagonal term (instead of just -1.) SpinCorrelationTensor corr(-1.,pc,-(prop+2.*mQ2)/4.); double res = -underlyingBornME()->spinColourCorrelatedME2(make_pair(bornEmitter(),bornSpectator()), corr); res *= 4.*Constants::pi*(realEmissionME()->lastXComb().lastSHat())* (underlyingBornME()->lastXComb().lastAlphaS())/ ((prop+2.*mQ2)*vijk); res *= realEmissionME()->finalStateSymmetry() / underlyingBornME()->finalStateSymmetry(); return res; } void FFMqqxDipole::persistentOutput(PersistentOStream &) const { } void FFMqqxDipole::persistentInput(PersistentIStream &, int) { } void FFMqqxDipole::Init() { static ClassDocumentation documentation ("FFMqqxDipole"); DipoleRepository::registerDipole<0,FFMqqxDipole,FFMassiveTildeKinematics,FFMassiveInvertedTildeKinematics> ("FFMqqxDipole","FFMassiveTildeKinematics","FFMassiveInvertedTildeKinematics"); } // *** 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 describeHerwigFFMqqxDipole("Herwig::FFMqqxDipole", "Herwig.so"); diff --git a/MatrixElement/Matchbox/Dipoles/FFMqqxDipole.h b/MatrixElement/Matchbox/Dipoles/FFMqqxDipole.h --- a/MatrixElement/Matchbox/Dipoles/FFMqqxDipole.h +++ b/MatrixElement/Matchbox/Dipoles/FFMqqxDipole.h @@ -1,168 +1,160 @@ // -*- C++ -*- // // FFMqqxDipole.h is a part of Herwig - A multi-purpose Monte Carlo event generator // Copyright (C) 2002-2019 The Herwig Collaboration // // Herwig is licenced under version 3 of the GPL, see COPYING for details. // Please respect the MCnet academic guidelines, see GUIDELINES for details. // #ifndef HERWIG_FFMqqxDipole_H #define HERWIG_FFMqqxDipole_H // // This is the declaration of the FFMqqxDipole class. // #include "Herwig/MatrixElement/Matchbox/Dipoles/SubtractionDipole.h" namespace Herwig { using namespace ThePEG; /** * \ingroup Matchbox * \author Simon Platzer, Martin Stoll * * \brief FFMqqxDipole implements the D_{q,qbar;k} subtraction dipole. * */ class FFMqqxDipole: public SubtractionDipole { public: - /** @name Standard constructors and destructors. */ - //@{ /** * The default constructor. */ FFMqqxDipole(); - /** - * The destructor. - */ - virtual ~FFMqqxDipole(); - //@} - public: /** * Return true, if this dipole can possibly handle the indicated * emitter. */ virtual bool canHandleEmitter(const cPDVector& partons, int emitter) const { return emitter > 1 && abs(partons[emitter]->id()) < 7; } /** * Return true, if this dipole can possibly handle the indicated * splitting. */ virtual bool canHandleSplitting(const cPDVector& partons, int emitter, int emission) const { return canHandleEmitter(partons,emitter) && partons[emitter]->id() + partons[emission]->id() == 0; } /** * Return true, if this dipole can possibly handle the indicated * spectator. */ virtual bool canHandleSpectator(const cPDVector& partons, int spectator) const { return spectator > 1 && partons[spectator]->coloured(); } /** * Return true, if this dipole applies to the selected * configuration. */ virtual bool canHandle(const cPDVector& partons, int emitter, int emission, int spectator) const; /** * How to sample the z-distribution. * FlatZ = 1 * OneOverZ = 2 * OneOverOneMinusZ = 3 * OneOverZOneMinusZ = 4 */ virtual int samplingZ() const {return 1;} /** * Return true, if this dipole is symmetric with respect to emitter * and emission. */ virtual bool isSymmetric() const { return true; } /** * Return the matrix element for the kinematical configuation * previously provided by the last call to setKinematics(), suitably * scaled by sHat() to give a dimension-less number. */ virtual double me2() const; /** * Return the matrix element averaged over spin correlations. */ virtual double me2Avg(double ccme2) 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. */ FFMqqxDipole & operator=(const FFMqqxDipole &) = delete; }; } #endif /* HERWIG_FFMqqxDipole_H */ diff --git a/MatrixElement/Matchbox/Dipoles/FFMsqgxDipole.cc b/MatrixElement/Matchbox/Dipoles/FFMsqgxDipole.cc --- a/MatrixElement/Matchbox/Dipoles/FFMsqgxDipole.cc +++ b/MatrixElement/Matchbox/Dipoles/FFMsqgxDipole.cc @@ -1,152 +1,150 @@ // -*- C++ -*- // // FFMsqgxDipole.cc is a part of Herwig - A multi-purpose Monte Carlo event generator // Copyright (C) 2002-2019 The Herwig Collaboration // // Herwig is licenced under version 3 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 FFMsqgxDipole class. // #include "FFMsqgxDipole.h" #include "ThePEG/Interface/ClassDocumentation.h" #include "ThePEG/Utilities/DescribeClass.h" #include "ThePEG/MatrixElement/Tree2toNDiagram.h" #include "ThePEG/StandardModel/StandardModelBase.h" #include "ThePEG/Persistency/PersistentOStream.h" #include "ThePEG/Persistency/PersistentIStream.h" #include "Herwig/MatrixElement/Matchbox/Base/DipoleRepository.h" #include "Herwig/MatrixElement/Matchbox/Phasespace/FFMassiveTildeKinematics.h" #include "Herwig/MatrixElement/Matchbox/Phasespace/FFMassiveInvertedTildeKinematics.h" using namespace Herwig; FFMsqgxDipole::FFMsqgxDipole() : SubtractionDipole() {} -FFMsqgxDipole::~FFMsqgxDipole() {} - IBPtr FFMsqgxDipole::clone() const { return new_ptr(*this); } IBPtr FFMsqgxDipole::fullclone() const { return new_ptr(*this); } bool FFMsqgxDipole::canHandle(const cPDVector& partons, int emitter, int emission, int spectator) const { return emitter > 1 && spectator > 1 && partons[emission]->id() == ParticleID::g && ((abs(partons[emitter]->id())> 1000000 && abs(partons[emitter]->id())< 1000007) || (abs(partons[emitter]->id())> 2000000 && abs(partons[emitter]->id())< 2000007)) && !(partons[emitter]->hardProcessMass() == ZERO && partons[spectator]->hardProcessMass() == ZERO); } double FFMsqgxDipole::me2Avg(double ccme2) const { if ( jacobian() == 0.0 ) return 0.0; double y = subtractionParameters()[0]; double z = subtractionParameters()[1]; // masses double muSQ2 = sqr( realEmissionME()->lastXComb().mePartonData()[realEmitter()]->hardProcessMass() / lastDipoleScale() ); double muj2 = sqr( realEmissionME()->lastXComb().mePartonData()[realSpectator()]->hardProcessMass() / lastDipoleScale() ); // massive extra terms double vijk = sqrt( sqr(2.*muj2+(1.-muSQ2-muj2)*(1.-y))-4.*muj2 ) / ((1.-muSQ2-muj2)*(1.-y)); double vbar = sqrt( 1.+sqr(muSQ2)+sqr(muj2)-2.*(muSQ2+muj2+muSQ2*muj2) ) / (1.-muSQ2-muj2); Energy2 prop = 2.*((realEmissionME()->lastXComb().meMomenta()[realEmitter()])* (realEmissionME()->lastXComb().meMomenta()[realEmission()])); double CF = (SM().Nc()*SM().Nc()-1.)/(2.*SM().Nc()); double res = 8.*Constants::pi*CF*(realEmissionME()->lastXComb().lastSHat())* (underlyingBornME()->lastXComb().lastAlphaS())/prop; res *= ( 2./(1.-z*(1.-y)) - vbar/vijk * ( 2. + muSQ2*sqr(lastDipoleScale())*2./prop )); res *= -ccme2; res *= realEmissionME()->finalStateSymmetry() / underlyingBornME()->finalStateSymmetry(); return res; } double FFMsqgxDipole::me2() const { if ( jacobian() == 0.0 ) return 0.0; double y = subtractionParameters()[0]; double z = subtractionParameters()[1]; // masses double muSQ2 = sqr( realEmissionME()->lastXComb().mePartonData()[realEmitter()]->hardProcessMass() / lastDipoleScale() ); double muj2 = sqr( realEmissionME()->lastXComb().mePartonData()[realSpectator()]->hardProcessMass() / lastDipoleScale() ); // massive extra terms double vijk = sqrt( sqr(2.*muj2+(1.-muSQ2-muj2)*(1.-y))-4.*muj2 ) / ((1.-muSQ2-muj2)*(1.-y)); double vbar = sqrt( 1.+sqr(muSQ2)+sqr(muj2)-2.*(muSQ2+muj2+muSQ2*muj2) ) / (1.-muSQ2-muj2); Energy2 prop = 2.*((realEmissionME()->lastXComb().meMomenta()[realEmitter()])* (realEmissionME()->lastXComb().meMomenta()[realEmission()])); double CF = (SM().Nc()*SM().Nc()-1.)/(2.*SM().Nc()); // extra mass terms cancel: mi2+m2-Mi2 = mQ2+0-mQ2 double res = 8.*Constants::pi*CF*(realEmissionME()->lastXComb().lastSHat())* (underlyingBornME()->lastXComb().lastAlphaS())/prop; res *= ( 2./(1.-z*(1.-y)) - vbar/vijk * ( 2. + muSQ2*sqr(lastDipoleScale())*2./prop ) ); res *= -underlyingBornME()->colourCorrelatedME2(make_pair(bornEmitter(),bornSpectator())); res *= realEmissionME()->finalStateSymmetry() / underlyingBornME()->finalStateSymmetry(); return res; } void FFMsqgxDipole::persistentOutput(PersistentOStream &) const { } void FFMsqgxDipole::persistentInput(PersistentIStream &, int) { } void FFMsqgxDipole::Init() { static ClassDocumentation documentation ("FFMsqgxDipole"); DipoleRepository::registerDipole<0,FFMsqgxDipole,FFMassiveTildeKinematics,FFMassiveInvertedTildeKinematics> ("FFMsqgxDipole","FFMassiveTildeKinematics","FFMassiveInvertedTildeKinematics"); } // *** 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 describeHerwigFFMsqgxDipole("Herwig::FFMsqgxDipole", "Herwig.so"); diff --git a/MatrixElement/Matchbox/Dipoles/FFMsqgxDipole.h b/MatrixElement/Matchbox/Dipoles/FFMsqgxDipole.h --- a/MatrixElement/Matchbox/Dipoles/FFMsqgxDipole.h +++ b/MatrixElement/Matchbox/Dipoles/FFMsqgxDipole.h @@ -1,164 +1,156 @@ // -*- C++ -*- // // FFMsqgxDipole.h is a part of Herwig - A multi-purpose Monte Carlo event generator // Copyright (C) 2002-2019 The Herwig Collaboration // // Herwig is licenced under version 3 of the GPL, see COPYING for details. // Please respect the MCnet academic guidelines, see GUIDELINES for details. // #ifndef HERWIG_FFMsqgxDipole_H #define HERWIG_FFMsqgxDipole_H // // This is the declaration of the FFMsqgxDipole class. // #include "Herwig/MatrixElement/Matchbox/Dipoles/SubtractionDipole.h" namespace Herwig { using namespace ThePEG; /** * \ingroup Matchbox * \author Simon Platzer, Alexandra Wilcock, Christian Reuschle * * \brief FFMsqgxDipole implements the D_{sq,g;k} subtraction dipole. * */ class FFMsqgxDipole: public SubtractionDipole { public: - /** @name Standard constructors and destructors. */ - //@{ /** * The default constructor. */ FFMsqgxDipole(); - /** - * The destructor. - */ - virtual ~FFMsqgxDipole(); - //@} - public: /** * Return true, if this dipole can possibly handle the indicated * emitter. */ virtual bool canHandleEmitter(const cPDVector& partons, int emitter) const { return emitter > 1 && (abs(abs(partons[emitter]->id()) - 1000000) < 7 || abs(abs(partons[emitter]->id()) - 2000000) < 7); } /** * Return true, if this dipole can possibly handle the indicated * splitting. */ virtual bool canHandleSplitting(const cPDVector& partons, int emitter, int emission) const { return canHandleEmitter(partons,emitter) && partons[emission]->id() == ParticleID::g; } /** * Return true, if this dipole can possibly handle the indicated * spectator. */ virtual bool canHandleSpectator(const cPDVector& partons, int spectator) const { return spectator > 1 && partons[spectator]->coloured(); } /** * Return true, if this dipole applies to the selected * configuration. */ virtual bool canHandle(const cPDVector& partons, int emitter, int emission, int spectator) const; /** * How to sample the z-distribution. * FlatZ = 1 * OneOverZ = 2 * OneOverOneMinusZ = 3 * OneOverZOneMinusZ = 4 */ virtual int samplingZ() const {return 3;} /** * Return the matrix element for the kinematical configuation * previously provided by the last call to setKinematics(), suitably * scaled by sHat() to give a dimension-less number. */ virtual double me2() const; /** * Return the matrix element averaged over spin correlations. */ virtual double me2Avg(double ccme2) 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. */ FFMsqgxDipole & operator=(const FFMsqgxDipole &) = delete; }; } #endif /* HERWIG_FFMsqgxDipole_H */ diff --git a/MatrixElement/Matchbox/Dipoles/FFggxDipole.cc b/MatrixElement/Matchbox/Dipoles/FFggxDipole.cc --- a/MatrixElement/Matchbox/Dipoles/FFggxDipole.cc +++ b/MatrixElement/Matchbox/Dipoles/FFggxDipole.cc @@ -1,138 +1,136 @@ // -*- C++ -*- // // FFggxDipole.cc is a part of Herwig - A multi-purpose Monte Carlo event generator // Copyright (C) 2002-2019 The Herwig Collaboration // // Herwig is licenced under version 3 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 FFggxDipole class. // #include "FFggxDipole.h" #include "ThePEG/Interface/ClassDocumentation.h" #include "ThePEG/Utilities/DescribeClass.h" #include "ThePEG/MatrixElement/Tree2toNDiagram.h" #include "ThePEG/StandardModel/StandardModelBase.h" #include "ThePEG/Persistency/PersistentOStream.h" #include "ThePEG/Persistency/PersistentIStream.h" #include "Herwig/MatrixElement/Matchbox/Base/DipoleRepository.h" #include "Herwig/MatrixElement/Matchbox/Utility/SpinCorrelationTensor.h" #include "Herwig/MatrixElement/Matchbox/Phasespace/FFLightTildeKinematics.h" #include "Herwig/MatrixElement/Matchbox/Phasespace/FFLightInvertedTildeKinematics.h" using namespace Herwig; FFggxDipole::FFggxDipole() : SubtractionDipole() {} -FFggxDipole::~FFggxDipole() {} - IBPtr FFggxDipole::clone() const { return new_ptr(*this); } IBPtr FFggxDipole::fullclone() const { return new_ptr(*this); } bool FFggxDipole::canHandle(const cPDVector& partons, int emitter, int emission, int spectator) const { return emitter > 1 && spectator > 1 && partons[emission]->id() == ParticleID::g && partons[emitter]->id() == ParticleID::g && partons[spectator]->hardProcessMass() == ZERO; } double FFggxDipole::me2Avg(double ccme2) const { if ( jacobian() == 0.0 ) return 0.0; double y = subtractionParameters()[0]; double z = subtractionParameters()[1]; Energy2 prop = 2.*((realEmissionME()->lastXComb().meMomenta()[realEmitter()])* (realEmissionME()->lastXComb().meMomenta()[realEmission()])); double res = 1./(1.-z*(1.-y)) + 1./(1.-(1.-z)*(1.-y)) - 2. + z*(1.-z); res *= -ccme2; res *= 16.*Constants::pi*SM().Nc()*(realEmissionME()->lastXComb().lastSHat())* (underlyingBornME()->lastXComb().lastAlphaS())/prop; res *= realEmissionME()->finalStateSymmetry() / underlyingBornME()->finalStateSymmetry(); return res; } double FFggxDipole::me2() const { if ( jacobian() == 0.0 ) return 0.0; double y = subtractionParameters()[0]; double z = subtractionParameters()[1]; if ( alpha() < y ) return 0.0; Energy2 prop = 2.*((realEmissionME()->lastXComb().meMomenta()[realEmitter()])* (realEmissionME()->lastXComb().meMomenta()[realEmission()])); double diag = 1./(1.-z*(1.-y))+1./(1.-(1.-z)*(1.-y))-2.; Lorentz5Momentum pc = z*realEmissionME()->lastXComb().meMomenta()[realEmitter()] - (1.-z)*realEmissionME()->lastXComb().meMomenta()[realEmission()]; SpinCorrelationTensor corr(-diag,pc,prop/2.); double res = -underlyingBornME()->spinColourCorrelatedME2(make_pair(bornEmitter(),bornSpectator()), corr); res *= 16.*Constants::pi*SM().Nc()*(realEmissionME()->lastXComb().lastSHat())* (underlyingBornME()->lastXComb().lastAlphaS())/prop; res *= realEmissionME()->finalStateSymmetry() / underlyingBornME()->finalStateSymmetry(); return res; } void FFggxDipole::persistentOutput(PersistentOStream &) const { } void FFggxDipole::persistentInput(PersistentIStream &, int) { } void FFggxDipole::Init() { static ClassDocumentation documentation ("FFggxDipole"); DipoleRepository::registerDipole<0,FFggxDipole,FFLightTildeKinematics,FFLightInvertedTildeKinematics> ("FFggxDipole","FFLightTildeKinematics","FFLightInvertedTildeKinematics"); } // *** 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 describeHerwigFFggxDipole("Herwig::FFggxDipole", "Herwig.so"); diff --git a/MatrixElement/Matchbox/Dipoles/FFggxDipole.h b/MatrixElement/Matchbox/Dipoles/FFggxDipole.h --- a/MatrixElement/Matchbox/Dipoles/FFggxDipole.h +++ b/MatrixElement/Matchbox/Dipoles/FFggxDipole.h @@ -1,167 +1,159 @@ // -*- C++ -*- // // FFggxDipole.h is a part of Herwig - A multi-purpose Monte Carlo event generator // Copyright (C) 2002-2019 The Herwig Collaboration // // Herwig is licenced under version 3 of the GPL, see COPYING for details. // Please respect the MCnet academic guidelines, see GUIDELINES for details. // #ifndef HERWIG_FFggxDipole_H #define HERWIG_FFggxDipole_H // // This is the declaration of the FFggxDipole class. // #include "Herwig/MatrixElement/Matchbox/Dipoles/SubtractionDipole.h" namespace Herwig { using namespace ThePEG; /** * \ingroup Matchbox * \author Simon Platzer * * \brief FFggxDipole implements the D_{g,g;k} subtraction dipole. * */ class FFggxDipole: public SubtractionDipole { public: - /** @name Standard constructors and destructors. */ - //@{ /** * The default constructor. */ FFggxDipole(); - /** - * The destructor. - */ - virtual ~FFggxDipole(); - //@} - public: /** * Return true, if this dipole can possibly handle the indicated * emitter. */ virtual bool canHandleEmitter(const cPDVector& partons, int emitter) const { return emitter > 1 && partons[emitter]->id() == ParticleID::g; } /** * Return true, if this dipole can possibly handle the indicated * splitting. */ virtual bool canHandleSplitting(const cPDVector& partons, int emitter, int emission) const { return canHandleEmitter(partons,emitter) && partons[emission]->id() == ParticleID::g; } /** * Return true, if this dipole can possibly handle the indicated * spectator. */ virtual bool canHandleSpectator(const cPDVector& partons, int spectator) const { return spectator > 1 && partons[spectator]->coloured(); } /** * Return true, if this dipole applies to the selected * configuration. */ virtual bool canHandle(const cPDVector& partons, int emitter, int emission, int spectator) const; /** * Return true, if this dipole is symmetric with respect to emitter * and emission. */ virtual bool isSymmetric() const { return true; } /** * How to sample the z-distribution. * FlatZ = 1 * OneOverZ = 2 * OneOverOneMinusZ = 3 * OneOverZOneMinusZ = 4 */ virtual int samplingZ() const {return 4;} /** * Return the matrix element for the kinematical configuation * previously provided by the last call to setKinematics(), suitably * scaled by sHat() to give a dimension-less number. */ virtual double me2() const; /** * Return the matrix element averaged over spin correlations. */ virtual double me2Avg(double ccme2) 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. */ FFggxDipole & operator=(const FFggxDipole &) = delete; }; } #endif /* HERWIG_FFggxDipole_H */ diff --git a/MatrixElement/Matchbox/Dipoles/FFqgxDipole.cc b/MatrixElement/Matchbox/Dipoles/FFqgxDipole.cc --- a/MatrixElement/Matchbox/Dipoles/FFqgxDipole.cc +++ b/MatrixElement/Matchbox/Dipoles/FFqgxDipole.cc @@ -1,137 +1,135 @@ // -*- C++ -*- // // FFqgxDipole.cc is a part of Herwig - A multi-purpose Monte Carlo event generator // Copyright (C) 2002-2019 The Herwig Collaboration // // Herwig is licenced under version 3 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 FFqgxDipole class. // #include "FFqgxDipole.h" #include "ThePEG/Interface/ClassDocumentation.h" #include "ThePEG/Utilities/DescribeClass.h" #include "ThePEG/MatrixElement/Tree2toNDiagram.h" #include "ThePEG/StandardModel/StandardModelBase.h" #include "ThePEG/Persistency/PersistentOStream.h" #include "ThePEG/Persistency/PersistentIStream.h" #include "Herwig/MatrixElement/Matchbox/Base/DipoleRepository.h" #include "Herwig/MatrixElement/Matchbox/Phasespace/FFLightTildeKinematics.h" #include "Herwig/MatrixElement/Matchbox/Phasespace/FFLightInvertedTildeKinematics.h" using namespace Herwig; FFqgxDipole::FFqgxDipole() : SubtractionDipole() {} -FFqgxDipole::~FFqgxDipole() {} - IBPtr FFqgxDipole::clone() const { return new_ptr(*this); } IBPtr FFqgxDipole::fullclone() const { return new_ptr(*this); } bool FFqgxDipole::canHandle(const cPDVector& partons, int emitter, int emission, int spectator) const { return emitter > 1 && spectator > 1 && partons[emission]->id() == ParticleID::g && abs(partons[emitter]->id()) < 6 && partons[emitter]->hardProcessMass() == ZERO && partons[spectator]->hardProcessMass() == ZERO; } double FFqgxDipole::me2Avg(double ccme2) const { if ( jacobian() == 0.0 ) return 0.0; double y = subtractionParameters()[0]; double z = subtractionParameters()[1]; Energy2 prop = 2.*((realEmissionME()->lastXComb().meMomenta()[realEmitter()])* (realEmissionME()->lastXComb().meMomenta()[realEmission()])); double CF = (SM().Nc()*SM().Nc()-1.)/(2.*SM().Nc()); double res = 8.*Constants::pi*CF*(realEmissionME()->lastXComb().lastSHat())* (underlyingBornME()->lastXComb().lastAlphaS())/prop; res *= ( 2./(1.-z*(1.-y)) - (1.+z) ); res *= -ccme2; res *= realEmissionME()->finalStateSymmetry() / underlyingBornME()->finalStateSymmetry(); return res; } double FFqgxDipole::me2() const { if ( jacobian() == 0.0 ) return 0.0; double y = subtractionParameters()[0]; double z = subtractionParameters()[1]; if ( alpha() < y ) return 0.0; Energy2 prop = 2.*((realEmissionME()->lastXComb().meMomenta()[realEmitter()])* (realEmissionME()->lastXComb().meMomenta()[realEmission()])); double CF = (SM().Nc()*SM().Nc()-1.)/(2.*SM().Nc()); double res = 8.*Constants::pi*CF*(realEmissionME()->lastXComb().lastSHat())* (underlyingBornME()->lastXComb().lastAlphaS())/prop; res *= ( 2./(1.-z*(1.-y)) - (1.+z) ); res *= -underlyingBornME()->colourCorrelatedME2(make_pair(bornEmitter(),bornSpectator())); res *= realEmissionME()->finalStateSymmetry() / underlyingBornME()->finalStateSymmetry(); return res; } void FFqgxDipole::persistentOutput(PersistentOStream &) const { } void FFqgxDipole::persistentInput(PersistentIStream &, int) { } void FFqgxDipole::Init() { static ClassDocumentation documentation ("FFqgxDipole"); DipoleRepository::registerDipole<0,FFqgxDipole,FFLightTildeKinematics,FFLightInvertedTildeKinematics> ("FFqgxDipole","FFLightTildeKinematics","FFLightInvertedTildeKinematics"); } // *** 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 describeHerwigFFqgxDipole("Herwig::FFqgxDipole", "Herwig.so"); diff --git a/MatrixElement/Matchbox/Dipoles/FFqgxDipole.h b/MatrixElement/Matchbox/Dipoles/FFqgxDipole.h --- a/MatrixElement/Matchbox/Dipoles/FFqgxDipole.h +++ b/MatrixElement/Matchbox/Dipoles/FFqgxDipole.h @@ -1,160 +1,152 @@ // -*- C++ -*- // // FFqgxDipole.h is a part of Herwig - A multi-purpose Monte Carlo event generator // Copyright (C) 2002-2019 The Herwig Collaboration // // Herwig is licenced under version 3 of the GPL, see COPYING for details. // Please respect the MCnet academic guidelines, see GUIDELINES for details. // #ifndef HERWIG_FFqgxDipole_H #define HERWIG_FFqgxDipole_H // // This is the declaration of the FFqgxDipole class. // #include "Herwig/MatrixElement/Matchbox/Dipoles/SubtractionDipole.h" namespace Herwig { using namespace ThePEG; /** * \ingroup Matchbox * \author Simon Platzer * * \brief FFqgxDipole implements the D_{q,g;k} subtraction dipole. * */ class FFqgxDipole: public SubtractionDipole { public: - /** @name Standard constructors and destructors. */ - //@{ /** * The default constructor. */ FFqgxDipole(); - /** - * The destructor. - */ - virtual ~FFqgxDipole(); - //@} - public: /** * Return true, if this dipole can possibly handle the indicated * emitter. */ virtual bool canHandleEmitter(const cPDVector& partons, int emitter) const { return emitter > 1 && abs(partons[emitter]->id()) < 7; } /** * Return true, if this dipole can possibly handle the indicated * splitting. */ virtual bool canHandleSplitting(const cPDVector& partons, int emitter, int emission) const { return canHandleEmitter(partons,emitter) && partons[emission]->id() == ParticleID::g; } /** * Return true, if this dipole can possibly handle the indicated * spectator. */ virtual bool canHandleSpectator(const cPDVector& partons, int spectator) const { return spectator > 1 && partons[spectator]->coloured(); } /** * Return true, if this dipole applies to the selected * configuration. */ virtual bool canHandle(const cPDVector& partons, int emitter, int emission, int spectator) const; /** * How to sample the z-distribution. * FlatZ = 1 * OneOverZ = 2 * OneOverOneMinusZ = 3 * OneOverZOneMinusZ = 4 */ virtual int samplingZ() const {return 3;} /** * Return the matrix element for the kinematical configuation * previously provided by the last call to setKinematics(), suitably * scaled by sHat() to give a dimension-less number. */ virtual double me2() const; /** * Return the matrix element averaged over spin correlations. */ virtual double me2Avg(double ccme2) 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. */ FFqgxDipole & operator=(const FFqgxDipole &) = delete; }; } #endif /* HERWIG_FFqgxDipole_H */ diff --git a/MatrixElement/Matchbox/Dipoles/FFqqxDipole.cc b/MatrixElement/Matchbox/Dipoles/FFqqxDipole.cc --- a/MatrixElement/Matchbox/Dipoles/FFqqxDipole.cc +++ b/MatrixElement/Matchbox/Dipoles/FFqqxDipole.cc @@ -1,138 +1,136 @@ // -*- C++ -*- // // FFqqxDipole.cc is a part of Herwig - A multi-purpose Monte Carlo event generator // Copyright (C) 2002-2019 The Herwig Collaboration // // Herwig is licenced under version 3 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 FFqqxDipole class. // #include "FFqqxDipole.h" #include "ThePEG/Interface/ClassDocumentation.h" #include "ThePEG/Utilities/DescribeClass.h" #include "ThePEG/MatrixElement/Tree2toNDiagram.h" #include "ThePEG/StandardModel/StandardModelBase.h" #include "ThePEG/Persistency/PersistentOStream.h" #include "ThePEG/Persistency/PersistentIStream.h" #include "Herwig/MatrixElement/Matchbox/Base/DipoleRepository.h" #include "Herwig/MatrixElement/Matchbox/Utility/SpinCorrelationTensor.h" #include "Herwig/MatrixElement/Matchbox/Phasespace/FFLightTildeKinematics.h" #include "Herwig/MatrixElement/Matchbox/Phasespace/FFLightInvertedTildeKinematics.h" using namespace Herwig; FFqqxDipole::FFqqxDipole() : SubtractionDipole() {} -FFqqxDipole::~FFqqxDipole() {} - IBPtr FFqqxDipole::clone() const { return new_ptr(*this); } IBPtr FFqqxDipole::fullclone() const { return new_ptr(*this); } bool FFqqxDipole::canHandle(const cPDVector& partons, int emitter, int emission, int spectator) const { return emitter > 1 && spectator > 1 && abs(partons[emission]->id()) < 6 && abs(partons[emitter]->id()) < 6 && partons[emission]->id() + partons[emitter]->id() == 0 && partons[emitter]->hardProcessMass() == ZERO && partons[emission]->hardProcessMass() == ZERO && partons[spectator]->hardProcessMass() == ZERO; } double FFqqxDipole::me2Avg(double ccme2) const { if ( jacobian() == 0.0 ) return 0.0; double z = subtractionParameters()[1]; Energy2 prop = 2.*((realEmissionME()->lastXComb().meMomenta()[realEmitter()])* (realEmissionME()->lastXComb().meMomenta()[realEmission()])); double res = 1.-2.*z*(1.-z); res *= -ccme2; res *= 4.*Constants::pi*(realEmissionME()->lastXComb().lastSHat())* (underlyingBornME()->lastXComb().lastAlphaS())/prop; res *= realEmissionME()->finalStateSymmetry() / underlyingBornME()->finalStateSymmetry(); return res; } double FFqqxDipole::me2() const { if ( jacobian() == 0.0 ) return 0.0; double y = subtractionParameters()[0]; double z = subtractionParameters()[1]; if ( alpha() < y ) return 0.0; Energy2 prop = 2.*((realEmissionME()->lastXComb().meMomenta()[realEmitter()])* (realEmissionME()->lastXComb().meMomenta()[realEmission()])); Lorentz5Momentum pc = z*realEmissionME()->lastXComb().meMomenta()[realEmitter()] - (1.-z)*realEmissionME()->lastXComb().meMomenta()[realEmission()]; SpinCorrelationTensor corr(-1.,pc,-prop/4.); double res = -underlyingBornME()->spinColourCorrelatedME2(make_pair(bornEmitter(),bornSpectator()), corr); res *= 4.*Constants::pi*(realEmissionME()->lastXComb().lastSHat())* (underlyingBornME()->lastXComb().lastAlphaS())/prop; res *= realEmissionME()->finalStateSymmetry() / underlyingBornME()->finalStateSymmetry(); return res; } void FFqqxDipole::persistentOutput(PersistentOStream &) const { } void FFqqxDipole::persistentInput(PersistentIStream &, int) { } void FFqqxDipole::Init() { static ClassDocumentation documentation ("FFqqxDipole"); DipoleRepository::registerDipole<0,FFqqxDipole,FFLightTildeKinematics,FFLightInvertedTildeKinematics> ("FFqqxDipole","FFLightTildeKinematics","FFLightInvertedTildeKinematics"); } // *** 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 describeHerwigFFqqxDipole("Herwig::FFqqxDipole", "Herwig.so"); diff --git a/MatrixElement/Matchbox/Dipoles/FFqqxDipole.h b/MatrixElement/Matchbox/Dipoles/FFqqxDipole.h --- a/MatrixElement/Matchbox/Dipoles/FFqqxDipole.h +++ b/MatrixElement/Matchbox/Dipoles/FFqqxDipole.h @@ -1,168 +1,160 @@ // -*- C++ -*- // // FFqqxDipole.h is a part of Herwig - A multi-purpose Monte Carlo event generator // Copyright (C) 2002-2019 The Herwig Collaboration // // Herwig is licenced under version 3 of the GPL, see COPYING for details. // Please respect the MCnet academic guidelines, see GUIDELINES for details. // #ifndef HERWIG_FFqqxDipole_H #define HERWIG_FFqqxDipole_H // // This is the declaration of the FFqqxDipole class. // #include "Herwig/MatrixElement/Matchbox/Dipoles/SubtractionDipole.h" namespace Herwig { using namespace ThePEG; /** * \ingroup Matchbox * \author Simon Platzer * * \brief FFqqxDipole implements the D_{q,qbar;k} subtraction dipole. * */ class FFqqxDipole: public SubtractionDipole { public: - /** @name Standard constructors and destructors. */ - //@{ /** * The default constructor. */ FFqqxDipole(); - /** - * The destructor. - */ - virtual ~FFqqxDipole(); - //@} - public: /** * Return true, if this dipole can possibly handle the indicated * emitter. */ virtual bool canHandleEmitter(const cPDVector& partons, int emitter) const { return emitter > 1 && abs(partons[emitter]->id()) < 7; } /** * Return true, if this dipole can possibly handle the indicated * splitting. */ virtual bool canHandleSplitting(const cPDVector& partons, int emitter, int emission) const { return canHandleEmitter(partons,emitter) && partons[emitter]->id() + partons[emission]->id() == 0; } /** * Return true, if this dipole can possibly handle the indicated * spectator. */ virtual bool canHandleSpectator(const cPDVector& partons, int spectator) const { return spectator > 1 && partons[spectator]->coloured(); } /** * Return true, if this dipole applies to the selected * configuration. */ virtual bool canHandle(const cPDVector& partons, int emitter, int emission, int spectator) const; /** * How to sample the z-distribution. * FlatZ = 1 * OneOverZ = 2 * OneOverOneMinusZ = 3 * OneOverZOneMinusZ = 4 */ virtual int samplingZ() const {return 1;} /** * Return true, if this dipole is symmetric with respect to emitter * and emission. */ virtual bool isSymmetric() const { return true; } /** * Return the matrix element for the kinematical configuation * previously provided by the last call to setKinematics(), suitably * scaled by sHat() to give a dimension-less number. */ virtual double me2() const; /** * Return the matrix element averaged over spin correlations. */ virtual double me2Avg(double ccme2) 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. */ FFqqxDipole & operator=(const FFqqxDipole &) = delete; }; } #endif /* HERWIG_FFqqxDipole_H */ diff --git a/MatrixElement/Matchbox/Dipoles/FIMqgxDipole.cc b/MatrixElement/Matchbox/Dipoles/FIMqgxDipole.cc --- a/MatrixElement/Matchbox/Dipoles/FIMqgxDipole.cc +++ b/MatrixElement/Matchbox/Dipoles/FIMqgxDipole.cc @@ -1,167 +1,165 @@ // -*- C++ -*- // // FIqgxDipole.cc is a part of Herwig - A multi-purpose Monte Carlo event generator // Copyright (C) 2002-2019 The Herwig Collaboration // // Herwig is licenced under version 3 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 FIMqgxDipole class. // #include "FIMqgxDipole.h" #include "ThePEG/Interface/ClassDocumentation.h" #include "ThePEG/Utilities/DescribeClass.h" #include "ThePEG/MatrixElement/Tree2toNDiagram.h" #include "ThePEG/StandardModel/StandardModelBase.h" #include "ThePEG/Persistency/PersistentOStream.h" #include "ThePEG/Persistency/PersistentIStream.h" #include "Herwig/MatrixElement/Matchbox/Base/DipoleRepository.h" //#include "Herwig/MatrixElement/Matchbox/Phasespace/FILightTildeKinematics.h" //#include "Herwig/MatrixElement/Matchbox/Phasespace/FILightInvertedTildeKinematics.h" #include "Herwig/MatrixElement/Matchbox/Phasespace/FIMassiveTildeKinematics.h" #include "Herwig/MatrixElement/Matchbox/Phasespace/FIMassiveInvertedTildeKinematics.h" using namespace Herwig; FIMqgxDipole::FIMqgxDipole() : SubtractionDipole() {} -FIMqgxDipole::~FIMqgxDipole() {} - IBPtr FIMqgxDipole::clone() const { return new_ptr(*this); } IBPtr FIMqgxDipole::fullclone() const { return new_ptr(*this); } bool FIMqgxDipole::canHandle(const cPDVector& partons, int emitter, int emission, int spectator) const { return emitter > 1 && spectator < 2 && partons[emission]->id() == ParticleID::g && // abs(partons[emitter]->id()) < 7 && ( abs(partons[emitter]->id()) < 7 || abs(partons[emitter]->id()) == 1000021 ) && partons[emitter]->hardProcessMass() != ZERO && partons[spectator]->hardProcessMass() == ZERO; } double FIMqgxDipole::me2Avg(double ccme2) const { if ( jacobian() == 0.0 ) return 0.0; double x = subtractionParameters()[0]; double z = subtractionParameters()[1]; Energy2 prop = 2.*((realEmissionME()->lastXComb().meMomenta()[realEmitter()])* (realEmissionME()->lastXComb().meMomenta()[realEmission()]))*x; double CF = (SM().Nc()*SM().Nc()-1.)/(2.*SM().Nc()); if ( realEmissionME()->lastXComb().mePartonData()[realEmitter()]->id() == 1000021 ) CF = SM().Nc(); // For the SUSY D_{gluino,g}^a subtraction dipole we need to replace CF by CA=Nc // extra mass terms cancel double res = 8.*Constants::pi*CF*(realEmissionME()->lastXComb().lastSHat())* (underlyingBornME()->lastXComb().lastAlphaS())/prop; // NOTE: extra term taken from FIqgxDipole implementation // NOTE: extra term switched off for the moment in the massive case res *= ( 2./(1.-z+(1.-x)) - (1.+z) // + (1.-x)*(1.+3.*x*z) - sqr(realEmissionME()->lastXComb().mePartonData()[realEmitter()]->hardProcessMass()) / prop * 2.*x ); res *= -ccme2; res *= pow(realEmissionME()->lastXComb().lastSHat() / underlyingBornME()->lastXComb().lastSHat(), underlyingBornME()->lastXComb().mePartonData().size()-4.); res *= realEmissionME()->finalStateSymmetry() / underlyingBornME()->finalStateSymmetry(); return res; } double FIMqgxDipole::me2() const { if ( jacobian() == 0.0 ) return 0.0; double x = subtractionParameters()[0]; double z = subtractionParameters()[1]; Energy2 prop = 2.*((realEmissionME()->lastXComb().meMomenta()[realEmitter()])* (realEmissionME()->lastXComb().meMomenta()[realEmission()]))*x; double CF = (SM().Nc()*SM().Nc()-1.)/(2.*SM().Nc()); if ( realEmissionME()->lastXComb().mePartonData()[realEmitter()]->id() == 1000021 ) CF = SM().Nc(); // For the SUSY D_{gluino,g}^a subtraction dipole we need to replace CF by CA=Nc // extra mass terms cancel double res = 8.*Constants::pi*CF*(realEmissionME()->lastXComb().lastSHat())* (underlyingBornME()->lastXComb().lastAlphaS())/prop; // NOTE: extra term taken from FIqgxDipole implementation // NOTE: extra term switched off for the moment in the massive case res *= ( 2./(1.-z+(1.-x)) - (1.+z) // + (1.-x)*(1.+3.*x*z) - sqr(realEmissionME()->lastXComb().mePartonData()[realEmitter()]->hardProcessMass()) / prop * 2.*x ); res *= -underlyingBornME()->colourCorrelatedME2(make_pair(bornEmitter(),bornSpectator())); res *= pow(realEmissionME()->lastXComb().lastSHat() / underlyingBornME()->lastXComb().lastSHat(), underlyingBornME()->lastXComb().mePartonData().size()-4.); res *= realEmissionME()->finalStateSymmetry() / underlyingBornME()->finalStateSymmetry(); return res; } void FIMqgxDipole::persistentOutput(PersistentOStream &) const { } void FIMqgxDipole::persistentInput(PersistentIStream &, int) { } void FIMqgxDipole::Init() { static ClassDocumentation documentation ("FIMqgxDipole"); // DipoleRepository::registerDipole<0,FIMqgxDipole,FILightTildeKinematics,FILightInvertedTildeKinematics> // ("FIMqgxDipole","FILightTildeKinematics","FILightInvertedTildeKinematics"); DipoleRepository::registerDipole<0,FIMqgxDipole,FIMassiveTildeKinematics,FIMassiveInvertedTildeKinematics> ("FIMqgxDipole","FIMassiveTildeKinematics","FIMassiveInvertedTildeKinematics"); } // *** 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 describeHerwigFIMqgxDipole("Herwig::FIMqgxDipole", "Herwig.so"); diff --git a/MatrixElement/Matchbox/Dipoles/FIMqgxDipole.h b/MatrixElement/Matchbox/Dipoles/FIMqgxDipole.h --- a/MatrixElement/Matchbox/Dipoles/FIMqgxDipole.h +++ b/MatrixElement/Matchbox/Dipoles/FIMqgxDipole.h @@ -1,161 +1,153 @@ // -*- C++ -*- // // FIMqgxDipole.h is a part of Herwig - A multi-purpose Monte Carlo event generator // Copyright (C) 2002-2019 The Herwig Collaboration // // Herwig is licenced under version 3 of the GPL, see COPYING for details. // Please respect the MCnet academic guidelines, see GUIDELINES for details. // #ifndef HERWIG_FIMqgxDipole_H #define HERWIG_FIMqgxDipole_H // // This is the declaration of the FIMqgxDipole class. // #include "Herwig/MatrixElement/Matchbox/Dipoles/SubtractionDipole.h" namespace Herwig { using namespace ThePEG; /** * \ingroup Matchbox * \author Simon Platzer, Chrstian Reuschle * * \brief FIMqgxDipole implements the D_{Q,g}^a subtraction dipole, * as well as the D_{gluino,g}^a subtraction dipole. * */ class FIMqgxDipole: public SubtractionDipole { public: - /** @name Standard constructors and destructors. */ - //@{ /** * The default constructor. */ FIMqgxDipole(); - /** - * The destructor. - */ - virtual ~FIMqgxDipole(); - //@} - public: /** * Return true, if this dipole can possibly handle the indicated * emitter. */ virtual bool canHandleEmitter(const cPDVector& partons, int emitter) const { return emitter > 1 && abs(partons[emitter]->id()) < 7; } /** * Return true, if this dipole can possibly handle the indicated * splitting. */ virtual bool canHandleSplitting(const cPDVector& partons, int emitter, int emission) const { return canHandleEmitter(partons,emitter) && partons[emission]->id() == ParticleID::g; } /** * Return true, if this dipole can possibly handle the indicated * spectator. */ virtual bool canHandleSpectator(const cPDVector& partons, int spectator) const { return spectator < 2 && partons[spectator]->coloured(); } /** * Return true, if this dipole applies to the selected * configuration. */ virtual bool canHandle(const cPDVector& partons, int emitter, int emission, int spectator) const; /** * How to sample the z-distribution. * FlatZ = 1 * OneOverZ = 2 * OneOverOneMinusZ = 3 * OneOverZOneMinusZ = 4 */ virtual int samplingZ() const {return 3;} /** * Return the matrix element for the kinematical configuation * previously provided by the last call to setKinematics(), suitably * scaled by sHat() to give a dimension-less number. */ virtual double me2() const; /** * Return the matrix element averaged over spin correlations. */ virtual double me2Avg(double ccme2) 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. */ FIMqgxDipole & operator=(const FIMqgxDipole &) = delete; }; } #endif /* HERWIG_FIMqgxDipole_H */ diff --git a/MatrixElement/Matchbox/Dipoles/FIMqqxDipole.cc b/MatrixElement/Matchbox/Dipoles/FIMqqxDipole.cc --- a/MatrixElement/Matchbox/Dipoles/FIMqqxDipole.cc +++ b/MatrixElement/Matchbox/Dipoles/FIMqqxDipole.cc @@ -1,163 +1,161 @@ // -*- C++ -*- // // FIMqqxDipole.cc is a part of Herwig - A multi-purpose Monte Carlo event generator // Copyright (C) 2002-2019 The Herwig Collaboration // // Herwig is licenced under version 3 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 FIqqxDipole class. // #include "FIMqqxDipole.h" #include "ThePEG/Interface/ClassDocumentation.h" #include "ThePEG/Utilities/DescribeClass.h" #include "ThePEG/MatrixElement/Tree2toNDiagram.h" #include "ThePEG/StandardModel/StandardModelBase.h" #include "ThePEG/Persistency/PersistentOStream.h" #include "ThePEG/Persistency/PersistentIStream.h" #include "Herwig/MatrixElement/Matchbox/Base/DipoleRepository.h" #include "Herwig/MatrixElement/Matchbox/Utility/SpinCorrelationTensor.h" #include "Herwig/MatrixElement/Matchbox/Phasespace/FIMassiveTildeKinematics.h" #include "Herwig/MatrixElement/Matchbox/Phasespace/FIMassiveInvertedTildeKinematics.h" using namespace Herwig; FIMqqxDipole::FIMqqxDipole() : SubtractionDipole() {} -FIMqqxDipole::~FIMqqxDipole() {} - IBPtr FIMqqxDipole::clone() const { return new_ptr(*this); } IBPtr FIMqqxDipole::fullclone() const { return new_ptr(*this); } bool FIMqqxDipole::canHandle(const cPDVector& partons, int emitter, int emission, int spectator) const { return emitter > 1 && spectator < 2 && abs(partons[emission]->id()) < 7 && abs(partons[emitter]->id()) < 7 && partons[emission]->id() + partons[emitter]->id() == 0 && // !(partons[emitter]->hardProcessMass() == ZERO && // partons[emission]->hardProcessMass() == ZERO && // partons[spectator]->hardProcessMass() == ZERO); !(partons[emitter]->hardProcessMass() == ZERO && partons[emission]->hardProcessMass() == ZERO) && partons[spectator]->hardProcessMass() == ZERO; } double FIMqqxDipole::me2Avg(double ccme2) const { if ( jacobian() == 0.0 ) return 0.0; double x = subtractionParameters()[0]; double z = subtractionParameters()[1]; Energy2 prop = 2.*((realEmissionME()->lastXComb().meMomenta()[realEmitter()])* (realEmissionME()->lastXComb().meMomenta()[realEmission()]))*x; Energy2 mQ2 = sqr(realEmissionME()->lastXComb().mePartonData()[realEmitter()]->hardProcessMass()); // double muQ2 = x * mQ2 / double muQ2 = 0.5 * z * mQ2 / ((realEmissionME()->lastXComb().meMomenta()[realEmitter()])* (realEmissionME()->lastXComb().meMomenta()[realSpectator()])); // mu_ij=0, mu_i=mu_j=mu_Q. // double zm = ( 1.-x - sqrt( sqr(1.-x-2.*muQ2) - 4.*muQ2 ) ) / ( 2.*(1.-x) ); // double zp = ( 1.-x + sqrt( sqr(1.-x-2.*muQ2) - 4.*muQ2 ) ) / ( 2.*(1.-x) ); double zm = ( 1.-x - sqrt( sqr(1.-x-2.*muQ2) - 4.*sqr(muQ2) ) ) / ( 2.*(1.-x) ); double zp = ( 1.-x + sqrt( sqr(1.-x-2.*muQ2) - 4.*sqr(muQ2) ) ) / ( 2.*(1.-x) ); double res = 1.-2.*(z-zm)*(zp-z); res *= 4.*Constants::pi*(realEmissionME()->lastXComb().lastSHat())* (underlyingBornME()->lastXComb().lastAlphaS())/( prop+2.*mQ2*x ); res *= -ccme2; res *= pow(realEmissionME()->lastXComb().lastSHat() / underlyingBornME()->lastXComb().lastSHat(), underlyingBornME()->lastXComb().mePartonData().size()-4.); res *= realEmissionME()->finalStateSymmetry() / underlyingBornME()->finalStateSymmetry(); return res; } double FIMqqxDipole::me2() const { if ( jacobian() == 0.0 ) return 0.0; double x = subtractionParameters()[0]; double z = subtractionParameters()[1]; Energy2 prop = 2.*((realEmissionME()->lastXComb().meMomenta()[realEmitter()])* (realEmissionME()->lastXComb().meMomenta()[realEmission()]))*x; Energy2 mQ2 = sqr((realEmissionME()->lastXComb().mePartonData()[realEmitter()])->hardProcessMass()); Lorentz5Momentum pc = z*realEmissionME()->lastXComb().meMomenta()[realEmitter()] - (1.-z)*realEmissionME()->lastXComb().meMomenta()[realEmission()]; SpinCorrelationTensor corr(-1.,pc,-(prop+2.*mQ2*x)/(4.*x)); double res = -underlyingBornME()->spinColourCorrelatedME2(make_pair(bornEmitter(),bornSpectator()), corr); res *= 4.*Constants::pi*(realEmissionME()->lastXComb().lastSHat())* (underlyingBornME()->lastXComb().lastAlphaS())/( prop+2.*mQ2*x ); res *= pow(realEmissionME()->lastXComb().lastSHat() / underlyingBornME()->lastXComb().lastSHat(), underlyingBornME()->lastXComb().mePartonData().size()-4.); res *= realEmissionME()->finalStateSymmetry() / underlyingBornME()->finalStateSymmetry(); return res; } void FIMqqxDipole::persistentOutput(PersistentOStream &) const { } void FIMqqxDipole::persistentInput(PersistentIStream &, int) { } void FIMqqxDipole::Init() { static ClassDocumentation documentation ("FIMqqxDipole"); // DipoleRepository::registerDipole<0,FIMqqxDipole,FILightTildeKinematics,FILightInvertedTildeKinematics> // ("FIMqqxDipole","FILightTildeKinematics","FILightInvertedTildeKinematics"); DipoleRepository::registerDipole<0,FIMqqxDipole,FIMassiveTildeKinematics,FIMassiveInvertedTildeKinematics> ("FIMqqxDipole","FIMassiveTildeKinematics","FIMassiveInvertedTildeKinematics"); } // *** 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 describeHerwigFIMqqxDipole("Herwig::FIMqqxDipole", "Herwig.so"); diff --git a/MatrixElement/Matchbox/Dipoles/FIMqqxDipole.h b/MatrixElement/Matchbox/Dipoles/FIMqqxDipole.h --- a/MatrixElement/Matchbox/Dipoles/FIMqqxDipole.h +++ b/MatrixElement/Matchbox/Dipoles/FIMqqxDipole.h @@ -1,168 +1,160 @@ // -*- C++ -*- // // FIMqqxDipole.h is a part of Herwig - A multi-purpose Monte Carlo event generator // Copyright (C) 2002-2019 The Herwig Collaboration // // Herwig is licenced under version 3 of the GPL, see COPYING for details. // Please respect the MCnet academic guidelines, see GUIDELINES for details. // #ifndef HERWIG_FIMqqxDipole_H #define HERWIG_FIMqqxDipole_H // // This is the declaration of the FIMqqxDipole class. // #include "Herwig/MatrixElement/Matchbox/Dipoles/SubtractionDipole.h" namespace Herwig { using namespace ThePEG; /** * \ingroup Matchbox * \author Simon Platzer * * \brief FIMqqxDipole implements the D_{q,qbar}^a subtraction dipole. * */ class FIMqqxDipole: public SubtractionDipole { public: - /** @name Standard constructors and destructors. */ - //@{ /** * The default constructor. */ FIMqqxDipole(); - /** - * The destructor. - */ - virtual ~FIMqqxDipole(); - //@} - public: /** * Return true, if this dipole can possibly handle the indicated * emitter. */ virtual bool canHandleEmitter(const cPDVector& partons, int emitter) const { return emitter > 1 && abs(partons[emitter]->id()) < 7; } /** * Return true, if this dipole can possibly handle the indicated * splitting. */ virtual bool canHandleSplitting(const cPDVector& partons, int emitter, int emission) const { return canHandleEmitter(partons,emitter) && partons[emitter]->id() + partons[emission]->id() == 0; } /** * Return true, if this dipole can possibly handle the indicated * spectator. */ virtual bool canHandleSpectator(const cPDVector& partons, int spectator) const { return spectator < 2 && partons[spectator]->coloured(); } /** * Return true, if this dipole applies to the selected * configuration. */ virtual bool canHandle(const cPDVector& partons, int emitter, int emission, int spectator) const; /** * How to sample the z-distribution. * FlatZ = 1 * OneOverZ = 2 * OneOverOneMinusZ = 3 * OneOverZOneMinusZ = 4 */ virtual int samplingZ() const {return 1;} /** * Return true, if this dipole is symmetric with respect to emitter * and emission. */ virtual bool isSymmetric() const { return true; } /** * Return the matrix element for the kinematical configuation * previously provided by the last call to setKinematics(), suitably * scaled by sHat() to give a dimension-less number. */ virtual double me2() const; /** * Return the matrix element averaged over spin correlations. */ virtual double me2Avg(double ccme2) 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. */ FIMqqxDipole & operator=(const FIMqqxDipole &) = delete; }; } #endif /* HERWIG_FIMqqxDipole_H */ diff --git a/MatrixElement/Matchbox/Dipoles/FIMsqgxDipole.cc b/MatrixElement/Matchbox/Dipoles/FIMsqgxDipole.cc --- a/MatrixElement/Matchbox/Dipoles/FIMsqgxDipole.cc +++ b/MatrixElement/Matchbox/Dipoles/FIMsqgxDipole.cc @@ -1,155 +1,153 @@ // -*- C++ -*- // // FIqgxDipole.cc is a part of Herwig - A multi-purpose Monte Carlo event generator // Copyright (C) 2002-2019 The Herwig Collaboration // // Herwig is licenced under version 3 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 FIMsqgxDipole class. // #include "FIMsqgxDipole.h" #include "ThePEG/Interface/ClassDocumentation.h" #include "ThePEG/Utilities/DescribeClass.h" #include "ThePEG/MatrixElement/Tree2toNDiagram.h" #include "ThePEG/StandardModel/StandardModelBase.h" #include "ThePEG/Persistency/PersistentOStream.h" #include "ThePEG/Persistency/PersistentIStream.h" #include "Herwig/MatrixElement/Matchbox/Base/DipoleRepository.h" #include "Herwig/MatrixElement/Matchbox/Phasespace/FIMassiveTildeKinematics.h" #include "Herwig/MatrixElement/Matchbox/Phasespace/FIMassiveInvertedTildeKinematics.h" using namespace Herwig; FIMsqgxDipole::FIMsqgxDipole() : SubtractionDipole() {} -FIMsqgxDipole::~FIMsqgxDipole() {} - IBPtr FIMsqgxDipole::clone() const { return new_ptr(*this); } IBPtr FIMsqgxDipole::fullclone() const { return new_ptr(*this); } bool FIMsqgxDipole::canHandle(const cPDVector& partons, int emitter, int emission, int spectator) const { return emitter > 1 && spectator < 2 && partons[emission]->id() == ParticleID::g && ((abs(partons[emitter]->id())> 1000000 && abs(partons[emitter]->id())< 1000007) || (abs(partons[emitter]->id())> 2000000 && abs(partons[emitter]->id())< 2000007)) && partons[emitter]->hardProcessMass() != ZERO && partons[spectator]->hardProcessMass() == ZERO; } double FIMsqgxDipole::me2Avg(double ccme2) const { if ( jacobian() == 0.0 ) return 0.0; double x = subtractionParameters()[0]; double z = subtractionParameters()[1]; Energy2 prop = 2.*((realEmissionME()->lastXComb().meMomenta()[realEmitter()])* (realEmissionME()->lastXComb().meMomenta()[realEmission()]))*x; double CF = (SM().Nc()*SM().Nc()-1.)/(2.*SM().Nc()); // extra mass terms cancel double res = 8.*Constants::pi*CF*(realEmissionME()->lastXComb().lastSHat())* (underlyingBornME()->lastXComb().lastAlphaS())/prop; // // NOTE: extra term taken from FIqgxDipole implementation?? // res *= ( 2./(1.-z+(1.-x)) - 2. +(1.-x)*(1.+3.*x*z) - // sqr(realEmissionME()->lastXComb().mePartonData()[realEmission()]->hardProcessMass()) / prop * 2.*x); // NOTE: CR: extra term switched off in massive implementation for the moment, // mass of realEmission changed to mass of realEmitter res *= ( 2./(1.-z+(1.-x)) - 2. - sqr(realEmissionME()->lastXComb().mePartonData()[realEmitter()]->hardProcessMass()) / prop * 2.*x); res *= -ccme2; res *= pow(realEmissionME()->lastXComb().lastSHat() / underlyingBornME()->lastXComb().lastSHat(), underlyingBornME()->lastXComb().mePartonData().size()-4.); res *= realEmissionME()->finalStateSymmetry() / underlyingBornME()->finalStateSymmetry(); return res; } double FIMsqgxDipole::me2() const { if ( jacobian() == 0.0 ) return 0.0; double x = subtractionParameters()[0]; double z = subtractionParameters()[1]; Energy2 prop = 2.*((realEmissionME()->lastXComb().meMomenta()[realEmitter()])* (realEmissionME()->lastXComb().meMomenta()[realEmission()]))*x; double CF = (SM().Nc()*SM().Nc()-1.)/(2.*SM().Nc()); // extra mass terms cancel double res = 8.*Constants::pi*CF*(realEmissionME()->lastXComb().lastSHat())* (underlyingBornME()->lastXComb().lastAlphaS())/prop; // // NOTE: extra term taken from FIqgxDipole implementation // res *= ( 2./(1.-z+(1.-x)) -2. +(1.-x)*(1.+3.*x*z) - // sqr(realEmissionME()->lastXComb().mePartonData()[realEmission()]->hardProcessMass()) / prop * 2.*x); // NOTE: CR: extra term switched off in massive implementation for the moment, // mass of realEmission changed to mass of realEmitter res *= ( 2./(1.-z+(1.-x)) - 2. - sqr(realEmissionME()->lastXComb().mePartonData()[realEmitter()]->hardProcessMass()) / prop * 2.*x); res *= -underlyingBornME()->colourCorrelatedME2(make_pair(bornEmitter(),bornSpectator())); res *= pow(realEmissionME()->lastXComb().lastSHat() / underlyingBornME()->lastXComb().lastSHat(), underlyingBornME()->lastXComb().mePartonData().size()-4.); res *= realEmissionME()->finalStateSymmetry() / underlyingBornME()->finalStateSymmetry(); return res; } void FIMsqgxDipole::persistentOutput(PersistentOStream &) const { } void FIMsqgxDipole::persistentInput(PersistentIStream &, int) { } void FIMsqgxDipole::Init() { static ClassDocumentation documentation ("FIMsqgxDipole"); DipoleRepository::registerDipole<0,FIMsqgxDipole,FIMassiveTildeKinematics,FIMassiveInvertedTildeKinematics> ("FIMsqgxDipole","FIMassiveTildeKinematics","FIMassiveInvertedTildeKinematics"); } // *** 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 describeHerwigFIMsqgxDipole("Herwig::FIMsqgxDipole", "Herwig.so"); diff --git a/MatrixElement/Matchbox/Dipoles/FIMsqgxDipole.h b/MatrixElement/Matchbox/Dipoles/FIMsqgxDipole.h --- a/MatrixElement/Matchbox/Dipoles/FIMsqgxDipole.h +++ b/MatrixElement/Matchbox/Dipoles/FIMsqgxDipole.h @@ -1,164 +1,156 @@ // -*- C++ -*- // // FIMsqgxDipole.h is a part of Herwig - A multi-purpose Monte Carlo event generator // Copyright (C) 2002-2019 The Herwig Collaboration // // Herwig is licenced under version 3 of the GPL, see COPYING for details. // Please respect the MCnet academic guidelines, see GUIDELINES for details. // #ifndef HERWIG_FIMsqgxDipole_H #define HERWIG_FIMsqgxDipole_H // // This is the declaration of the FIMsqgxDipole class. // #include "Herwig/MatrixElement/Matchbox/Dipoles/SubtractionDipole.h" namespace Herwig { using namespace ThePEG; /** * \ingroup Matchbox * \author Simon Platzer, Alexandra Wilcock, Christian Reuschle * * \brief FIMsqgxDipole implements the D_{sq,g}^a subtraction dipole. * */ class FIMsqgxDipole: public SubtractionDipole { public: - /** @name Standard constructors and destructors. */ - //@{ /** * The default constructor. */ FIMsqgxDipole(); - /** - * The destructor. - */ - virtual ~FIMsqgxDipole(); - //@} - public: /** * Return true, if this dipole can possibly handle the indicated * emitter. */ virtual bool canHandleEmitter(const cPDVector& partons, int emitter) const { return emitter > 1 && (abs(abs(partons[emitter]->id()) - 1000000) < 7 || abs(abs(partons[emitter]->id()) - 2000000) < 7); } /** * Return true, if this dipole can possibly handle the indicated * splitting. */ virtual bool canHandleSplitting(const cPDVector& partons, int emitter, int emission) const { return canHandleEmitter(partons,emitter) && partons[emission]->id() == ParticleID::g; } /** * Return true, if this dipole can possibly handle the indicated * spectator. */ virtual bool canHandleSpectator(const cPDVector& partons, int spectator) const { return spectator < 2 && partons[spectator]->coloured(); } /** * Return true, if this dipole applies to the selected * configuration. */ virtual bool canHandle(const cPDVector& partons, int emitter, int emission, int spectator) const; /** * How to sample the z-distribution. * FlatZ = 1 * OneOverZ = 2 * OneOverOneMinusZ = 3 * OneOverZOneMinusZ = 4 */ virtual int samplingZ() const {return 3;} /** * Return the matrix element for the kinematical configuation * previously provided by the last call to setKinematics(), suitably * scaled by sHat() to give a dimension-less number. */ virtual double me2() const; /** * Return the matrix element averaged over spin correlations. */ virtual double me2Avg(double ccme2) 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. */ FIMsqgxDipole & operator=(const FIMsqgxDipole &) = delete; }; } #endif /* HERWIG_FIMsqgxDipole_H */ diff --git a/MatrixElement/Matchbox/Dipoles/FIggxDipole.cc b/MatrixElement/Matchbox/Dipoles/FIggxDipole.cc --- a/MatrixElement/Matchbox/Dipoles/FIggxDipole.cc +++ b/MatrixElement/Matchbox/Dipoles/FIggxDipole.cc @@ -1,151 +1,149 @@ // -*- C++ -*- // // FIggxDipole.cc is a part of Herwig - A multi-purpose Monte Carlo event generator // Copyright (C) 2002-2019 The Herwig Collaboration // // Herwig is licenced under version 3 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 FIggxDipole class. // #include "FIggxDipole.h" #include "ThePEG/Interface/ClassDocumentation.h" #include "ThePEG/Utilities/DescribeClass.h" #include "ThePEG/MatrixElement/Tree2toNDiagram.h" #include "ThePEG/StandardModel/StandardModelBase.h" #include "ThePEG/Persistency/PersistentOStream.h" #include "ThePEG/Persistency/PersistentIStream.h" #include "Herwig/MatrixElement/Matchbox/Base/DipoleRepository.h" #include "Herwig/MatrixElement/Matchbox/Utility/SpinCorrelationTensor.h" #include "Herwig/MatrixElement/Matchbox/Phasespace/FILightTildeKinematics.h" #include "Herwig/MatrixElement/Matchbox/Phasespace/FILightInvertedTildeKinematics.h" using namespace Herwig; FIggxDipole::FIggxDipole() : SubtractionDipole() {} -FIggxDipole::~FIggxDipole() {} - IBPtr FIggxDipole::clone() const { return new_ptr(*this); } IBPtr FIggxDipole::fullclone() const { return new_ptr(*this); } bool FIggxDipole::canHandle(const cPDVector& partons, int emitter, int emission, int spectator) const { return emitter > 1 && spectator < 2 && partons[emission]->id() == ParticleID::g && partons[emitter]->id() == ParticleID::g && partons[spectator]->hardProcessMass() == ZERO; } double FIggxDipole::me2Avg(double ccme2) const { if ( jacobian() == 0.0 ) return 0.0; double x = subtractionParameters()[0]; double z = subtractionParameters()[1]; Energy2 prop = 2.*((realEmissionME()->lastXComb().meMomenta()[realEmitter()])* (realEmissionME()->lastXComb().meMomenta()[realEmission()]))*x; double res = 1./((1.-z)+(1.-x)) + 1./(z+(1.-x)) - 2.+z*(1.-z) + (1.-x)*(1.+x*z*(1.-z)) ; res *= 16.*Constants::pi*SM().Nc()*(realEmissionME()->lastXComb().lastSHat())* (underlyingBornME()->lastXComb().lastAlphaS())/prop; res *= -ccme2; res *= pow(realEmissionME()->lastXComb().lastSHat() / underlyingBornME()->lastXComb().lastSHat(), underlyingBornME()->lastXComb().mePartonData().size()-4.); res *= realEmissionME()->finalStateSymmetry() / underlyingBornME()->finalStateSymmetry(); return res; } double FIggxDipole::me2() const { if ( jacobian() == 0.0 ) return 0.0; double x = subtractionParameters()[0]; double z = subtractionParameters()[1]; if ( alpha() < (1.-x) ) return 0.0; Energy2 prop = 2.*((realEmissionME()->lastXComb().meMomenta()[realEmitter()])* (realEmissionME()->lastXComb().meMomenta()[realEmission()]))*x; double diag = 1./(1.-z+1.-x) + 1./(z+1.-x) - 2. //+ (1.-x)*(1.+x*z*(1.-z)) ; Lorentz5Momentum pc = z*realEmissionME()->lastXComb().meMomenta()[realEmitter()] - (1.-z)*realEmissionME()->lastXComb().meMomenta()[realEmission()]; SpinCorrelationTensor corr(-diag,pc,prop/(2.*x)); double res = -underlyingBornME()->spinColourCorrelatedME2(make_pair(bornEmitter(),bornSpectator()), corr); res *= 16.*Constants::pi*SM().Nc()*(realEmissionME()->lastXComb().lastSHat())* (underlyingBornME()->lastXComb().lastAlphaS())/prop; res *= pow(realEmissionME()->lastXComb().lastSHat() / underlyingBornME()->lastXComb().lastSHat(), underlyingBornME()->lastXComb().mePartonData().size()-4.); res *= realEmissionME()->finalStateSymmetry() / underlyingBornME()->finalStateSymmetry(); return res; } void FIggxDipole::persistentOutput(PersistentOStream &) const { } void FIggxDipole::persistentInput(PersistentIStream &, int) { } void FIggxDipole::Init() { static ClassDocumentation documentation ("FIggxDipole"); DipoleRepository::registerDipole<0,FIggxDipole,FILightTildeKinematics,FILightInvertedTildeKinematics> ("FIggxDipole","FILightTildeKinematics","FILightInvertedTildeKinematics"); } // *** 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 describeHerwigFIggxDipole("Herwig::FIggxDipole", "Herwig.so"); diff --git a/MatrixElement/Matchbox/Dipoles/FIggxDipole.h b/MatrixElement/Matchbox/Dipoles/FIggxDipole.h --- a/MatrixElement/Matchbox/Dipoles/FIggxDipole.h +++ b/MatrixElement/Matchbox/Dipoles/FIggxDipole.h @@ -1,166 +1,158 @@ // -*- C++ -*- // // FIggxDipole.h is a part of Herwig - A multi-purpose Monte Carlo event generator // Copyright (C) 2002-2019 The Herwig Collaboration // // Herwig is licenced under version 3 of the GPL, see COPYING for details. // Please respect the MCnet academic guidelines, see GUIDELINES for details. // #ifndef HERWIG_FIggxDipole_H #define HERWIG_FIggxDipole_H // // This is the declaration of the FIggxDipole class. // #include "Herwig/MatrixElement/Matchbox/Dipoles/SubtractionDipole.h" namespace Herwig { using namespace ThePEG; /** * \ingroup Matchbox * \author Simon Platzer * * \brief FIggxDipole implements the D_{g,g}^a subtraction dipole. * */ class FIggxDipole: public SubtractionDipole { public: - /** @name Standard constructors and destructors. */ - //@{ /** * The default constructor. */ FIggxDipole(); - /** - * The destructor. - */ - virtual ~FIggxDipole(); - //@} - public: /** * Return true, if this dipole can possibly handle the indicated * emitter. */ virtual bool canHandleEmitter(const cPDVector& partons, int emitter) const { return emitter > 1 && partons[emitter]->id() == ParticleID::g; } /** * Return true, if this dipole can possibly handle the indicated * splitting. */ virtual bool canHandleSplitting(const cPDVector& partons, int emitter, int emission) const { return canHandleEmitter(partons,emitter) && partons[emission]->id() == ParticleID::g; } /** * Return true, if this dipole can possibly handle the indicated * spectator. */ virtual bool canHandleSpectator(const cPDVector& partons, int spectator) const { return spectator < 2 && partons[spectator]->coloured(); } /** * Return true, if this dipole applies to the selected * configuration. */ virtual bool canHandle(const cPDVector& partons, int emitter, int emission, int spectator) const; /** * How to sample the z-distribution. * FlatZ = 1 * OneOverZ = 2 * OneOverOneMinusZ = 3 * OneOverZOneMinusZ = 4 */ virtual int samplingZ() const {return 4;} /** * Return true, if this dipole is symmetric with respect to emitter * and emission. */ virtual bool isSymmetric() const { return true; } /** * Return the matrix element for the kinematical configuation * previously provided by the last call to setKinematics(), suitably * scaled by sHat() to give a dimension-less number. */ virtual double me2() const; /** * Return the matrix element averaged over spin correlations. */ virtual double me2Avg(double ccme2) 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. */ FIggxDipole & operator=(const FIggxDipole &) = delete; }; } #endif /* HERWIG_FIggxDipole_H */ diff --git a/MatrixElement/Matchbox/Dipoles/FIqgxDipole.cc b/MatrixElement/Matchbox/Dipoles/FIqgxDipole.cc --- a/MatrixElement/Matchbox/Dipoles/FIqgxDipole.cc +++ b/MatrixElement/Matchbox/Dipoles/FIqgxDipole.cc @@ -1,151 +1,149 @@ // -*- C++ -*- // // FIqgxDipole.cc is a part of Herwig - A multi-purpose Monte Carlo event generator // Copyright (C) 2002-2019 The Herwig Collaboration // // Herwig is licenced under version 3 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 FIqgxDipole class. // #include "FIqgxDipole.h" #include "ThePEG/Interface/ClassDocumentation.h" #include "ThePEG/Utilities/DescribeClass.h" #include "ThePEG/MatrixElement/Tree2toNDiagram.h" #include "ThePEG/StandardModel/StandardModelBase.h" #include "ThePEG/Persistency/PersistentOStream.h" #include "ThePEG/Persistency/PersistentIStream.h" #include "Herwig/MatrixElement/Matchbox/Base/DipoleRepository.h" #include "Herwig/MatrixElement/Matchbox/Phasespace/FILightTildeKinematics.h" #include "Herwig/MatrixElement/Matchbox/Phasespace/FILightInvertedTildeKinematics.h" using namespace Herwig; FIqgxDipole::FIqgxDipole() : SubtractionDipole() {} -FIqgxDipole::~FIqgxDipole() {} - IBPtr FIqgxDipole::clone() const { return new_ptr(*this); } IBPtr FIqgxDipole::fullclone() const { return new_ptr(*this); } bool FIqgxDipole::canHandle(const cPDVector& partons, int emitter, int emission, int spectator) const { return emitter > 1 && spectator < 2 && partons[emission]->id() == ParticleID::g && abs(partons[emitter]->id()) < 6 && partons[emitter]->hardProcessMass() == ZERO && partons[spectator]->hardProcessMass() == ZERO; } double FIqgxDipole::me2Avg(double ccme2) const { if ( jacobian() == 0.0 ) return 0.0; double x = subtractionParameters()[0]; double z = subtractionParameters()[1]; Energy2 prop = 2.*((realEmissionME()->lastXComb().meMomenta()[realEmitter()])* (realEmissionME()->lastXComb().meMomenta()[realEmission()]))*x; double CF = (SM().Nc()*SM().Nc()-1.)/(2.*SM().Nc()); double res = 8.*Constants::pi*CF*(realEmissionME()->lastXComb().lastSHat())* (underlyingBornME()->lastXComb().lastAlphaS())/prop; res *= ( 2./(1.-z+(1.-x)) -(1.+z) + (1.-x)*(1.+3.*x*z) ); res *= -ccme2; res *= pow(realEmissionME()->lastXComb().lastSHat() / underlyingBornME()->lastXComb().lastSHat(), underlyingBornME()->lastXComb().mePartonData().size()-4.); res *= realEmissionME()->finalStateSymmetry() / underlyingBornME()->finalStateSymmetry(); return res; } double FIqgxDipole::me2() const { if ( jacobian() == 0.0 ) return 0.0; double x = subtractionParameters()[0]; double z = subtractionParameters()[1]; if ( alpha() < (1.-x) ) return 0.0; Energy2 prop = 2.*((realEmissionME()->lastXComb().meMomenta()[realEmitter()])* (realEmissionME()->lastXComb().meMomenta()[realEmission()]))*x; double CF = (SM().Nc()*SM().Nc()-1.)/(2.*SM().Nc()); double res = 8.*Constants::pi*CF*(realEmissionME()->lastXComb().lastSHat())* (underlyingBornME()->lastXComb().lastAlphaS())/prop; res *= ( 2./(1.-z+(1.-x)) - (1.+z) //+ (1.-x)*(1.+3.*x*z) ); res *= -underlyingBornME()->colourCorrelatedME2(make_pair(bornEmitter(),bornSpectator())); res *= pow(realEmissionME()->lastXComb().lastSHat() / underlyingBornME()->lastXComb().lastSHat(), underlyingBornME()->lastXComb().mePartonData().size()-4.); res *= realEmissionME()->finalStateSymmetry() / underlyingBornME()->finalStateSymmetry(); return res; } void FIqgxDipole::persistentOutput(PersistentOStream &) const { } void FIqgxDipole::persistentInput(PersistentIStream &, int) { } void FIqgxDipole::Init() { static ClassDocumentation documentation ("FIqgxDipole"); DipoleRepository::registerDipole<0,FIqgxDipole,FILightTildeKinematics,FILightInvertedTildeKinematics> ("FIqgxDipole","FILightTildeKinematics","FILightInvertedTildeKinematics"); } // *** 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 describeHerwigFIqgxDipole("Herwig::FIqgxDipole", "Herwig.so"); diff --git a/MatrixElement/Matchbox/Dipoles/FIqgxDipole.h b/MatrixElement/Matchbox/Dipoles/FIqgxDipole.h --- a/MatrixElement/Matchbox/Dipoles/FIqgxDipole.h +++ b/MatrixElement/Matchbox/Dipoles/FIqgxDipole.h @@ -1,160 +1,152 @@ // -*- C++ -*- // // FIqgxDipole.h is a part of Herwig - A multi-purpose Monte Carlo event generator // Copyright (C) 2002-2019 The Herwig Collaboration // // Herwig is licenced under version 3 of the GPL, see COPYING for details. // Please respect the MCnet academic guidelines, see GUIDELINES for details. // #ifndef HERWIG_FIqgxDipole_H #define HERWIG_FIqgxDipole_H // // This is the declaration of the FIqgxDipole class. // #include "Herwig/MatrixElement/Matchbox/Dipoles/SubtractionDipole.h" namespace Herwig { using namespace ThePEG; /** * \ingroup Matchbox * \author Simon Platzer * * \brief FIqgxDipole implements the D_{q,g}^a subtraction dipole. * */ class FIqgxDipole: public SubtractionDipole { public: - /** @name Standard constructors and destructors. */ - //@{ /** * The default constructor. */ FIqgxDipole(); - /** - * The destructor. - */ - virtual ~FIqgxDipole(); - //@} - public: /** * Return true, if this dipole can possibly handle the indicated * emitter. */ virtual bool canHandleEmitter(const cPDVector& partons, int emitter) const { return emitter > 1 && abs(partons[emitter]->id()) < 7; } /** * Return true, if this dipole can possibly handle the indicated * splitting. */ virtual bool canHandleSplitting(const cPDVector& partons, int emitter, int emission) const { return canHandleEmitter(partons,emitter) && partons[emission]->id() == ParticleID::g; } /** * Return true, if this dipole can possibly handle the indicated * spectator. */ virtual bool canHandleSpectator(const cPDVector& partons, int spectator) const { return spectator < 2 && partons[spectator]->coloured(); } /** * Return true, if this dipole applies to the selected * configuration. */ virtual bool canHandle(const cPDVector& partons, int emitter, int emission, int spectator) const; /** * How to sample the z-distribution. * FlatZ = 1 * OneOverZ = 2 * OneOverOneMinusZ = 3 * OneOverZOneMinusZ = 4 */ virtual int samplingZ() const {return 3;} /** * Return the matrix element for the kinematical configuation * previously provided by the last call to setKinematics(), suitably * scaled by sHat() to give a dimension-less number. */ virtual double me2() const; /** * Return the matrix element averaged over spin correlations. */ virtual double me2Avg(double ccme2) 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. */ FIqgxDipole & operator=(const FIqgxDipole &) = delete; }; } #endif /* HERWIG_FIqgxDipole_H */ diff --git a/MatrixElement/Matchbox/Dipoles/FIqqxDipole.cc b/MatrixElement/Matchbox/Dipoles/FIqqxDipole.cc --- a/MatrixElement/Matchbox/Dipoles/FIqqxDipole.cc +++ b/MatrixElement/Matchbox/Dipoles/FIqqxDipole.cc @@ -1,147 +1,145 @@ // -*- C++ -*- // // FIqqxDipole.cc is a part of Herwig - A multi-purpose Monte Carlo event generator // Copyright (C) 2002-2019 The Herwig Collaboration // // Herwig is licenced under version 3 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 FIqqxDipole class. // #include "FIqqxDipole.h" #include "ThePEG/Interface/ClassDocumentation.h" #include "ThePEG/Utilities/DescribeClass.h" #include "ThePEG/MatrixElement/Tree2toNDiagram.h" #include "ThePEG/StandardModel/StandardModelBase.h" #include "ThePEG/Persistency/PersistentOStream.h" #include "ThePEG/Persistency/PersistentIStream.h" #include "Herwig/MatrixElement/Matchbox/Base/DipoleRepository.h" #include "Herwig/MatrixElement/Matchbox/Utility/SpinCorrelationTensor.h" #include "Herwig/MatrixElement/Matchbox/Phasespace/FILightTildeKinematics.h" #include "Herwig/MatrixElement/Matchbox/Phasespace/FILightInvertedTildeKinematics.h" using namespace Herwig; FIqqxDipole::FIqqxDipole() : SubtractionDipole() {} -FIqqxDipole::~FIqqxDipole() {} - IBPtr FIqqxDipole::clone() const { return new_ptr(*this); } IBPtr FIqqxDipole::fullclone() const { return new_ptr(*this); } bool FIqqxDipole::canHandle(const cPDVector& partons, int emitter, int emission, int spectator) const { return emitter > 1 && spectator < 2 && abs(partons[emission]->id()) < 6 && abs(partons[emitter]->id()) < 6 && partons[emission]->id() + partons[emitter]->id() == 0 && partons[emitter]->hardProcessMass() == ZERO && partons[emission]->hardProcessMass() == ZERO && partons[spectator]->hardProcessMass() == ZERO; } double FIqqxDipole::me2Avg(double ccme2) const { if ( jacobian() == 0.0 ) return 0.0; double x = subtractionParameters()[0]; double z = subtractionParameters()[1]; Energy2 prop = 2.*((realEmissionME()->lastXComb().meMomenta()[realEmitter()])* (realEmissionME()->lastXComb().meMomenta()[realEmission()]))*x; double res = 1.-2.*z*(1.-z); res *= 4.*Constants::pi*(realEmissionME()->lastXComb().lastSHat())* (underlyingBornME()->lastXComb().lastAlphaS())/prop; res *= -ccme2; res *= pow(realEmissionME()->lastXComb().lastSHat() / underlyingBornME()->lastXComb().lastSHat(), underlyingBornME()->lastXComb().mePartonData().size()-4.); res *= realEmissionME()->finalStateSymmetry() / underlyingBornME()->finalStateSymmetry(); return res; } double FIqqxDipole::me2() const { if ( jacobian() == 0.0 ) return 0.0; double x = subtractionParameters()[0]; double z = subtractionParameters()[1]; if ( alpha() < (1.-x) ) return 0.0; Energy2 prop = 2.*((realEmissionME()->lastXComb().meMomenta()[realEmitter()])* (realEmissionME()->lastXComb().meMomenta()[realEmission()]))*x; Lorentz5Momentum pc = z*realEmissionME()->lastXComb().meMomenta()[realEmitter()] - (1.-z)*realEmissionME()->lastXComb().meMomenta()[realEmission()]; SpinCorrelationTensor corr(-1.,pc,-prop/(4.*x)); double res = -underlyingBornME()->spinColourCorrelatedME2(make_pair(bornEmitter(),bornSpectator()), corr); res *= 4.*Constants::pi*(realEmissionME()->lastXComb().lastSHat())* (underlyingBornME()->lastXComb().lastAlphaS())/prop; res *= pow(realEmissionME()->lastXComb().lastSHat() / underlyingBornME()->lastXComb().lastSHat(), underlyingBornME()->lastXComb().mePartonData().size()-4.); res *= realEmissionME()->finalStateSymmetry() / underlyingBornME()->finalStateSymmetry(); return res; } void FIqqxDipole::persistentOutput(PersistentOStream &) const { } void FIqqxDipole::persistentInput(PersistentIStream &, int) { } void FIqqxDipole::Init() { static ClassDocumentation documentation ("FIqqxDipole"); DipoleRepository::registerDipole<0,FIqqxDipole,FILightTildeKinematics,FILightInvertedTildeKinematics> ("FIqqxDipole","FILightTildeKinematics","FILightInvertedTildeKinematics"); } // *** 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 describeHerwigFIqqxDipole("Herwig::FIqqxDipole", "Herwig.so"); diff --git a/MatrixElement/Matchbox/Dipoles/FIqqxDipole.h b/MatrixElement/Matchbox/Dipoles/FIqqxDipole.h --- a/MatrixElement/Matchbox/Dipoles/FIqqxDipole.h +++ b/MatrixElement/Matchbox/Dipoles/FIqqxDipole.h @@ -1,168 +1,160 @@ // -*- C++ -*- // // FIqqxDipole.h is a part of Herwig - A multi-purpose Monte Carlo event generator // Copyright (C) 2002-2019 The Herwig Collaboration // // Herwig is licenced under version 3 of the GPL, see COPYING for details. // Please respect the MCnet academic guidelines, see GUIDELINES for details. // #ifndef HERWIG_FIqqxDipole_H #define HERWIG_FIqqxDipole_H // // This is the declaration of the FIqqxDipole class. // #include "Herwig/MatrixElement/Matchbox/Dipoles/SubtractionDipole.h" namespace Herwig { using namespace ThePEG; /** * \ingroup Matchbox * \author Simon Platzer * * \brief FIqqxDipole implements the D_{q,qbar}^a subtraction dipole. * */ class FIqqxDipole: public SubtractionDipole { public: - /** @name Standard constructors and destructors. */ - //@{ /** * The default constructor. */ FIqqxDipole(); - /** - * The destructor. - */ - virtual ~FIqqxDipole(); - //@} - public: /** * Return true, if this dipole can possibly handle the indicated * emitter. */ virtual bool canHandleEmitter(const cPDVector& partons, int emitter) const { return emitter > 1 && abs(partons[emitter]->id()) < 7; } /** * Return true, if this dipole can possibly handle the indicated * splitting. */ virtual bool canHandleSplitting(const cPDVector& partons, int emitter, int emission) const { return canHandleEmitter(partons,emitter) && partons[emitter]->id() + partons[emission]->id() == 0; } /** * Return true, if this dipole can possibly handle the indicated * spectator. */ virtual bool canHandleSpectator(const cPDVector& partons, int spectator) const { return spectator < 2 && partons[spectator]->coloured(); } /** * Return true, if this dipole applies to the selected * configuration. */ virtual bool canHandle(const cPDVector& partons, int emitter, int emission, int spectator) const; /** * How to sample the z-distribution. * FlatZ = 1 * OneOverZ = 2 * OneOverOneMinusZ = 3 * OneOverZOneMinusZ = 4 */ virtual int samplingZ() const {return 1;} /** * Return true, if this dipole is symmetric with respect to emitter * and emission. */ virtual bool isSymmetric() const { return true; } /** * Return the matrix element for the kinematical configuation * previously provided by the last call to setKinematics(), suitably * scaled by sHat() to give a dimension-less number. */ virtual double me2() const; /** * Return the matrix element averaged over spin correlations. */ virtual double me2Avg(double ccme2) 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. */ FIqqxDipole & operator=(const FIqqxDipole &) = delete; }; } #endif /* HERWIG_FIqqxDipole_H */ diff --git a/MatrixElement/Matchbox/Dipoles/IFMggxDipole.cc b/MatrixElement/Matchbox/Dipoles/IFMggxDipole.cc --- a/MatrixElement/Matchbox/Dipoles/IFMggxDipole.cc +++ b/MatrixElement/Matchbox/Dipoles/IFMggxDipole.cc @@ -1,152 +1,150 @@ // -*- C++ -*- // // IFMggxDipole.cc is a part of Herwig - A multi-purpose Monte Carlo event generator // Copyright (C) 2002-2019 The Herwig Collaboration // // Herwig is licenced under version 3 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 IFggxDipole class. // #include "IFMggxDipole.h" #include "ThePEG/Interface/ClassDocumentation.h" #include "ThePEG/Utilities/DescribeClass.h" #include "ThePEG/MatrixElement/Tree2toNDiagram.h" #include "ThePEG/StandardModel/StandardModelBase.h" #include "ThePEG/Persistency/PersistentOStream.h" #include "ThePEG/Persistency/PersistentIStream.h" #include "Herwig/MatrixElement/Matchbox/Base/DipoleRepository.h" #include "Herwig/MatrixElement/Matchbox/Utility/SpinCorrelationTensor.h" #include "Herwig/MatrixElement/Matchbox/Phasespace/IFMassiveTildeKinematics.h" #include "Herwig/MatrixElement/Matchbox/Phasespace/IFMassiveInvertedTildeKinematics.h" using namespace Herwig; IFMggxDipole::IFMggxDipole() : SubtractionDipole() {} -IFMggxDipole::~IFMggxDipole() {} - IBPtr IFMggxDipole::clone() const { return new_ptr(*this); } IBPtr IFMggxDipole::fullclone() const { return new_ptr(*this); } bool IFMggxDipole::canHandle(const cPDVector& partons, int emitter, int emission, int spectator) const { return emitter < 2 && spectator > 1 && partons[emission]->id() == ParticleID::g && partons[emitter]->id() == ParticleID::g && partons[spectator]->hardProcessMass() != ZERO; } double IFMggxDipole::me2Avg(double ccme2) const { if ( jacobian() == 0.0 ) return 0.0; double x = subtractionParameters()[0]; double u = subtractionParameters()[1]; Energy2 prop = 2.*((realEmissionME()->lastXComb().meMomenta()[realEmitter()])* (realEmissionME()->lastXComb().meMomenta()[realEmission()]))*x; double muj2 = sqr( (realEmissionME()->lastXComb().mePartonData()[realSpectator()]->hardProcessMass()) ) / (2.* (realEmissionME()->lastXComb().meMomenta()[bornSpectator()])* (realEmissionME()->lastXComb().meMomenta()[realEmitter()]) ); double res = 1./(1.-x+u) + (1.-x)/x - 1. + x*(1.-x) - muj2/x*u/(1.-u); res *= 16.*Constants::pi*SM().Nc()*(realEmissionME()->lastXComb().lastSHat())* (underlyingBornME()->lastXComb().lastAlphaS())/prop; res *= -ccme2; res *= pow(realEmissionME()->lastXComb().lastSHat() / underlyingBornME()->lastXComb().lastSHat(), underlyingBornME()->lastXComb().mePartonData().size()-4.); res *= realEmissionME()->finalStateSymmetry() / underlyingBornME()->finalStateSymmetry(); return res; } double IFMggxDipole::me2() const { if ( jacobian() == 0.0 ) return 0.0; double x = subtractionParameters()[0]; double u = subtractionParameters()[1]; Energy2 prop = 2.*((realEmissionME()->lastXComb().meMomenta()[realEmitter()])* (realEmissionME()->lastXComb().meMomenta()[realEmission()]))*x; double diag = 1./(1.-x+u)-1.+x*(1.-x); Lorentz5Momentum pc = realEmissionME()->lastXComb().meMomenta()[realEmission()]/u - realEmissionME()->lastXComb().meMomenta()[realSpectator()]/(1.-u); Energy2 sc = realEmissionME()->lastXComb().meMomenta()[realEmission()]* realEmissionME()->lastXComb().meMomenta()[realSpectator()]; sc /= u*(1.-u)*(1.-x)/x; SpinCorrelationTensor corr(-diag,pc,sc); double res = -underlyingBornME()->spinColourCorrelatedME2(make_pair(bornEmitter(),bornSpectator()), corr); res *= 16.*Constants::pi*SM().Nc()*(realEmissionME()->lastXComb().lastSHat())* (underlyingBornME()->lastXComb().lastAlphaS())/prop; res *= pow(realEmissionME()->lastXComb().lastSHat() / underlyingBornME()->lastXComb().lastSHat(), underlyingBornME()->lastXComb().mePartonData().size()-4.); res *= realEmissionME()->finalStateSymmetry() / underlyingBornME()->finalStateSymmetry(); return res; } void IFMggxDipole::persistentOutput(PersistentOStream &) const { } void IFMggxDipole::persistentInput(PersistentIStream &, int) { } void IFMggxDipole::Init() { static ClassDocumentation documentation ("IFMggxDipole"); DipoleRepository::registerDipole<0,IFMggxDipole,IFMassiveTildeKinematics,IFMassiveInvertedTildeKinematics> ("IFMggxDipole","IFMassiveTildeKinematics","IFMassiveInvertedTildeKinematics"); } // *** 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 describeHerwigIFMggxDipole("Herwig::IFMggxDipole", "Herwig.so"); diff --git a/MatrixElement/Matchbox/Dipoles/IFMggxDipole.h b/MatrixElement/Matchbox/Dipoles/IFMggxDipole.h --- a/MatrixElement/Matchbox/Dipoles/IFMggxDipole.h +++ b/MatrixElement/Matchbox/Dipoles/IFMggxDipole.h @@ -1,160 +1,152 @@ // -*- C++ -*- // // IFMggxDipole.h is a part of Herwig - A multi-purpose Monte Carlo event generator // Copyright (C) 2002-2019 The Herwig Collaboration // // Herwig is licenced under version 3 of the GPL, see COPYING for details. // Please respect the MCnet academic guidelines, see GUIDELINES for details. // #ifndef HERWIG_IFMggxDipole_H #define HERWIG_IFMggxDipole_H // // This is the declaration of the IFMggxDipole class. // #include "Herwig/MatrixElement/Matchbox/Dipoles/SubtractionDipole.h" namespace Herwig { using namespace ThePEG; /** * \ingroup Matchbox * \author Simon Platzer * * \brief IFMggxDipole implements the D^{g,g}_k subtraction dipole. * */ class IFMggxDipole: public SubtractionDipole { public: - /** @name Standard constructors and destructors. */ - //@{ /** * The default constructor. */ IFMggxDipole(); - /** - * The destructor. - */ - virtual ~IFMggxDipole(); - //@} - public: /** * Return true, if this dipole can possibly handle the indicated * emitter. */ virtual bool canHandleEmitter(const cPDVector& partons, int emitter) const { return emitter < 2 && partons[emitter]->id() == ParticleID::g; } /** * Return true, if this dipole can possibly handle the indicated * splitting. */ virtual bool canHandleSplitting(const cPDVector& partons, int emitter, int emission) const { return canHandleEmitter(partons,emitter) && partons[emission]->id() == ParticleID::g; } /** * Return true, if this dipole can possibly handle the indicated * spectator. */ virtual bool canHandleSpectator(const cPDVector& partons, int spectator) const { return spectator > 1 && partons[spectator]->coloured(); } /** * Return true, if this dipole applies to the selected * configuration. */ virtual bool canHandle(const cPDVector& partons, int emitter, int emission, int spectator) const; /** * How to sample the z-distribution. * FlatZ = 1 * OneOverZ = 2 * OneOverOneMinusZ = 3 * OneOverZOneMinusZ = 4 */ virtual int samplingZ() const {return 4;} /** * Return the matrix element for the kinematical configuation * previously provided by the last call to setKinematics(), suitably * scaled by sHat() to give a dimension-less number. */ virtual double me2() const; /** * Return the matrix element averaged over spin correlations. */ virtual double me2Avg(double ccme2) 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. */ IFMggxDipole & operator=(const IFMggxDipole &) = delete; }; } #endif /* HERWIG_IFMggxDipole_H */ diff --git a/MatrixElement/Matchbox/Dipoles/IFMgqxDipole.cc b/MatrixElement/Matchbox/Dipoles/IFMgqxDipole.cc --- a/MatrixElement/Matchbox/Dipoles/IFMgqxDipole.cc +++ b/MatrixElement/Matchbox/Dipoles/IFMgqxDipole.cc @@ -1,136 +1,134 @@ // -*- C++ -*- // // IFMgqxDipole.cc is a part of Herwig - A multi-purpose Monte Carlo event generator // Copyright (C) 2002-2019 The Herwig Collaboration // // Herwig is licenced under version 3 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 IFgqxDipole class. // #include "IFMgqxDipole.h" #include "ThePEG/Interface/ClassDocumentation.h" #include "ThePEG/Utilities/DescribeClass.h" #include "ThePEG/MatrixElement/Tree2toNDiagram.h" #include "ThePEG/StandardModel/StandardModelBase.h" #include "ThePEG/Persistency/PersistentOStream.h" #include "ThePEG/Persistency/PersistentIStream.h" #include "Herwig/MatrixElement/Matchbox/Base/DipoleRepository.h" #include "Herwig/MatrixElement/Matchbox/Phasespace/IFMassiveTildeKinematics.h" #include "Herwig/MatrixElement/Matchbox/Phasespace/IFMassiveInvertedTildeKinematics.h" using namespace Herwig; IFMgqxDipole::IFMgqxDipole() : SubtractionDipole() {} -IFMgqxDipole::~IFMgqxDipole() {} - IBPtr IFMgqxDipole::clone() const { return new_ptr(*this); } IBPtr IFMgqxDipole::fullclone() const { return new_ptr(*this); } bool IFMgqxDipole::canHandle(const cPDVector& partons, int emitter, int emission, int spectator) const { return emitter < 2 && spectator > 1 && partons[emitter]->id() == ParticleID::g && abs(partons[emission]->id()) < 7 && partons[emission]->hardProcessMass() == ZERO && partons[spectator]->hardProcessMass() != ZERO; } double IFMgqxDipole::me2Avg(double ccme2) const { if ( jacobian() == 0.0 ) return 0.0; double x = subtractionParameters()[0]; Energy2 prop = 2.*((realEmissionME()->lastXComb().meMomenta()[realEmitter()])* (realEmissionME()->lastXComb().meMomenta()[realEmission()]))*x; double res = 8.*Constants::pi*(realEmissionME()->lastXComb().lastSHat())* (underlyingBornME()->lastXComb().lastAlphaS())/prop; res *= .5 * ( 1.-2.*x*(1.-x) ); res *= -ccme2; res *= pow(realEmissionME()->lastXComb().lastSHat() / underlyingBornME()->lastXComb().lastSHat(), underlyingBornME()->lastXComb().mePartonData().size()-4.); res *= realEmissionME()->finalStateSymmetry() / underlyingBornME()->finalStateSymmetry(); return res; } double IFMgqxDipole::me2() const { if ( jacobian() == 0.0 ) return 0.0; double x = subtractionParameters()[0]; Energy2 prop = 2.*((realEmissionME()->lastXComb().meMomenta()[realEmitter()])* (realEmissionME()->lastXComb().meMomenta()[realEmission()]))*x; double res = 8.*Constants::pi*(realEmissionME()->lastXComb().lastSHat())* (underlyingBornME()->lastXComb().lastAlphaS())/prop; res *= .5 * ( 1.-2.*x*(1.-x) ); res *= -underlyingBornME()->colourCorrelatedME2(make_pair(bornEmitter(),bornSpectator())); res *= pow(realEmissionME()->lastXComb().lastSHat() / underlyingBornME()->lastXComb().lastSHat(), underlyingBornME()->lastXComb().mePartonData().size()-4.); res *= realEmissionME()->finalStateSymmetry() / underlyingBornME()->finalStateSymmetry(); return res; } void IFMgqxDipole::persistentOutput(PersistentOStream &) const { } void IFMgqxDipole::persistentInput(PersistentIStream &, int) { } void IFMgqxDipole::Init() { static ClassDocumentation documentation ("IFMgqxDipole"); DipoleRepository::registerDipole<0,IFMgqxDipole,IFMassiveTildeKinematics,IFMassiveInvertedTildeKinematics> ("IFMgqxDipole","IFMassiveTildeKinematics","IFMassiveInvertedTildeKinematics"); } // *** 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 describeHerwigIFMgqxDipole("Herwig::IFMgqxDipole", "Herwig.so"); diff --git a/MatrixElement/Matchbox/Dipoles/IFMgqxDipole.h b/MatrixElement/Matchbox/Dipoles/IFMgqxDipole.h --- a/MatrixElement/Matchbox/Dipoles/IFMgqxDipole.h +++ b/MatrixElement/Matchbox/Dipoles/IFMgqxDipole.h @@ -1,160 +1,152 @@ // -*- C++ -*- // // IFMgqxDipole.h is a part of Herwig - A multi-purpose Monte Carlo event generator // Copyright (C) 2002-2019 The Herwig Collaboration // // Herwig is licenced under version 3 of the GPL, see COPYING for details. // Please respect the MCnet academic guidelines, see GUIDELINES for details. // #ifndef HERWIG_IFMgqxDipole_H #define HERWIG_IFMgqxDipole_H // // This is the declaration of the IFMgqxDipole class. // #include "Herwig/MatrixElement/Matchbox/Dipoles/SubtractionDipole.h" namespace Herwig { using namespace ThePEG; /** * \ingroup Matchbox * \author Simon Platzer * * \brief IFMgqxDipole implements the D_k^{g,q} subtraction dipole. * */ class IFMgqxDipole: public SubtractionDipole { public: - /** @name Standard constructors and destructors. */ - //@{ /** * The default constructor. */ IFMgqxDipole(); - /** - * The destructor. - */ - virtual ~IFMgqxDipole(); - //@} - public: /** * Return true, if this dipole can possibly handle the indicated * emitter. */ virtual bool canHandleEmitter(const cPDVector& partons, int emitter) const { return emitter < 2 && partons[emitter]->id() == ParticleID::g; } /** * Return true, if this dipole can possibly handle the indicated * splitting. */ virtual bool canHandleSplitting(const cPDVector& partons, int emitter, int emission) const { return canHandleEmitter(partons,emitter) && abs(partons[emission]->id()) < 7; } /** * Return true, if this dipole can possibly handle the indicated * spectator. */ virtual bool canHandleSpectator(const cPDVector& partons, int spectator) const { return spectator > 1 && partons[spectator]->coloured(); } /** * Return true, if this dipole applies to the selected * configuration. */ virtual bool canHandle(const cPDVector& partons, int emitter, int emission, int spectator) const; /** * How to sample the z-distribution. * FlatZ = 1 * OneOverZ = 2 * OneOverOneMinusZ = 3 * OneOverZOneMinusZ = 4 */ virtual int samplingZ() const {return 2;} /** * Return the matrix element for the kinematical configuation * previously provided by the last call to setKinematics(), suitably * scaled by sHat() to give a dimension-less number. */ virtual double me2() const; /** * Return the matrix element averaged over spin correlations. */ virtual double me2Avg(double ccme2) 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. */ IFMgqxDipole & operator=(const IFMgqxDipole &) = delete; }; } #endif /* HERWIG_IFMgqxDipole_H */ diff --git a/MatrixElement/Matchbox/Dipoles/IFMqgxDipole.cc b/MatrixElement/Matchbox/Dipoles/IFMqgxDipole.cc --- a/MatrixElement/Matchbox/Dipoles/IFMqgxDipole.cc +++ b/MatrixElement/Matchbox/Dipoles/IFMqgxDipole.cc @@ -1,154 +1,152 @@ // -*- C++ -*- // // IFMqgxDipole.cc is a part of Herwig - A multi-purpose Monte Carlo event generator // Copyright (C) 2002-2019 The Herwig Collaboration // // Herwig is licenced under version 3 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 IFqgxDipole class. // #include "IFMqgxDipole.h" #include "ThePEG/Interface/ClassDocumentation.h" #include "ThePEG/Utilities/DescribeClass.h" #include "ThePEG/MatrixElement/Tree2toNDiagram.h" #include "ThePEG/StandardModel/StandardModelBase.h" #include "ThePEG/Persistency/PersistentOStream.h" #include "ThePEG/Persistency/PersistentIStream.h" #include "Herwig/MatrixElement/Matchbox/Base/DipoleRepository.h" #include "Herwig/MatrixElement/Matchbox/Phasespace/IFMassiveTildeKinematics.h" #include "Herwig/MatrixElement/Matchbox/Phasespace/IFMassiveInvertedTildeKinematics.h" using namespace Herwig; IFMqgxDipole::IFMqgxDipole() : SubtractionDipole() {} -IFMqgxDipole::~IFMqgxDipole() {} - IBPtr IFMqgxDipole::clone() const { return new_ptr(*this); } IBPtr IFMqgxDipole::fullclone() const { return new_ptr(*this); } bool IFMqgxDipole::canHandle(const cPDVector& partons, int emitter, int emission, int spectator) const { return emitter < 2 && spectator > 1 && partons[emission]->id() == ParticleID::g && abs(partons[emitter]->id()) < 7 && partons[emitter]->hardProcessMass() == ZERO && partons[spectator]->hardProcessMass() != ZERO; } double IFMqgxDipole::me2Avg(double ccme2) const { if ( jacobian() == 0.0 ) return 0.0; double x = subtractionParameters()[0]; double u = subtractionParameters()[1]; Energy2 prop = 2.*((realEmissionME()->lastXComb().meMomenta()[realEmitter()])* (realEmissionME()->lastXComb().meMomenta()[realEmission()]))*x; double CF = (SM().Nc()*SM().Nc()-1.)/(2.*SM().Nc()); double res = 8.*Constants::pi*CF*(realEmissionME()->lastXComb().lastSHat())* (underlyingBornME()->lastXComb().lastAlphaS())/prop; // NOTE: extra term same as in IFqgxDipole // NOTE: extra term switched off for the moment in the massive case res *= ( 2./(1.-x+u) - (1.+x) // + u*(1.+3.*x*(1.-u)) ); res *= -ccme2; res *= pow(realEmissionME()->lastXComb().lastSHat() / underlyingBornME()->lastXComb().lastSHat(), underlyingBornME()->lastXComb().mePartonData().size()-4.); res *= realEmissionME()->finalStateSymmetry() / underlyingBornME()->finalStateSymmetry(); return res; } double IFMqgxDipole::me2() const { if ( jacobian() == 0.0 ) return 0.0; double x = subtractionParameters()[0]; double u = subtractionParameters()[1]; Energy2 prop = 2.*((realEmissionME()->lastXComb().meMomenta()[realEmitter()])* (realEmissionME()->lastXComb().meMomenta()[realEmission()]))*x; double CF = (SM().Nc()*SM().Nc()-1.)/(2.*SM().Nc()); double res = 8.*Constants::pi*CF*(realEmissionME()->lastXComb().lastSHat())* (underlyingBornME()->lastXComb().lastAlphaS())/prop; // NOTE: extra term same as in IFqgxDipole // NOTE: extra term switched off for the moment in the massive case res *= ( 2./(1.-x+u) - (1.+x) // + u*(1.+3.*x*(1.-u)) ); res *= -underlyingBornME()->colourCorrelatedME2(make_pair(bornEmitter(),bornSpectator())); res *= pow(realEmissionME()->lastXComb().lastSHat() / underlyingBornME()->lastXComb().lastSHat(), underlyingBornME()->lastXComb().mePartonData().size()-4.); res *= realEmissionME()->finalStateSymmetry() / underlyingBornME()->finalStateSymmetry(); return res; } void IFMqgxDipole::persistentOutput(PersistentOStream &) const { } void IFMqgxDipole::persistentInput(PersistentIStream &, int) { } void IFMqgxDipole::Init() { static ClassDocumentation documentation ("IFMqgxDipole"); // DipoleRepository::registerDipole<0,IFMqgxDipole,IFLightTildeKinematics,IFLightInvertedTildeKinematics> // ("IFMqgxDipole","IFLightTildeKinematics","IFLightInvertedTildeKinematics"); DipoleRepository::registerDipole<0,IFMqgxDipole,IFMassiveTildeKinematics,IFMassiveInvertedTildeKinematics> ("IFMqgxDipole","IFMassiveTildeKinematics","IFMassiveInvertedTildeKinematics"); } // *** 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 describeHerwigIFMqgxDipole("Herwig::IFMqgxDipole", "Herwig.so"); diff --git a/MatrixElement/Matchbox/Dipoles/IFMqgxDipole.h b/MatrixElement/Matchbox/Dipoles/IFMqgxDipole.h --- a/MatrixElement/Matchbox/Dipoles/IFMqgxDipole.h +++ b/MatrixElement/Matchbox/Dipoles/IFMqgxDipole.h @@ -1,160 +1,152 @@ // -*- C++ -*- // // IFMqgxDipole.h is a part of Herwig - A multi-purpose Monte Carlo event generator // Copyright (C) 2002-2019 The Herwig Collaboration // // Herwig is licenced under version 3 of the GPL, see COPYING for details. // Please respect the MCnet academic guidelines, see GUIDELINES for details. // #ifndef HERWIG_IFMqgxDipole_H #define HERWIG_IFMqgxDipole_H // // This is the declaration of the IFMqgxDipole class. // #include "Herwig/MatrixElement/Matchbox/Dipoles/SubtractionDipole.h" namespace Herwig { using namespace ThePEG; /** * \ingroup Matchbox * \author Simon Platzer * * \brief IFMqgxDipole implements the D^{q,g}_k subtraction dipole * */ class IFMqgxDipole: public SubtractionDipole { public: - /** @name Standard constructors and destructors. */ - //@{ /** * The default constructor. */ IFMqgxDipole(); - /** - * The destructor. - */ - virtual ~IFMqgxDipole(); - //@} - public: /** * Return true, if this dipole can possibly handle the indicated * emitter. */ virtual bool canHandleEmitter(const cPDVector& partons, int emitter) const { return emitter < 2 && abs(partons[emitter]->id()) < 7; } /** * Return true, if this dipole can possibly handle the indicated * splitting. */ virtual bool canHandleSplitting(const cPDVector& partons, int emitter, int emission) const { return canHandleEmitter(partons,emitter) && partons[emission]->id() == ParticleID::g; } /** * Return true, if this dipole can possibly handle the indicated * spectator. */ virtual bool canHandleSpectator(const cPDVector& partons, int spectator) const { return spectator > 1 && partons[spectator]->coloured(); } /** * Return true, if this dipole applies to the selected * configuration. */ virtual bool canHandle(const cPDVector& partons, int emitter, int emission, int spectator) const; /** * How to sample the z-distribution. * FlatZ = 1 * OneOverZ = 2 * OneOverOneMinusZ = 3 * OneOverZOneMinusZ = 4 */ virtual int samplingZ() const {return 4;} /** * Return the matrix element for the kinematical configuation * previously provided by the last call to setKinematics(), suitably * scaled by sHat() to give a dimension-less number. */ virtual double me2() const; /** * Return the matrix element averaged over spin correlations. */ virtual double me2Avg(double ccme2) 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. */ IFMqgxDipole & operator=(const IFMqgxDipole &) = delete; }; } #endif /* HERWIG_IFMqgxDipole_H */ diff --git a/MatrixElement/Matchbox/Dipoles/IFMqqxDipole.cc b/MatrixElement/Matchbox/Dipoles/IFMqqxDipole.cc --- a/MatrixElement/Matchbox/Dipoles/IFMqqxDipole.cc +++ b/MatrixElement/Matchbox/Dipoles/IFMqqxDipole.cc @@ -1,167 +1,165 @@ // -*- C++ -*- // // IFMqqxDipole.cc is a part of Herwig - A multi-purpose Monte Carlo event generator // Copyright (C) 2002-2019 The Herwig Collaboration // // Herwig is licenced under version 3 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 IFqqxDipole class. // #include "IFMqqxDipole.h" #include "ThePEG/Interface/ClassDocumentation.h" #include "ThePEG/Utilities/DescribeClass.h" #include "ThePEG/MatrixElement/Tree2toNDiagram.h" #include "ThePEG/StandardModel/StandardModelBase.h" #include "ThePEG/Persistency/PersistentOStream.h" #include "ThePEG/Persistency/PersistentIStream.h" #include "Herwig/MatrixElement/Matchbox/Base/DipoleRepository.h" #include "Herwig/MatrixElement/Matchbox/Utility/SpinCorrelationTensor.h" //#include "Herwig/MatrixElement/Matchbox/Phasespace/IFLightTildeKinematics.h" //#include "Herwig/MatrixElement/Matchbox/Phasespace/IFLightInvertedTildeKinematics.h" #include "Herwig/MatrixElement/Matchbox/Phasespace/IFMassiveTildeKinematics.h" #include "Herwig/MatrixElement/Matchbox/Phasespace/IFMassiveInvertedTildeKinematics.h" using namespace Herwig; IFMqqxDipole::IFMqqxDipole() : SubtractionDipole() {} -IFMqqxDipole::~IFMqqxDipole() {} - IBPtr IFMqqxDipole::clone() const { return new_ptr(*this); } IBPtr IFMqqxDipole::fullclone() const { return new_ptr(*this); } bool IFMqqxDipole::canHandle(const cPDVector& partons, int emitter, int emission, int spectator) const { return emitter < 2 && spectator > 1 && // abs(partons[emission]->id()) < 6 && // abs(partons[emitter]->id()) < 6 && abs(partons[emission]->id()) < 7 && abs(partons[emitter]->id()) < 7 && partons[emission]->id() - partons[emitter]->id() == 0 && // !(partons[emitter]->hardProcessMass() == ZERO && // partons[emission]->hardProcessMass() == ZERO && // partons[spectator]->hardProcessMass() == ZERO); partons[emitter]->hardProcessMass() == ZERO && partons[emission]->hardProcessMass() == ZERO && partons[spectator]->hardProcessMass() != ZERO; } double IFMqqxDipole::me2Avg(double ccme2) const { if ( jacobian() == 0.0 ) return 0.0; double x = subtractionParameters()[0]; double u = subtractionParameters()[1]; Energy2 prop = 2.*((realEmissionME()->lastXComb().meMomenta()[realEmitter()])* (realEmissionME()->lastXComb().meMomenta()[realEmission()]))*x; double muj2 = sqr( (realEmissionME()->lastXComb().mePartonData()[realSpectator()]->hardProcessMass()) ) / (2.* (realEmissionME()->lastXComb().meMomenta()[bornSpectator()])* (realEmissionME()->lastXComb().meMomenta()[realEmitter()]) ); double res = x + 2.*(1.-x)/x - 2.*muj2/x*u/(1.-u); double CF = (SM().Nc()*SM().Nc()-1.)/(2.*SM().Nc()); res *= 8.*CF*Constants::pi*(realEmissionME()->lastXComb().lastSHat())* (underlyingBornME()->lastXComb().lastAlphaS())/prop; res *= -ccme2; res *= pow(realEmissionME()->lastXComb().lastSHat() / underlyingBornME()->lastXComb().lastSHat(), underlyingBornME()->lastXComb().mePartonData().size()-4.); res *= realEmissionME()->finalStateSymmetry() / underlyingBornME()->finalStateSymmetry(); return res; } double IFMqqxDipole::me2() const { if ( jacobian() == 0.0 ) return 0.0; double x = subtractionParameters()[0]; double u = subtractionParameters()[1]; Energy2 prop = 2.*((realEmissionME()->lastXComb().meMomenta()[realEmitter()])* (realEmissionME()->lastXComb().meMomenta()[realEmission()]))*x; Lorentz5Momentum pc = realEmissionME()->lastXComb().meMomenta()[realEmission()]/u - realEmissionME()->lastXComb().meMomenta()[realSpectator()]/(1.-u); Energy2 sc = realEmissionME()->lastXComb().meMomenta()[realEmission()]* realEmissionME()->lastXComb().meMomenta()[realSpectator()]; sc /= u*(1.-u)*(1.-x)/x; SpinCorrelationTensor corr(-x,pc,sc/2.); double res = -underlyingBornME()->spinColourCorrelatedME2(make_pair(bornEmitter(),bornSpectator()), corr); double CF = (SM().Nc()*SM().Nc()-1.)/(2.*SM().Nc()); res *= 8.*CF*Constants::pi*(realEmissionME()->lastXComb().lastSHat())* (underlyingBornME()->lastXComb().lastAlphaS())/prop; res *= pow(realEmissionME()->lastXComb().lastSHat() / underlyingBornME()->lastXComb().lastSHat(), underlyingBornME()->lastXComb().mePartonData().size()-4.); res *= realEmissionME()->finalStateSymmetry() / underlyingBornME()->finalStateSymmetry(); return res; } void IFMqqxDipole::persistentOutput(PersistentOStream &) const { } void IFMqqxDipole::persistentInput(PersistentIStream &, int) { } void IFMqqxDipole::Init() { static ClassDocumentation documentation ("IFMqqxDipole"); // DipoleRepository::registerDipole<0,IFMqqxDipole,IFLightTildeKinematics,IFLightInvertedTildeKinematics> // ("IFMqqxDipole","IFLightTildeKinematics","IFLightInvertedTildeKinematics"); DipoleRepository::registerDipole<0,IFMqqxDipole,IFMassiveTildeKinematics,IFMassiveInvertedTildeKinematics> ("IFMqqxDipole","IFMassiveTildeKinematics","IFMassiveInvertedTildeKinematics"); } // *** 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 describeHerwigIFMqqxDipole("Herwig::IFMqqxDipole", "Herwig.so"); diff --git a/MatrixElement/Matchbox/Dipoles/IFMqqxDipole.h b/MatrixElement/Matchbox/Dipoles/IFMqqxDipole.h --- a/MatrixElement/Matchbox/Dipoles/IFMqqxDipole.h +++ b/MatrixElement/Matchbox/Dipoles/IFMqqxDipole.h @@ -1,162 +1,154 @@ // -*- C++ -*- // // IFMqqxDipole.h is a part of Herwig - A multi-purpose Monte Carlo event generator // Copyright (C) 2002-2019 The Herwig Collaboration // // Herwig is licenced under version 3 of the GPL, see COPYING for details. // Please respect the MCnet academic guidelines, see GUIDELINES for details. // #ifndef HERWIG_IFMqqxDipole_H #define HERWIG_IFMqqxDipole_H // // This is the declaration of the IFMqqxDipole class. // #include "Herwig/MatrixElement/Matchbox/Dipoles/SubtractionDipole.h" namespace Herwig { using namespace ThePEG; /** * \ingroup Matchbox * \author Simon Platzer * * \brief IFMqqxDipole implements the D^{q,qbar}_k subtraction dipole. * */ class IFMqqxDipole: public SubtractionDipole { public: - /** @name Standard constructors and destructors. */ - //@{ /** * The default constructor. */ IFMqqxDipole(); - /** - * The destructor. - */ - virtual ~IFMqqxDipole(); - //@} - public: /** * Return true, if this dipole can possibly handle the indicated * emitter. */ virtual bool canHandleEmitter(const cPDVector& partons, int emitter) const { return emitter < 2 && abs(partons[emitter]->id()) < 7; } /** * Return true, if this dipole can possibly handle the indicated * splitting. */ virtual bool canHandleSplitting(const cPDVector& partons, int emitter, int emission) const { return canHandleEmitter(partons,emitter) && partons[emitter]->id() == partons[emission]->id(); } /** * Return true, if this dipole can possibly handle the indicated * spectator. */ virtual bool canHandleSpectator(const cPDVector& partons, int spectator) const { return spectator > 1 && partons[spectator]->coloured(); } /** * Return true, if this dipole applies to the selected * configuration. */ virtual bool canHandle(const cPDVector& partons, int emitter, int emission, int spectator) const; /** * How to sample the z-distribution. * FlatZ = 1 * OneOverZ = 2 * OneOverOneMinusZ = 3 * OneOverZOneMinusZ = 4 */ virtual int samplingZ() const {return 2;} /** * Return the matrix element for the kinematical configuation * previously provided by the last call to setKinematics(), suitably * scaled by sHat() to give a dimension-less number. */ virtual double me2() const; /** * Return the matrix element averaged over spin correlations. */ virtual double me2Avg(double ccme2) 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. */ IFMqqxDipole & operator=(const IFMqqxDipole &) = delete; }; } #endif /* HERWIG_IFMqqxDipole_H */ diff --git a/MatrixElement/Matchbox/Dipoles/IFggxDipole.cc b/MatrixElement/Matchbox/Dipoles/IFggxDipole.cc --- a/MatrixElement/Matchbox/Dipoles/IFggxDipole.cc +++ b/MatrixElement/Matchbox/Dipoles/IFggxDipole.cc @@ -1,150 +1,148 @@ // -*- C++ -*- // // IFggxDipole.cc is a part of Herwig - A multi-purpose Monte Carlo event generator // Copyright (C) 2002-2019 The Herwig Collaboration // // Herwig is licenced under version 3 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 IFggxDipole class. // #include "IFggxDipole.h" #include "ThePEG/Interface/ClassDocumentation.h" #include "ThePEG/Utilities/DescribeClass.h" #include "ThePEG/MatrixElement/Tree2toNDiagram.h" #include "ThePEG/StandardModel/StandardModelBase.h" #include "ThePEG/Persistency/PersistentOStream.h" #include "ThePEG/Persistency/PersistentIStream.h" #include "Herwig/MatrixElement/Matchbox/Base/DipoleRepository.h" #include "Herwig/MatrixElement/Matchbox/Utility/SpinCorrelationTensor.h" #include "Herwig/MatrixElement/Matchbox/Phasespace/IFLightTildeKinematics.h" #include "Herwig/MatrixElement/Matchbox/Phasespace/IFLightInvertedTildeKinematics.h" using namespace Herwig; IFggxDipole::IFggxDipole() : SubtractionDipole() {} -IFggxDipole::~IFggxDipole() {} - IBPtr IFggxDipole::clone() const { return new_ptr(*this); } IBPtr IFggxDipole::fullclone() const { return new_ptr(*this); } bool IFggxDipole::canHandle(const cPDVector& partons, int emitter, int emission, int spectator) const { return emitter < 2 && spectator > 1 && partons[emission]->id() == ParticleID::g && partons[emitter]->id() == ParticleID::g && partons[spectator]->hardProcessMass() == ZERO; } double IFggxDipole::me2Avg(double ccme2) const { if ( jacobian() == 0.0 ) return 0.0; double x = subtractionParameters()[0]; double u = subtractionParameters()[1]; Energy2 prop = 2.*((realEmissionME()->lastXComb().meMomenta()[realEmitter()])* (realEmissionME()->lastXComb().meMomenta()[realEmission()]))*x; double res = 1./(1.-x+u) + (1.-x)/x - 1. + x*(1.-x); res *= 16.*Constants::pi*SM().Nc()*(realEmissionME()->lastXComb().lastSHat())* (underlyingBornME()->lastXComb().lastAlphaS())/prop; res *= -ccme2; res *= pow(realEmissionME()->lastXComb().lastSHat() / underlyingBornME()->lastXComb().lastSHat(), underlyingBornME()->lastXComb().mePartonData().size()-4.); res *= realEmissionME()->finalStateSymmetry() / underlyingBornME()->finalStateSymmetry(); return res; } double IFggxDipole::me2() const { if ( jacobian() == 0.0 ) return 0.0; double x = subtractionParameters()[0]; double u = subtractionParameters()[1]; if ( alpha() < u ) return 0.0; Energy2 prop = 2.*((realEmissionME()->lastXComb().meMomenta()[realEmitter()])* (realEmissionME()->lastXComb().meMomenta()[realEmission()]))*x; double diag = 1./(1.-x+u)-1.+x*(1.-x); Lorentz5Momentum pc = realEmissionME()->lastXComb().meMomenta()[realEmission()]/u - realEmissionME()->lastXComb().meMomenta()[realSpectator()]/(1.-u); Energy2 sc = realEmissionME()->lastXComb().meMomenta()[realEmission()]* realEmissionME()->lastXComb().meMomenta()[realSpectator()]; sc /= u*(1.-u)*(1.-x)/x; SpinCorrelationTensor corr(-diag,pc,sc); double res = -underlyingBornME()->spinColourCorrelatedME2(make_pair(bornEmitter(),bornSpectator()), corr); res *= 16.*Constants::pi*SM().Nc()*(realEmissionME()->lastXComb().lastSHat())* (underlyingBornME()->lastXComb().lastAlphaS())/prop; res *= pow(realEmissionME()->lastXComb().lastSHat() / underlyingBornME()->lastXComb().lastSHat(), underlyingBornME()->lastXComb().mePartonData().size()-4.); res *= realEmissionME()->finalStateSymmetry() / underlyingBornME()->finalStateSymmetry(); return res; } void IFggxDipole::persistentOutput(PersistentOStream &) const { } void IFggxDipole::persistentInput(PersistentIStream &, int) { } void IFggxDipole::Init() { static ClassDocumentation documentation ("IFggxDipole"); DipoleRepository::registerDipole<0,IFggxDipole,IFLightTildeKinematics,IFLightInvertedTildeKinematics> ("IFggxDipole","IFLightTildeKinematics","IFLightInvertedTildeKinematics"); } // *** 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 describeHerwigIFggxDipole("Herwig::IFggxDipole", "Herwig.so"); diff --git a/MatrixElement/Matchbox/Dipoles/IFggxDipole.h b/MatrixElement/Matchbox/Dipoles/IFggxDipole.h --- a/MatrixElement/Matchbox/Dipoles/IFggxDipole.h +++ b/MatrixElement/Matchbox/Dipoles/IFggxDipole.h @@ -1,160 +1,152 @@ // -*- C++ -*- // // IFggxDipole.h is a part of Herwig - A multi-purpose Monte Carlo event generator // Copyright (C) 2002-2019 The Herwig Collaboration // // Herwig is licenced under version 3 of the GPL, see COPYING for details. // Please respect the MCnet academic guidelines, see GUIDELINES for details. // #ifndef HERWIG_IFggxDipole_H #define HERWIG_IFggxDipole_H // // This is the declaration of the IFggxDipole class. // #include "Herwig/MatrixElement/Matchbox/Dipoles/SubtractionDipole.h" namespace Herwig { using namespace ThePEG; /** * \ingroup Matchbox * \author Simon Platzer * * \brief IFggxDipole implements the D^{g,g}_k subtraction dipole. * */ class IFggxDipole: public SubtractionDipole { public: - /** @name Standard constructors and destructors. */ - //@{ /** * The default constructor. */ IFggxDipole(); - /** - * The destructor. - */ - virtual ~IFggxDipole(); - //@} - public: /** * Return true, if this dipole can possibly handle the indicated * emitter. */ virtual bool canHandleEmitter(const cPDVector& partons, int emitter) const { return emitter < 2 && partons[emitter]->id() == ParticleID::g; } /** * Return true, if this dipole can possibly handle the indicated * splitting. */ virtual bool canHandleSplitting(const cPDVector& partons, int emitter, int emission) const { return canHandleEmitter(partons,emitter) && partons[emission]->id() == ParticleID::g; } /** * Return true, if this dipole can possibly handle the indicated * spectator. */ virtual bool canHandleSpectator(const cPDVector& partons, int spectator) const { return spectator > 1 && partons[spectator]->coloured(); } /** * Return true, if this dipole applies to the selected * configuration. */ virtual bool canHandle(const cPDVector& partons, int emitter, int emission, int spectator) const; /** * How to sample the z-distribution. * FlatZ = 1 * OneOverZ = 2 * OneOverOneMinusZ = 3 * OneOverZOneMinusZ = 4 */ virtual int samplingZ() const {return 4;} /** * Return the matrix element for the kinematical configuation * previously provided by the last call to setKinematics(), suitably * scaled by sHat() to give a dimension-less number. */ virtual double me2() const; /** * Return the matrix element averaged over spin correlations. */ virtual double me2Avg(double ccme2) 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. */ IFggxDipole & operator=(const IFggxDipole &) = delete; }; } #endif /* HERWIG_IFggxDipole_H */ diff --git a/MatrixElement/Matchbox/Dipoles/IFgqxDipole.cc b/MatrixElement/Matchbox/Dipoles/IFgqxDipole.cc --- a/MatrixElement/Matchbox/Dipoles/IFgqxDipole.cc +++ b/MatrixElement/Matchbox/Dipoles/IFgqxDipole.cc @@ -1,140 +1,138 @@ // -*- C++ -*- // // IFgqxDipole.cc is a part of Herwig - A multi-purpose Monte Carlo event generator // Copyright (C) 2002-2019 The Herwig Collaboration // // Herwig is licenced under version 3 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 IFgqxDipole class. // #include "IFgqxDipole.h" #include "ThePEG/Interface/ClassDocumentation.h" #include "ThePEG/Utilities/DescribeClass.h" #include "ThePEG/MatrixElement/Tree2toNDiagram.h" #include "ThePEG/StandardModel/StandardModelBase.h" #include "ThePEG/Persistency/PersistentOStream.h" #include "ThePEG/Persistency/PersistentIStream.h" #include "Herwig/MatrixElement/Matchbox/Base/DipoleRepository.h" #include "Herwig/MatrixElement/Matchbox/Phasespace/IFLightTildeKinematics.h" #include "Herwig/MatrixElement/Matchbox/Phasespace/IFLightInvertedTildeKinematics.h" using namespace Herwig; IFgqxDipole::IFgqxDipole() : SubtractionDipole() {} -IFgqxDipole::~IFgqxDipole() {} - IBPtr IFgqxDipole::clone() const { return new_ptr(*this); } IBPtr IFgqxDipole::fullclone() const { return new_ptr(*this); } bool IFgqxDipole::canHandle(const cPDVector& partons, int emitter, int emission, int spectator) const { return emitter < 2 && spectator > 1 && partons[emitter]->id() == ParticleID::g && abs(partons[emission]->id()) < 6 && partons[emission]->hardProcessMass() == ZERO && partons[spectator]->hardProcessMass() == ZERO; } double IFgqxDipole::me2Avg(double ccme2) const { if ( jacobian() == 0.0 ) return 0.0; double x = subtractionParameters()[0]; Energy2 prop = 2.*((realEmissionME()->lastXComb().meMomenta()[realEmitter()])* (realEmissionME()->lastXComb().meMomenta()[realEmission()]))*x; double res = 8.*Constants::pi*(realEmissionME()->lastXComb().lastSHat())* (underlyingBornME()->lastXComb().lastAlphaS())/prop; res *= .5 * ( 1.-2.*x*(1.-x) ); res *= -ccme2; res *= pow(realEmissionME()->lastXComb().lastSHat() / underlyingBornME()->lastXComb().lastSHat(), underlyingBornME()->lastXComb().mePartonData().size()-4.); res *= realEmissionME()->finalStateSymmetry() / underlyingBornME()->finalStateSymmetry(); return res; } double IFgqxDipole::me2() const { if ( jacobian() == 0.0 ) return 0.0; double x = subtractionParameters()[0]; double u = subtractionParameters()[1]; if ( alpha() < u ) return 0.0; Energy2 prop = 2.*((realEmissionME()->lastXComb().meMomenta()[realEmitter()])* (realEmissionME()->lastXComb().meMomenta()[realEmission()]))*x; double res = 8.*Constants::pi*(realEmissionME()->lastXComb().lastSHat())* (underlyingBornME()->lastXComb().lastAlphaS())/prop; res *= .5 * ( 1.-2.*x*(1.-x) ); res *= -underlyingBornME()->colourCorrelatedME2(make_pair(bornEmitter(),bornSpectator())); res *= pow(realEmissionME()->lastXComb().lastSHat() / underlyingBornME()->lastXComb().lastSHat(), underlyingBornME()->lastXComb().mePartonData().size()-4.); res *= realEmissionME()->finalStateSymmetry() / underlyingBornME()->finalStateSymmetry(); return res; } void IFgqxDipole::persistentOutput(PersistentOStream &) const { } void IFgqxDipole::persistentInput(PersistentIStream &, int) { } void IFgqxDipole::Init() { static ClassDocumentation documentation ("IFgqxDipole"); DipoleRepository::registerDipole<0,IFgqxDipole,IFLightTildeKinematics,IFLightInvertedTildeKinematics> ("IFgqxDipole","IFLightTildeKinematics","IFLightInvertedTildeKinematics"); } // *** 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 describeHerwigIFgqxDipole("Herwig::IFgqxDipole", "Herwig.so"); diff --git a/MatrixElement/Matchbox/Dipoles/IFgqxDipole.h b/MatrixElement/Matchbox/Dipoles/IFgqxDipole.h --- a/MatrixElement/Matchbox/Dipoles/IFgqxDipole.h +++ b/MatrixElement/Matchbox/Dipoles/IFgqxDipole.h @@ -1,160 +1,152 @@ // -*- C++ -*- // // IFgqxDipole.h is a part of Herwig - A multi-purpose Monte Carlo event generator // Copyright (C) 2002-2019 The Herwig Collaboration // // Herwig is licenced under version 3 of the GPL, see COPYING for details. // Please respect the MCnet academic guidelines, see GUIDELINES for details. // #ifndef HERWIG_IFgqxDipole_H #define HERWIG_IFgqxDipole_H // // This is the declaration of the IFgqxDipole class. // #include "Herwig/MatrixElement/Matchbox/Dipoles/SubtractionDipole.h" namespace Herwig { using namespace ThePEG; /** * \ingroup Matchbox * \author Simon Platzer * * \brief IFgqxDipole implements the D_k^{g,q} subtraction dipole. * */ class IFgqxDipole: public SubtractionDipole { public: - /** @name Standard constructors and destructors. */ - //@{ /** * The default constructor. */ IFgqxDipole(); - /** - * The destructor. - */ - virtual ~IFgqxDipole(); - //@} - public: /** * Return true, if this dipole can possibly handle the indicated * emitter. */ virtual bool canHandleEmitter(const cPDVector& partons, int emitter) const { return emitter < 2 && partons[emitter]->id() == ParticleID::g; } /** * Return true, if this dipole can possibly handle the indicated * splitting. */ virtual bool canHandleSplitting(const cPDVector& partons, int emitter, int emission) const { return canHandleEmitter(partons,emitter) && abs(partons[emission]->id()) < 7; } /** * Return true, if this dipole can possibly handle the indicated * spectator. */ virtual bool canHandleSpectator(const cPDVector& partons, int spectator) const { return spectator > 1 && partons[spectator]->coloured(); } /** * Return true, if this dipole applies to the selected * configuration. */ virtual bool canHandle(const cPDVector& partons, int emitter, int emission, int spectator) const; /** * How to sample the z-distribution. * FlatZ = 1 * OneOverZ = 2 * OneOverOneMinusZ = 3 * OneOverZOneMinusZ = 4 */ virtual int samplingZ() const {return 2;} /** * Return the matrix element for the kinematical configuation * previously provided by the last call to setKinematics(), suitably * scaled by sHat() to give a dimension-less number. */ virtual double me2() const; /** * Return the matrix element averaged over spin correlations. */ virtual double me2Avg(double ccme2) 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. */ IFgqxDipole & operator=(const IFgqxDipole &) = delete; }; } #endif /* HERWIG_IFgqxDipole_H */ diff --git a/MatrixElement/Matchbox/Dipoles/IFqgxDipole.cc b/MatrixElement/Matchbox/Dipoles/IFqgxDipole.cc --- a/MatrixElement/Matchbox/Dipoles/IFqgxDipole.cc +++ b/MatrixElement/Matchbox/Dipoles/IFqgxDipole.cc @@ -1,151 +1,149 @@ // -*- C++ -*- // // IFqgxDipole.cc is a part of Herwig - A multi-purpose Monte Carlo event generator // Copyright (C) 2002-2019 The Herwig Collaboration // // Herwig is licenced under version 3 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 IFqgxDipole class. // #include "IFqgxDipole.h" #include "ThePEG/Interface/ClassDocumentation.h" #include "ThePEG/Utilities/DescribeClass.h" #include "ThePEG/MatrixElement/Tree2toNDiagram.h" #include "ThePEG/StandardModel/StandardModelBase.h" #include "ThePEG/Persistency/PersistentOStream.h" #include "ThePEG/Persistency/PersistentIStream.h" #include "Herwig/MatrixElement/Matchbox/Base/DipoleRepository.h" #include "Herwig/MatrixElement/Matchbox/Phasespace/IFLightTildeKinematics.h" #include "Herwig/MatrixElement/Matchbox/Phasespace/IFLightInvertedTildeKinematics.h" using namespace Herwig; IFqgxDipole::IFqgxDipole() : SubtractionDipole() {} -IFqgxDipole::~IFqgxDipole() {} - IBPtr IFqgxDipole::clone() const { return new_ptr(*this); } IBPtr IFqgxDipole::fullclone() const { return new_ptr(*this); } bool IFqgxDipole::canHandle(const cPDVector& partons, int emitter, int emission, int spectator) const { return emitter < 2 && spectator > 1 && partons[emission]->id() == ParticleID::g && abs(partons[emitter]->id()) < 6 && partons[emitter]->hardProcessMass() == ZERO && partons[spectator]->hardProcessMass() == ZERO; } double IFqgxDipole::me2Avg(double ccme2) const { if ( jacobian() == 0.0 ) return 0.0; double x = subtractionParameters()[0]; double u = subtractionParameters()[1]; Energy2 prop = 2.*((realEmissionME()->lastXComb().meMomenta()[realEmitter()])* (realEmissionME()->lastXComb().meMomenta()[realEmission()]))*x; double CF = (SM().Nc()*SM().Nc()-1.)/(2.*SM().Nc()); double res = 8.*Constants::pi*CF*(realEmissionME()->lastXComb().lastSHat())* (underlyingBornME()->lastXComb().lastAlphaS())/prop; res *= ( 2./(1.-x+u) - (1.+x) + u*(1.+3.*x*(1.-u)) ); res *= -ccme2; res *= pow(realEmissionME()->lastXComb().lastSHat() / underlyingBornME()->lastXComb().lastSHat(), underlyingBornME()->lastXComb().mePartonData().size()-4.); res *= realEmissionME()->finalStateSymmetry() / underlyingBornME()->finalStateSymmetry(); return res; } double IFqgxDipole::me2() const { if ( jacobian() == 0.0 ) return 0.0; double x = subtractionParameters()[0]; double u = subtractionParameters()[1]; if ( alpha() < u ) return 0.0; Energy2 prop = 2.*((realEmissionME()->lastXComb().meMomenta()[realEmitter()])* (realEmissionME()->lastXComb().meMomenta()[realEmission()]))*x; double CF = (SM().Nc()*SM().Nc()-1.)/(2.*SM().Nc()); double res = 8.*Constants::pi*CF*(realEmissionME()->lastXComb().lastSHat())* (underlyingBornME()->lastXComb().lastAlphaS())/prop; res *= ( 2./(1.-x+u) - (1.+x) //+ u*(1.+3.*x*(1.-u)) ); res *= -underlyingBornME()->colourCorrelatedME2(make_pair(bornEmitter(),bornSpectator())); res *= pow(realEmissionME()->lastXComb().lastSHat() / underlyingBornME()->lastXComb().lastSHat(), underlyingBornME()->lastXComb().mePartonData().size()-4.); res *= realEmissionME()->finalStateSymmetry() / underlyingBornME()->finalStateSymmetry(); return res; } void IFqgxDipole::persistentOutput(PersistentOStream &) const { } void IFqgxDipole::persistentInput(PersistentIStream &, int) { } void IFqgxDipole::Init() { static ClassDocumentation documentation ("IFqgxDipole"); DipoleRepository::registerDipole<0,IFqgxDipole,IFLightTildeKinematics,IFLightInvertedTildeKinematics> ("IFqgxDipole","IFLightTildeKinematics","IFLightInvertedTildeKinematics"); } // *** 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 describeHerwigIFqgxDipole("Herwig::IFqgxDipole", "Herwig.so"); diff --git a/MatrixElement/Matchbox/Dipoles/IFqgxDipole.h b/MatrixElement/Matchbox/Dipoles/IFqgxDipole.h --- a/MatrixElement/Matchbox/Dipoles/IFqgxDipole.h +++ b/MatrixElement/Matchbox/Dipoles/IFqgxDipole.h @@ -1,160 +1,152 @@ // -*- C++ -*- // // IFqgxDipole.h is a part of Herwig - A multi-purpose Monte Carlo event generator // Copyright (C) 2002-2019 The Herwig Collaboration // // Herwig is licenced under version 3 of the GPL, see COPYING for details. // Please respect the MCnet academic guidelines, see GUIDELINES for details. // #ifndef HERWIG_IFqgxDipole_H #define HERWIG_IFqgxDipole_H // // This is the declaration of the IFqgxDipole class. // #include "Herwig/MatrixElement/Matchbox/Dipoles/SubtractionDipole.h" namespace Herwig { using namespace ThePEG; /** * \ingroup Matchbox * \author Simon Platzer * * \brief IFqgxDipole implements the D^{q,g}_k subtraction dipole * */ class IFqgxDipole: public SubtractionDipole { public: - /** @name Standard constructors and destructors. */ - //@{ /** * The default constructor. */ IFqgxDipole(); - /** - * The destructor. - */ - virtual ~IFqgxDipole(); - //@} - public: /** * Return true, if this dipole can possibly handle the indicated * emitter. */ virtual bool canHandleEmitter(const cPDVector& partons, int emitter) const { return emitter < 2 && abs(partons[emitter]->id()) < 7; } /** * Return true, if this dipole can possibly handle the indicated * splitting. */ virtual bool canHandleSplitting(const cPDVector& partons, int emitter, int emission) const { return canHandleEmitter(partons,emitter) && partons[emission]->id() == ParticleID::g; } /** * Return true, if this dipole can possibly handle the indicated * spectator. */ virtual bool canHandleSpectator(const cPDVector& partons, int spectator) const { return spectator > 1 && partons[spectator]->coloured(); } /** * Return true, if this dipole applies to the selected * configuration. */ virtual bool canHandle(const cPDVector& partons, int emitter, int emission, int spectator) const; /** * How to sample the z-distribution. * FlatZ = 1 * OneOverZ = 2 * OneOverOneMinusZ = 3 * OneOverZOneMinusZ = 4 */ virtual int samplingZ() const {return 4;} /** * Return the matrix element for the kinematical configuation * previously provided by the last call to setKinematics(), suitably * scaled by sHat() to give a dimension-less number. */ virtual double me2() const; /** * Return the matrix element averaged over spin correlations. */ virtual double me2Avg(double ccme2) 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. */ IFqgxDipole & operator=(const IFqgxDipole &) = delete; }; } #endif /* HERWIG_IFqgxDipole_H */ diff --git a/MatrixElement/Matchbox/Dipoles/IFqqxDipole.cc b/MatrixElement/Matchbox/Dipoles/IFqqxDipole.cc --- a/MatrixElement/Matchbox/Dipoles/IFqqxDipole.cc +++ b/MatrixElement/Matchbox/Dipoles/IFqqxDipole.cc @@ -1,155 +1,153 @@ // -*- C++ -*- // // IFqqxDipole.cc is a part of Herwig - A multi-purpose Monte Carlo event generator // Copyright (C) 2002-2019 The Herwig Collaboration // // Herwig is licenced under version 3 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 IFqqxDipole class. // #include "IFqqxDipole.h" #include "ThePEG/Interface/ClassDocumentation.h" #include "ThePEG/Utilities/DescribeClass.h" #include "ThePEG/MatrixElement/Tree2toNDiagram.h" #include "ThePEG/StandardModel/StandardModelBase.h" #include "ThePEG/Persistency/PersistentOStream.h" #include "ThePEG/Persistency/PersistentIStream.h" #include "Herwig/MatrixElement/Matchbox/Base/DipoleRepository.h" #include "Herwig/MatrixElement/Matchbox/Utility/SpinCorrelationTensor.h" #include "Herwig/MatrixElement/Matchbox/Phasespace/IFLightTildeKinematics.h" #include "Herwig/MatrixElement/Matchbox/Phasespace/IFLightInvertedTildeKinematics.h" using namespace Herwig; IFqqxDipole::IFqqxDipole() : SubtractionDipole() {} -IFqqxDipole::~IFqqxDipole() {} - IBPtr IFqqxDipole::clone() const { return new_ptr(*this); } IBPtr IFqqxDipole::fullclone() const { return new_ptr(*this); } bool IFqqxDipole::canHandle(const cPDVector& partons, int emitter, int emission, int spectator) const { return emitter < 2 && spectator > 1 && abs(partons[emission]->id()) < 6 && abs(partons[emitter]->id()) < 6 && partons[emission]->id() - partons[emitter]->id() == 0 && partons[emitter]->hardProcessMass() == ZERO && partons[emission]->hardProcessMass() == ZERO && partons[spectator]->hardProcessMass() == ZERO; } double IFqqxDipole::me2Avg(double ccme2) const { if ( jacobian() == 0.0 ) return 0.0; double x = subtractionParameters()[0]; Energy2 prop = 2.*((realEmissionME()->lastXComb().meMomenta()[realEmitter()])* (realEmissionME()->lastXComb().meMomenta()[realEmission()]))*x; double res = x + 2.*(1.-x)/x; double CF = (SM().Nc()*SM().Nc()-1.)/(2.*SM().Nc()); res *= 8.*CF*Constants::pi*(realEmissionME()->lastXComb().lastSHat())* (underlyingBornME()->lastXComb().lastAlphaS())/prop; res *= -ccme2; res *= pow(realEmissionME()->lastXComb().lastSHat() / underlyingBornME()->lastXComb().lastSHat(), underlyingBornME()->lastXComb().mePartonData().size()-4.); res *= realEmissionME()->finalStateSymmetry() / underlyingBornME()->finalStateSymmetry(); return res; } double IFqqxDipole::me2() const { if ( jacobian() == 0.0 ) return 0.0; double x = subtractionParameters()[0]; double u = subtractionParameters()[1]; if ( alpha() < u ) return 0.0; Energy2 prop = 2.*((realEmissionME()->lastXComb().meMomenta()[realEmitter()])* (realEmissionME()->lastXComb().meMomenta()[realEmission()]))*x; Lorentz5Momentum pc = realEmissionME()->lastXComb().meMomenta()[realEmission()]/u - realEmissionME()->lastXComb().meMomenta()[realSpectator()]/(1.-u); Energy2 sc = realEmissionME()->lastXComb().meMomenta()[realEmission()]* realEmissionME()->lastXComb().meMomenta()[realSpectator()]; sc /= u*(1.-u)*(1.-x)/x; SpinCorrelationTensor corr(-x,pc,sc/2.); double res = -underlyingBornME()->spinColourCorrelatedME2(make_pair(bornEmitter(),bornSpectator()), corr); double CF = (SM().Nc()*SM().Nc()-1.)/(2.*SM().Nc()); res *= 8.*CF*Constants::pi*(realEmissionME()->lastXComb().lastSHat())* (underlyingBornME()->lastXComb().lastAlphaS())/prop; res *= pow(realEmissionME()->lastXComb().lastSHat() / underlyingBornME()->lastXComb().lastSHat(), underlyingBornME()->lastXComb().mePartonData().size()-4.); res *= realEmissionME()->finalStateSymmetry() / underlyingBornME()->finalStateSymmetry(); return res; } void IFqqxDipole::persistentOutput(PersistentOStream &) const { } void IFqqxDipole::persistentInput(PersistentIStream &, int) { } void IFqqxDipole::Init() { static ClassDocumentation documentation ("IFqqxDipole"); DipoleRepository::registerDipole<0,IFqqxDipole,IFLightTildeKinematics,IFLightInvertedTildeKinematics> ("IFqqxDipole","IFLightTildeKinematics","IFLightInvertedTildeKinematics"); } // *** 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 describeHerwigIFqqxDipole("Herwig::IFqqxDipole", "Herwig.so"); diff --git a/MatrixElement/Matchbox/Dipoles/IFqqxDipole.h b/MatrixElement/Matchbox/Dipoles/IFqqxDipole.h --- a/MatrixElement/Matchbox/Dipoles/IFqqxDipole.h +++ b/MatrixElement/Matchbox/Dipoles/IFqqxDipole.h @@ -1,162 +1,154 @@ // -*- C++ -*- // // IFqqxDipole.h is a part of Herwig - A multi-purpose Monte Carlo event generator // Copyright (C) 2002-2019 The Herwig Collaboration // // Herwig is licenced under version 3 of the GPL, see COPYING for details. // Please respect the MCnet academic guidelines, see GUIDELINES for details. // #ifndef HERWIG_IFqqxDipole_H #define HERWIG_IFqqxDipole_H // // This is the declaration of the IFqqxDipole class. // #include "Herwig/MatrixElement/Matchbox/Dipoles/SubtractionDipole.h" namespace Herwig { using namespace ThePEG; /** * \ingroup Matchbox * \author Simon Platzer * * \brief IFqqxDipole implements the D^{q,qbar}_k subtraction dipole. * */ class IFqqxDipole: public SubtractionDipole { public: - /** @name Standard constructors and destructors. */ - //@{ /** * The default constructor. */ IFqqxDipole(); - /** - * The destructor. - */ - virtual ~IFqqxDipole(); - //@} - public: /** * Return true, if this dipole can possibly handle the indicated * emitter. */ virtual bool canHandleEmitter(const cPDVector& partons, int emitter) const { return emitter < 2 && abs(partons[emitter]->id()) < 7; } /** * Return true, if this dipole can possibly handle the indicated * splitting. */ virtual bool canHandleSplitting(const cPDVector& partons, int emitter, int emission) const { return canHandleEmitter(partons,emitter) && partons[emitter]->id() == partons[emission]->id(); } /** * Return true, if this dipole can possibly handle the indicated * spectator. */ virtual bool canHandleSpectator(const cPDVector& partons, int spectator) const { return spectator > 1 && partons[spectator]->coloured(); } /** * Return true, if this dipole applies to the selected * configuration. */ virtual bool canHandle(const cPDVector& partons, int emitter, int emission, int spectator) const; /** * How to sample the z-distribution. * FlatZ = 1 * OneOverZ = 2 * OneOverOneMinusZ = 3 * OneOverZOneMinusZ = 4 */ virtual int samplingZ() const {return 2;} /** * Return the matrix element for the kinematical configuation * previously provided by the last call to setKinematics(), suitably * scaled by sHat() to give a dimension-less number. */ virtual double me2() const; /** * Return the matrix element averaged over spin correlations. */ virtual double me2Avg(double ccme2) 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. */ IFqqxDipole & operator=(const IFqqxDipole &) = delete; }; } #endif /* HERWIG_IFqqxDipole_H */ diff --git a/MatrixElement/Matchbox/Dipoles/IIggxDipole.cc b/MatrixElement/Matchbox/Dipoles/IIggxDipole.cc --- a/MatrixElement/Matchbox/Dipoles/IIggxDipole.cc +++ b/MatrixElement/Matchbox/Dipoles/IIggxDipole.cc @@ -1,149 +1,147 @@ // -*- C++ -*- // // IIggxDipole.cc is a part of Herwig - A multi-purpose Monte Carlo event generator // Copyright (C) 2002-2019 The Herwig Collaboration // // Herwig is licenced under version 3 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 IIggxDipole class. // #include "IIggxDipole.h" #include "ThePEG/Interface/ClassDocumentation.h" #include "ThePEG/Utilities/DescribeClass.h" #include "ThePEG/MatrixElement/Tree2toNDiagram.h" #include "ThePEG/StandardModel/StandardModelBase.h" #include "ThePEG/Persistency/PersistentOStream.h" #include "ThePEG/Persistency/PersistentIStream.h" #include "Herwig/MatrixElement/Matchbox/Base/DipoleRepository.h" #include "Herwig/MatrixElement/Matchbox/Utility/SpinCorrelationTensor.h" #include "Herwig/MatrixElement/Matchbox/Phasespace/IILightTildeKinematics.h" #include "Herwig/MatrixElement/Matchbox/Phasespace/IILightInvertedTildeKinematics.h" using namespace Herwig; IIggxDipole::IIggxDipole() : SubtractionDipole() {} -IIggxDipole::~IIggxDipole() {} - IBPtr IIggxDipole::clone() const { return new_ptr(*this); } IBPtr IIggxDipole::fullclone() const { return new_ptr(*this); } bool IIggxDipole::canHandle(const cPDVector& partons, int emitter, int emission, int spectator) const { return emitter < 2 && spectator < 2 && partons[emission]->id() == ParticleID::g && partons[emitter]->id() == ParticleID::g && partons[spectator]->hardProcessMass() == ZERO; } double IIggxDipole::me2Avg(double ccme2) const { if ( jacobian() == 0.0 ) return 0.0; double x = subtractionParameters()[0]; Energy2 prop = 2.*((realEmissionME()->lastXComb().meMomenta()[realEmitter()])* (realEmissionME()->lastXComb().meMomenta()[realEmission()]))*x; double res = x/(1.-x) + (1.-x)/x + x*(1.-x); res *= 16.*Constants::pi*SM().Nc()*(realEmissionME()->lastXComb().lastSHat())* (underlyingBornME()->lastXComb().lastAlphaS())/prop; res *= -ccme2; res *= pow(realEmissionME()->lastXComb().lastSHat() / underlyingBornME()->lastXComb().lastSHat(), underlyingBornME()->lastXComb().mePartonData().size()-4.); res *= realEmissionME()->finalStateSymmetry() / underlyingBornME()->finalStateSymmetry(); return res; } double IIggxDipole::me2() const { if ( jacobian() == 0.0 ) return 0.0; double x = subtractionParameters()[0]; double v = subtractionParameters()[1]; if ( alpha() < v ) return 0.0; Energy2 prop = 2.*((realEmissionME()->lastXComb().meMomenta()[realEmitter()])* (realEmissionME()->lastXComb().meMomenta()[realEmission()]))*x; double diag = x/(1.-x)+x*(1.-x); Lorentz5Momentum pc = realEmissionME()->lastXComb().meMomenta()[realEmission()] - v*realEmissionME()->lastXComb().meMomenta()[realSpectator()]; Energy2 sc = realEmissionME()->lastXComb().meMomenta()[realEmission()]* realEmissionME()->lastXComb().meMomenta()[realSpectator()]; sc /= (1.-x)/(x*v); SpinCorrelationTensor corr(-diag,pc,sc); double res = -underlyingBornME()->spinColourCorrelatedME2(make_pair(bornEmitter(),bornSpectator()), corr); res *= 16.*Constants::pi*SM().Nc()*(realEmissionME()->lastXComb().lastSHat())* (underlyingBornME()->lastXComb().lastAlphaS())/prop; res *= pow(realEmissionME()->lastXComb().lastSHat() / underlyingBornME()->lastXComb().lastSHat(), underlyingBornME()->lastXComb().mePartonData().size()-4.); res *= realEmissionME()->finalStateSymmetry() / underlyingBornME()->finalStateSymmetry(); return res; } void IIggxDipole::persistentOutput(PersistentOStream &) const { } void IIggxDipole::persistentInput(PersistentIStream &, int) { } void IIggxDipole::Init() { static ClassDocumentation documentation ("IIggxDipole"); DipoleRepository::registerDipole<0,IIggxDipole,IILightTildeKinematics,IILightInvertedTildeKinematics> ("IIggxDipole","IILightTildeKinematics","IILightInvertedTildeKinematics"); } // *** 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 describeHerwigIIggxDipole("Herwig::IIggxDipole", "Herwig.so"); diff --git a/MatrixElement/Matchbox/Dipoles/IIggxDipole.h b/MatrixElement/Matchbox/Dipoles/IIggxDipole.h --- a/MatrixElement/Matchbox/Dipoles/IIggxDipole.h +++ b/MatrixElement/Matchbox/Dipoles/IIggxDipole.h @@ -1,159 +1,151 @@ // -*- C++ -*- // // IIggxDipole.h is a part of Herwig - A multi-purpose Monte Carlo event generator // Copyright (C) 2002-2019 The Herwig Collaboration // // Herwig is licenced under version 3 of the GPL, see COPYING for details. // Please respect the MCnet academic guidelines, see GUIDELINES for details. // #ifndef HERWIG_IIggxDipole_H #define HERWIG_IIggxDipole_H // // This is the declaration of the IIggxDipole class. // #include "Herwig/MatrixElement/Matchbox/Dipoles/SubtractionDipole.h" namespace Herwig { using namespace ThePEG; /** * \ingroup Matchbox * \author Simon Platzer * * \brief IIggxDipole implements the D^{g,g;b} subtraction dipole. * */ class IIggxDipole: public SubtractionDipole { public: - /** @name Standard constructors and destructors. */ - //@{ /** * The default constructor. */ IIggxDipole(); - /** - * The destructor. - */ - virtual ~IIggxDipole(); - //@} - public: /** * Return true, if this dipole can possibly handle the indicated * emitter. */ virtual bool canHandleEmitter(const cPDVector& partons, int emitter) const { return emitter < 2 && partons[emitter]->id() == ParticleID::g; } /** * Return true, if this dipole can possibly handle the indicated * splitting. */ virtual bool canHandleSplitting(const cPDVector& partons, int emitter, int emission) const { return canHandleEmitter(partons,emitter) && partons[emission]->id() == ParticleID::g; } /** * Return true, if this dipole can possibly handle the indicated * spectator. */ virtual bool canHandleSpectator(const cPDVector& partons, int spectator) const { return spectator < 2 && partons[spectator]->coloured(); } /** * Return true, if this dipole applies to the selected * configuration. */ virtual bool canHandle(const cPDVector& partons, int emitter, int emission, int spectator) const; /** * How to sample the z-distribution. * FlatZ = 1 * OneOverZ = 2 * OneOverOneMinusZ = 3 * OneOverZOneMinusZ = 4 */ virtual int samplingZ() const {return 4;} /** * Return the matrix element for the kinematical configuation * previously provided by the last call to setKinematics(), suitably * scaled by sHat() to give a dimension-less number. */ virtual double me2() const; /** * Return the matrix element averaged over spin correlations. */ virtual double me2Avg(double ccme2) 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. */ IIggxDipole & operator=(const IIggxDipole &) = delete; }; } #endif /* HERWIG_IIggxDipole_H */ diff --git a/MatrixElement/Matchbox/Dipoles/IIgqxDipole.cc b/MatrixElement/Matchbox/Dipoles/IIgqxDipole.cc --- a/MatrixElement/Matchbox/Dipoles/IIgqxDipole.cc +++ b/MatrixElement/Matchbox/Dipoles/IIgqxDipole.cc @@ -1,140 +1,138 @@ // -*- C++ -*- // // IIgqxDipole.cc is a part of Herwig - A multi-purpose Monte Carlo event generator // Copyright (C) 2002-2019 The Herwig Collaboration // // Herwig is licenced under version 3 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 IIgqxDipole class. // #include "IIgqxDipole.h" #include "ThePEG/Interface/ClassDocumentation.h" #include "ThePEG/Utilities/DescribeClass.h" #include "ThePEG/MatrixElement/Tree2toNDiagram.h" #include "ThePEG/StandardModel/StandardModelBase.h" #include "ThePEG/Persistency/PersistentOStream.h" #include "ThePEG/Persistency/PersistentIStream.h" #include "Herwig/MatrixElement/Matchbox/Base/DipoleRepository.h" #include "Herwig/MatrixElement/Matchbox/Phasespace/IILightTildeKinematics.h" #include "Herwig/MatrixElement/Matchbox/Phasespace/IILightInvertedTildeKinematics.h" using namespace Herwig; IIgqxDipole::IIgqxDipole() : SubtractionDipole() {} -IIgqxDipole::~IIgqxDipole() {} - IBPtr IIgqxDipole::clone() const { return new_ptr(*this); } IBPtr IIgqxDipole::fullclone() const { return new_ptr(*this); } bool IIgqxDipole::canHandle(const cPDVector& partons, int emitter, int emission, int spectator) const { return emitter < 2 && spectator < 2 && partons[emitter]->id() == ParticleID::g && abs(partons[emission]->id()) < 6 && partons[emission]->hardProcessMass() == ZERO && partons[spectator]->hardProcessMass() == ZERO; } double IIgqxDipole::me2Avg(double ccme2) const { if ( jacobian() == 0.0 ) return 0.0; double x = subtractionParameters()[0]; Energy2 prop = 2.*((realEmissionME()->lastXComb().meMomenta()[realEmitter()])* (realEmissionME()->lastXComb().meMomenta()[realEmission()]))*x; double res = 8.*Constants::pi*(realEmissionME()->lastXComb().lastSHat())* (underlyingBornME()->lastXComb().lastAlphaS())/prop; res *= .5 * ( 1.-2.*x*(1.-x) ); res *= -ccme2; res *= pow(realEmissionME()->lastXComb().lastSHat() / underlyingBornME()->lastXComb().lastSHat(), underlyingBornME()->lastXComb().mePartonData().size()-4.); res *= realEmissionME()->finalStateSymmetry() / underlyingBornME()->finalStateSymmetry(); return res; } double IIgqxDipole::me2() const { if ( jacobian() == 0.0 ) return 0.0; double x = subtractionParameters()[0]; double v = subtractionParameters()[1]; if ( alpha() < v ) return 0.0; Energy2 prop = 2.*((realEmissionME()->lastXComb().meMomenta()[realEmitter()])* (realEmissionME()->lastXComb().meMomenta()[realEmission()]))*x; double res = 8.*Constants::pi*(realEmissionME()->lastXComb().lastSHat())* (underlyingBornME()->lastXComb().lastAlphaS())/prop; res *= .5 * ( 1.-2.*x*(1.-x) ); res *= -underlyingBornME()->colourCorrelatedME2(make_pair(bornEmitter(),bornSpectator())); res *= pow(realEmissionME()->lastXComb().lastSHat() / underlyingBornME()->lastXComb().lastSHat(), underlyingBornME()->lastXComb().mePartonData().size()-4.); res *= realEmissionME()->finalStateSymmetry() / underlyingBornME()->finalStateSymmetry(); return res; } void IIgqxDipole::persistentOutput(PersistentOStream &) const { } void IIgqxDipole::persistentInput(PersistentIStream &, int) { } void IIgqxDipole::Init() { static ClassDocumentation documentation ("IIgqxDipole"); DipoleRepository::registerDipole<0,IIgqxDipole,IILightTildeKinematics,IILightInvertedTildeKinematics> ("IIgqxDipole","IILightTildeKinematics","IILightInvertedTildeKinematics"); } // *** 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 describeHerwigIIgqxDipole("Herwig::IIgqxDipole", "Herwig.so"); diff --git a/MatrixElement/Matchbox/Dipoles/IIgqxDipole.h b/MatrixElement/Matchbox/Dipoles/IIgqxDipole.h --- a/MatrixElement/Matchbox/Dipoles/IIgqxDipole.h +++ b/MatrixElement/Matchbox/Dipoles/IIgqxDipole.h @@ -1,160 +1,152 @@ // -*- C++ -*- // // IIgqxDipole.h is a part of Herwig - A multi-purpose Monte Carlo event generator // Copyright (C) 2002-2019 The Herwig Collaboration // // Herwig is licenced under version 3 of the GPL, see COPYING for details. // Please respect the MCnet academic guidelines, see GUIDELINES for details. // #ifndef HERWIG_IIgqxDipole_H #define HERWIG_IIgqxDipole_H // // This is the declaration of the IIgqxDipole class. // #include "Herwig/MatrixElement/Matchbox/Dipoles/SubtractionDipole.h" namespace Herwig { using namespace ThePEG; /** * \ingroup Matchbox * \author Simon Platzer * * \brief IIgqxDipole implements the D^{g,q,k} subtraction dipole * */ class IIgqxDipole: public SubtractionDipole { public: - /** @name Standard constructors and destructors. */ - //@{ /** * The default constructor. */ IIgqxDipole(); - /** - * The destructor. - */ - virtual ~IIgqxDipole(); - //@} - public: /** * Return true, if this dipole can possibly handle the indicated * emitter. */ virtual bool canHandleEmitter(const cPDVector& partons, int emitter) const { return emitter < 2 && partons[emitter]->id() == ParticleID::g; } /** * Return true, if this dipole can possibly handle the indicated * splitting. */ virtual bool canHandleSplitting(const cPDVector& partons, int emitter, int emission) const { return canHandleEmitter(partons,emitter) && abs(partons[emission]->id()) < 7; } /** * Return true, if this dipole can possibly handle the indicated * spectator. */ virtual bool canHandleSpectator(const cPDVector& partons, int spectator) const { return spectator < 2 && partons[spectator]->coloured(); } /** * Return true, if this dipole applies to the selected * configuration. */ virtual bool canHandle(const cPDVector& partons, int emitter, int emission, int spectator) const; /** * How to sample the z-distribution. * FlatZ = 1 * OneOverZ = 2 * OneOverOneMinusZ = 3 * OneOverZOneMinusZ = 4 * N.B. not the perturbative result chosen to improve sampling */ virtual int samplingZ() const {return 2;} /** * Return the matrix element for the kinematical configuation * previously provided by the last call to setKinematics(), suitably * scaled by sHat() to give a dimension-less number. */ virtual double me2() const; /** * Return the matrix element averaged over spin correlations. */ virtual double me2Avg(double ccme2) 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. */ IIgqxDipole & operator=(const IIgqxDipole &) = delete; }; } #endif /* HERWIG_IIgqxDipole_H */ diff --git a/MatrixElement/Matchbox/Dipoles/IIqgxDipole.cc b/MatrixElement/Matchbox/Dipoles/IIqgxDipole.cc --- a/MatrixElement/Matchbox/Dipoles/IIqgxDipole.cc +++ b/MatrixElement/Matchbox/Dipoles/IIqgxDipole.cc @@ -1,144 +1,142 @@ // -*- C++ -*- // // IIqgxDipole.cc is a part of Herwig - A multi-purpose Monte Carlo event generator // Copyright (C) 2002-2019 The Herwig Collaboration // // Herwig is licenced under version 3 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 IIqgxDipole class. // #include "IIqgxDipole.h" #include "ThePEG/Interface/ClassDocumentation.h" #include "ThePEG/Utilities/DescribeClass.h" #include "ThePEG/MatrixElement/Tree2toNDiagram.h" #include "ThePEG/StandardModel/StandardModelBase.h" #include "ThePEG/Persistency/PersistentOStream.h" #include "ThePEG/Persistency/PersistentIStream.h" #include "Herwig/MatrixElement/Matchbox/Base/DipoleRepository.h" #include "Herwig/MatrixElement/Matchbox/Phasespace/IILightTildeKinematics.h" #include "Herwig/MatrixElement/Matchbox/Phasespace/IILightInvertedTildeKinematics.h" using namespace Herwig; IIqgxDipole::IIqgxDipole() : SubtractionDipole() {} -IIqgxDipole::~IIqgxDipole() {} - IBPtr IIqgxDipole::clone() const { return new_ptr(*this); } IBPtr IIqgxDipole::fullclone() const { return new_ptr(*this); } bool IIqgxDipole::canHandle(const cPDVector& partons, int emitter, int emission, int spectator) const { return emitter < 2 && spectator < 2 && partons[emission]->id() == ParticleID::g && abs(partons[emitter]->id()) < 6 && partons[emitter]->hardProcessMass() == ZERO && partons[spectator]->hardProcessMass() == ZERO; } double IIqgxDipole::me2Avg(double ccme2) const { if ( jacobian() == 0.0 ) return 0.0; double x = subtractionParameters()[0]; Energy2 prop = 2.*((realEmissionME()->lastXComb().meMomenta()[realEmitter()])* (realEmissionME()->lastXComb().meMomenta()[realEmission()]))*x; double CF = (SM().Nc()*SM().Nc()-1.)/(2.*SM().Nc()); double res = 8.*Constants::pi*CF*(realEmissionME()->lastXComb().lastSHat())* (underlyingBornME()->lastXComb().lastAlphaS())/prop; res *= 2./(1.-x) - (1.+x); res *= -ccme2; res *= pow(realEmissionME()->lastXComb().lastSHat() / underlyingBornME()->lastXComb().lastSHat(), underlyingBornME()->lastXComb().mePartonData().size()-4.); res *= realEmissionME()->finalStateSymmetry() / underlyingBornME()->finalStateSymmetry(); return res; } double IIqgxDipole::me2() const { if ( jacobian() == 0.0 ) return 0.0; double x = subtractionParameters()[0]; double v = subtractionParameters()[1]; if ( alpha() < v ) return 0.0; Energy2 prop = 2.*((realEmissionME()->lastXComb().meMomenta()[realEmitter()])* (realEmissionME()->lastXComb().meMomenta()[realEmission()]))*x; double CF = (SM().Nc()*SM().Nc()-1.)/(2.*SM().Nc()); double res = 8.*Constants::pi*CF*(realEmissionME()->lastXComb().lastSHat())* (underlyingBornME()->lastXComb().lastAlphaS())/prop; res *= 2./(1.-x) - (1.+x); res *= -underlyingBornME()->colourCorrelatedME2(make_pair(bornEmitter(),bornSpectator())); res *= pow(realEmissionME()->lastXComb().lastSHat() / underlyingBornME()->lastXComb().lastSHat(), underlyingBornME()->lastXComb().mePartonData().size()-4.); res *= realEmissionME()->finalStateSymmetry() / underlyingBornME()->finalStateSymmetry(); return res; } void IIqgxDipole::persistentOutput(PersistentOStream &) const { } void IIqgxDipole::persistentInput(PersistentIStream &, int) { } void IIqgxDipole::Init() { static ClassDocumentation documentation ("IIqgxDipole"); DipoleRepository::registerDipole<0,IIqgxDipole,IILightTildeKinematics,IILightInvertedTildeKinematics> ("IIqgxDipole","IILightTildeKinematics","IILightInvertedTildeKinematics"); } // *** 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 describeHerwigIIqgxDipole("Herwig::IIqgxDipole", "Herwig.so"); diff --git a/MatrixElement/Matchbox/Dipoles/IIqgxDipole.h b/MatrixElement/Matchbox/Dipoles/IIqgxDipole.h --- a/MatrixElement/Matchbox/Dipoles/IIqgxDipole.h +++ b/MatrixElement/Matchbox/Dipoles/IIqgxDipole.h @@ -1,160 +1,152 @@ // -*- C++ -*- // // IIqgxDipole.h is a part of Herwig - A multi-purpose Monte Carlo event generator // Copyright (C) 2002-2019 The Herwig Collaboration // // Herwig is licenced under version 3 of the GPL, see COPYING for details. // Please respect the MCnet academic guidelines, see GUIDELINES for details. // #ifndef HERWIG_IIqgxDipole_H #define HERWIG_IIqgxDipole_H // // This is the declaration of the IIqgxDipole class. // #include "Herwig/MatrixElement/Matchbox/Dipoles/SubtractionDipole.h" namespace Herwig { using namespace ThePEG; /** * \ingroup Matchbox * \author Simon Platzer * * \brief IIqgxDipole implements the D^{q,g;b} subtraction dipole * */ class IIqgxDipole: public SubtractionDipole { public: - /** @name Standard constructors and destructors. */ - //@{ /** * The default constructor. */ IIqgxDipole(); - /** - * The destructor. - */ - virtual ~IIqgxDipole(); - //@} - public: /** * Return true, if this dipole can possibly handle the indicated * emitter. */ virtual bool canHandleEmitter(const cPDVector& partons, int emitter) const { return emitter < 2 && abs(partons[emitter]->id()) < 7; } /** * Return true, if this dipole can possibly handle the indicated * splitting. */ virtual bool canHandleSplitting(const cPDVector& partons, int emitter, int emission) const { return canHandleEmitter(partons,emitter) && partons[emission]->id() == ParticleID::g; } /** * Return true, if this dipole can possibly handle the indicated * spectator. */ virtual bool canHandleSpectator(const cPDVector& partons, int spectator) const { return spectator < 2 && partons[spectator]->coloured(); } /** * Return true, if this dipole applies to the selected * configuration. */ virtual bool canHandle(const cPDVector& partons, int emitter, int emission, int spectator) const; /** * How to sample the z-distribution. * FlatZ = 1 * OneOverZ = 2 * OneOverOneMinusZ = 3 * OneOverZOneMinusZ = 4 */ virtual int samplingZ() const {return 4;} /** * Return the matrix element for the kinematical configuation * previously provided by the last call to setKinematics(), suitably * scaled by sHat() to give a dimension-less number. */ virtual double me2() const; /** * Return the matrix element averaged over spin correlations. */ virtual double me2Avg(double ccme2) 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. */ IIqgxDipole & operator=(const IIqgxDipole &) = delete; }; } #endif /* HERWIG_IIqgxDipole_H */ diff --git a/MatrixElement/Matchbox/Dipoles/IIqqxDipole.cc b/MatrixElement/Matchbox/Dipoles/IIqqxDipole.cc --- a/MatrixElement/Matchbox/Dipoles/IIqqxDipole.cc +++ b/MatrixElement/Matchbox/Dipoles/IIqqxDipole.cc @@ -1,155 +1,153 @@ // -*- C++ -*- // // IIqqxDipole.cc is a part of Herwig - A multi-purpose Monte Carlo event generator // Copyright (C) 2002-2019 The Herwig Collaboration // // Herwig is licenced under version 3 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 IIqqxDipole class. // #include "IIqqxDipole.h" #include "ThePEG/Interface/ClassDocumentation.h" #include "ThePEG/Utilities/DescribeClass.h" #include "ThePEG/MatrixElement/Tree2toNDiagram.h" #include "ThePEG/StandardModel/StandardModelBase.h" #include "ThePEG/Persistency/PersistentOStream.h" #include "ThePEG/Persistency/PersistentIStream.h" #include "Herwig/MatrixElement/Matchbox/Base/DipoleRepository.h" #include "Herwig/MatrixElement/Matchbox/Utility/SpinCorrelationTensor.h" #include "Herwig/MatrixElement/Matchbox/Phasespace/IILightTildeKinematics.h" #include "Herwig/MatrixElement/Matchbox/Phasespace/IILightInvertedTildeKinematics.h" using namespace Herwig; IIqqxDipole::IIqqxDipole() : SubtractionDipole() {} -IIqqxDipole::~IIqqxDipole() {} - IBPtr IIqqxDipole::clone() const { return new_ptr(*this); } IBPtr IIqqxDipole::fullclone() const { return new_ptr(*this); } bool IIqqxDipole::canHandle(const cPDVector& partons, int emitter, int emission, int spectator) const { return emitter < 2 && spectator < 2 && abs(partons[emission]->id()) < 6 && abs(partons[emitter]->id()) < 6 && partons[emission]->id() - partons[emitter]->id() == 0 && partons[emitter]->hardProcessMass() == ZERO && partons[emission]->hardProcessMass() == ZERO && partons[spectator]->hardProcessMass() == ZERO; } double IIqqxDipole::me2Avg(double ccme2) const { if ( jacobian() == 0.0 ) return 0.0; double x = subtractionParameters()[0]; Energy2 prop = 2.*((realEmissionME()->lastXComb().meMomenta()[realEmitter()])* (realEmissionME()->lastXComb().meMomenta()[realEmission()]))*x; double res = (1.+sqr(1.-x))/x; double CF = (SM().Nc()*SM().Nc()-1.)/(2.*SM().Nc()); res *= 8.*Constants::pi*CF*(realEmissionME()->lastXComb().lastSHat())* (underlyingBornME()->lastXComb().lastAlphaS())/prop; res *= -ccme2; res *= pow(realEmissionME()->lastXComb().lastSHat() / underlyingBornME()->lastXComb().lastSHat(), underlyingBornME()->lastXComb().mePartonData().size()-4.); res *= realEmissionME()->finalStateSymmetry() / underlyingBornME()->finalStateSymmetry(); return res; } double IIqqxDipole::me2() const { if ( jacobian() == 0.0 ) return 0.0; double x = subtractionParameters()[0]; double v = subtractionParameters()[1]; if ( alpha() < v ) return 0.0; Energy2 prop = 2.*((realEmissionME()->lastXComb().meMomenta()[realEmitter()])* (realEmissionME()->lastXComb().meMomenta()[realEmission()]))*x; Lorentz5Momentum pc = realEmissionME()->lastXComb().meMomenta()[realEmission()] - v*realEmissionME()->lastXComb().meMomenta()[realSpectator()]; Energy2 sc = realEmissionME()->lastXComb().meMomenta()[realEmission()]* realEmissionME()->lastXComb().meMomenta()[realSpectator()]; sc /= (1.-x)/(x*v); SpinCorrelationTensor corr(-x,pc,sc/2.); double res = -underlyingBornME()->spinColourCorrelatedME2(make_pair(bornEmitter(),bornSpectator()), corr); double CF = (SM().Nc()*SM().Nc()-1.)/(2.*SM().Nc()); res *= 8.*Constants::pi*CF*(realEmissionME()->lastXComb().lastSHat())* (underlyingBornME()->lastXComb().lastAlphaS())/prop; res *= pow(realEmissionME()->lastXComb().lastSHat() / underlyingBornME()->lastXComb().lastSHat(), underlyingBornME()->lastXComb().mePartonData().size()-4.); res *= realEmissionME()->finalStateSymmetry() / underlyingBornME()->finalStateSymmetry(); return res; } void IIqqxDipole::persistentOutput(PersistentOStream &) const { } void IIqqxDipole::persistentInput(PersistentIStream &, int) { } void IIqqxDipole::Init() { static ClassDocumentation documentation ("IIqqxDipole"); DipoleRepository::registerDipole<0,IIqqxDipole,IILightTildeKinematics,IILightInvertedTildeKinematics> ("IIqqxDipole","IILightTildeKinematics","IILightInvertedTildeKinematics"); } // *** 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 describeHerwigIIqqxDipole("Herwig::IIqqxDipole", "Herwig.so"); diff --git a/MatrixElement/Matchbox/Dipoles/IIqqxDipole.h b/MatrixElement/Matchbox/Dipoles/IIqqxDipole.h --- a/MatrixElement/Matchbox/Dipoles/IIqqxDipole.h +++ b/MatrixElement/Matchbox/Dipoles/IIqqxDipole.h @@ -1,162 +1,154 @@ // -*- C++ -*- // // IIqqxDipole.h is a part of Herwig - A multi-purpose Monte Carlo event generator // Copyright (C) 2002-2019 The Herwig Collaboration // // Herwig is licenced under version 3 of the GPL, see COPYING for details. // Please respect the MCnet academic guidelines, see GUIDELINES for details. // #ifndef HERWIG_IIqqxDipole_H #define HERWIG_IIqqxDipole_H // // This is the declaration of the IIqqxDipole class. // #include "Herwig/MatrixElement/Matchbox/Dipoles/SubtractionDipole.h" namespace Herwig { using namespace ThePEG; /** * \ingroup Matchbox * \author Simon Platzer * * \brief IIqqxDipole implements the D^{q,qbar;b} subtraction dipole. * */ class IIqqxDipole: public SubtractionDipole { public: - /** @name Standard constructors and destructors. */ - //@{ /** * The default constructor. */ IIqqxDipole(); - /** - * The destructor. - */ - virtual ~IIqqxDipole(); - //@} - public: /** * Return true, if this dipole can possibly handle the indicated * emitter. */ virtual bool canHandleEmitter(const cPDVector& partons, int emitter) const { return emitter < 2 && abs(partons[emitter]->id()) < 7; } /** * Return true, if this dipole can possibly handle the indicated * splitting. */ virtual bool canHandleSplitting(const cPDVector& partons, int emitter, int emission) const { return canHandleEmitter(partons,emitter) && partons[emitter]->id() == partons[emission]->id(); } /** * Return true, if this dipole can possibly handle the indicated * spectator. */ virtual bool canHandleSpectator(const cPDVector& partons, int spectator) const { return spectator < 2 && partons[spectator]->coloured(); } /** * Return true, if this dipole applies to the selected * configuration. */ virtual bool canHandle(const cPDVector& partons, int emitter, int emission, int spectator) const; /** * How to sample the z-distribution. * FlatZ = 1 * OneOverZ = 2 * OneOverOneMinusZ = 3 * OneOverZOneMinusZ = 4 */ virtual int samplingZ() const {return 2;} /** * Return the matrix element for the kinematical configuation * previously provided by the last call to setKinematics(), suitably * scaled by sHat() to give a dimension-less number. */ virtual double me2() const; /** * Return the matrix element averaged over spin correlations. */ virtual double me2Avg(double ccme2) 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. */ IIqqxDipole & operator=(const IIqqxDipole &) = delete; }; } #endif /* HERWIG_IIqqxDipole_H */ diff --git a/MatrixElement/Matchbox/MatchboxFactory.cc b/MatrixElement/Matchbox/MatchboxFactory.cc --- a/MatrixElement/Matchbox/MatchboxFactory.cc +++ b/MatrixElement/Matchbox/MatchboxFactory.cc @@ -1,2106 +1,2104 @@ // -*- C++ -*- // // MatchboxFactory.cc is a part of Herwig - A multi-purpose Monte Carlo event generator // Copyright (C) 2002-2019 The Herwig Collaboration // // Herwig is licenced under version 3 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 MatchboxFactory class. // #include "MatchboxFactory.h" #include "ThePEG/Interface/ClassDocumentation.h" #include "ThePEG/Utilities/DescribeClass.h" #include "ThePEG/Interface/Reference.h" #include "ThePEG/Interface/RefVector.h" #include "ThePEG/Interface/Switch.h" #include "ThePEG/Interface/Parameter.h" #include "ThePEG/Interface/Command.h" #include "ThePEG/Utilities/StringUtils.h" #include "ThePEG/Repository/Repository.h" #include "ThePEG/Repository/EventGenerator.h" #include "ThePEG/Handlers/EventHandler.h" #include "ThePEG/Handlers/SamplerBase.h" #include "Herwig/MatrixElement/Matchbox/Base/DipoleRepository.h" #include "Herwig/MatrixElement/Matchbox/Utility/SU2Helper.h" #include "Herwig/API/RunDirectories.h" #include "Herwig/Utilities/Progress.h" #include using std::ostream_iterator; using namespace Herwig; using std::ostream_iterator; MatchboxFactory::MatchboxFactory() : SubProcessHandler(), theNLight(0), theOrderInAlphaS(0), theOrderInAlphaEW(0), theBornContributions(true), theVirtualContributions(true), theRealContributions(true), theIndependentVirtuals(false), theIndependentPKs(false), theFactorizationScaleFactor(1.0), theRenormalizationScaleFactor(1.0), theFixedCouplings(false), theFixedQEDCouplings(false), theVetoScales(false), theDipoleSet(0), theVerbose(false), theInitVerbose(false), theSubtractionData(""), theSubtractionPlotType(1), theSubtractionScatterPlot(false), thePoleData(""), theRealEmissionScales(false), theAllProcesses(false), theMECorrectionsOnly(false), theLoopSimCorrections(false), ranSetup(false), theFirstPerturbativePDF(true), theSecondPerturbativePDF(true), inProductionMode(false), theSpinCorrelations(false),theAlphaParameter(1.), theEnforceChargeConservation(true), theEnforceColourConservation(false), theEnforceLeptonNumberConservation(false), theEnforceQuarkNumberConservation(false), theLeptonFlavourDiagonal(false), theQuarkFlavourDiagonal(false) {} -MatchboxFactory::~MatchboxFactory() {} - Ptr::tptr MatchboxFactory::theCurrentFactory = Ptr::tptr(); bool& MatchboxFactory::theIsMatchboxRun() { static bool flag = false; return flag; } IBPtr MatchboxFactory::clone() const { return new_ptr(*this); } IBPtr MatchboxFactory::fullclone() const { return new_ptr(*this); } void MatchboxFactory::prepareME(Ptr::ptr me) { Ptr::ptr amp = dynamic_ptr_cast::ptr>((*me).amplitude()); me->matchboxAmplitude(amp); if ( phasespace() && !me->phasespace() ) me->phasespace(phasespace()); if ( scaleChoice() && !me->scaleChoice() ) me->scaleChoice(scaleChoice()); if ( !reweighters().empty() ) { for ( vector::const_iterator rw = reweighters().begin(); rw != reweighters().end(); ++rw ) me->addReweighter(*rw); } if ( !preweighters().empty() ) { for ( vector::const_iterator rw = preweighters().begin(); rw != preweighters().end(); ++rw ) me->addPreweighter(*rw); } } string pid(const PDVector& key) { ostringstream res; res << "[" << key[0]->PDGName() << "," << key[1]->PDGName() << "->"; for ( PDVector::const_iterator k = key.begin() + 2; k != key.end(); ++k ) res << (**k).PDGName() << (k != --key.end() ? "," : ""); res << "]"; return res.str(); } vector::ptr> MatchboxFactory:: makeMEs(const vector& proc, unsigned int orderas, bool virt) { generator()->log() << "determining subprocesses for "; copy(proc.begin(),proc.end(),ostream_iterator(generator()->log()," ")); generator()->log() << "\n" << flush; map::ptr,set > ampProcs; map::ptr> > procAmps; set processes = makeSubProcesses(proc); set colouredProcesses; for ( set::const_iterator pr = processes.begin(); pr != processes.end(); ++pr ) { for ( PDVector::const_iterator pp = pr->begin(); pp != pr->end(); ++pp ) { if ( (**pp).coloured() ) { colouredProcesses.insert(*pr); break; } } } if ( colouredProcesses.size() != processes.size() && (virtualContributions() || realContributions()) ) { // NLO not working for non coloured legs throw Exception() << "Found processes without coloured legs.\n" << "We currently do not support NLO corrections for those processes.\n" << "Please switch to a setup for LO production." << Exception::runerror; } // detect external particles with non-zero width for the hard process bool trouble = false; string troubleMaker; for ( set::const_iterator pr = processes.begin(); pr != processes.end(); ++pr ) { for ( PDVector::const_iterator pp = pr->begin(); pp != pr->end(); ++pp ) { if ( (**pp).hardProcessWidth() != ZERO ) { trouble = true; troubleMaker = (**pp).PDGName(); break; } } } if ( trouble ) { throw Exception() << "MatchboxFactory::makeMEs(): Particle '" << troubleMaker << "' appears as external\nprocess leg with non-zero " << "width to be used in the hard process calculation.\n" << "Please check your setup and consider setting HardProcessWidth to zero." << Exception::runerror; } vector::ptr> matchAmplitudes; unsigned int lowestAsOrder = allProcesses() ? 0 : orderas; unsigned int highestAsOrder = orderas; unsigned int lowestAeOrder = allProcesses() ? 0 : orderInAlphaEW(); unsigned int highestAeOrder = orderInAlphaEW(); for ( unsigned int oas = lowestAsOrder; oas <= highestAsOrder; ++oas ) { for ( unsigned int oae = lowestAeOrder; oae <= highestAeOrder; ++oae ) { for ( vector::ptr>::const_iterator amp = amplitudes().begin(); amp != amplitudes().end(); ++amp ) { if ( !theSelectedAmplitudes.empty() ) { if ( find(theSelectedAmplitudes.begin(),theSelectedAmplitudes.end(),*amp) == theSelectedAmplitudes.end() ) continue; } if ( !theDeselectedAmplitudes.empty() ) { if ( find(theDeselectedAmplitudes.begin(),theDeselectedAmplitudes.end(),*amp) != theDeselectedAmplitudes.end() ) continue; } (**amp).orderInGs(oas); (**amp).orderInGem(oae); if ( (**amp).orderInGs() != oas || (**amp).orderInGem() != oae ) { continue; } matchAmplitudes.push_back(*amp); } } } size_t combinations = processes.size()*matchAmplitudes.size(); size_t procCount = 0; generator()->log() << "building matrix elements." << flush; progress_display progressBar{ combinations, generator()->log() }; for ( unsigned int oas = lowestAsOrder; oas <= highestAsOrder; ++oas ) { for ( unsigned int oae = lowestAeOrder; oae <= highestAeOrder; ++oae ) { for ( vector::ptr>::const_iterator amp = matchAmplitudes.begin(); amp != matchAmplitudes.end(); ++amp ) { (**amp).orderInGs(oas); (**amp).orderInGem(oae); for ( set::const_iterator p = processes.begin(); p != processes.end(); ++p ) { ++progressBar; if ( !(**amp).canHandle(*p,this,virt) ) continue; if ( (**amp).isExternal() ) externalAmplitudes().insert(*amp); ++procCount; Process proc(*p,oas,oae); ampProcs[*amp].insert(proc); procAmps[proc].insert(*amp); } } } } generator()->log() << flush; bool clash = false; for ( map::ptr> >::const_iterator check = procAmps.begin(); check != procAmps.end(); ++check ) { if ( check->second.size() > 1 ) { clash = true; generator()->log() << "Several different amplitudes have been found for: " << check->first.legs[0]->PDGName() << " " << check->first.legs[1]->PDGName() << " -> "; for ( PDVector::const_iterator p = check->first.legs.begin() + 2; p != check->first.legs.end(); ++p ) generator()->log() << (**p).PDGName() << " "; generator()->log() << "at alpha_s^" << check->first.orderInAlphaS << " and alpha_ew^" << check->first.orderInAlphaEW << "\n"; generator()->log() << "The following amplitudes claim responsibility:\n"; for ( set::ptr>::const_iterator a = check->second.begin(); a != check->second.end(); ++a ) { generator()->log() << (**a).name() << " "; } generator()->log() << "\n"; } } if ( clash ) { throw Exception() << "MatchboxFactory: Ambiguous amplitude setup - please check your input files.\n" << "To avoid this problem use the SelectAmplitudes or DeselectAmplitudes interfaces.\n" << Exception::runerror; } bool canDoSpinCorrelations = true; vector::ptr> res; for ( map::ptr,set >::const_iterator ap = ampProcs.begin(); ap != ampProcs.end(); ++ap ) { canDoSpinCorrelations &= ap->first->canFillRhoMatrix(); for ( set::const_iterator m = ap->second.begin(); m != ap->second.end(); ++m ) { Ptr::ptr me = ap->first->makeME(m->legs); me->subProcess() = *m; me->amplitude(ap->first); me->matchboxAmplitude(ap->first); prepareME(me); string pname = "ME" + pid(m->legs); if ( ! (generator()->preinitRegister(me,pname) ) ) throw Exception() << "MatchboxFactory: Matrix element " << pname << " already existing." << Exception::runerror; if ( me->diagrams().empty() )continue; res.push_back(me); if ( theFirstPerturbativePDF ) theIncoming.insert(m->legs[0]->id()); if ( theSecondPerturbativePDF ) theIncoming.insert(m->legs[1]->id()); } } if ( spinCorrelations() && !canDoSpinCorrelations ) { generator()->log() << "Warning: Spin correlations have been requested, but no amplitude is " << "capable of performing these.\n"; theSpinCorrelations = false; } generator()->log() << "created " << procCount << " subprocesses.\n"; generator()->log() << "---------------------------------------------------\n" << flush; return res; } int MatchboxFactory::orderOLPProcess(const Process& proc, Ptr::tptr amp, int type) { map,int>& procs = olpProcesses()[amp]; map,int>::const_iterator it = procs.find(make_pair(proc,type)); if ( it != procs.end() ) return it->second; int id = procs.size(); procs[make_pair(proc,type)] = id + 1; return id + 1; } void MatchboxFactory::productionMode() { if ( inProductionMode ) return; if ( !bornContributions() && !virtualContributions() && !realContributions() ) throw Exception() << "MatchboxFactory: At least one cross section contribution needs to be enabled.\n" << "Please check your setup.\n" << Exception::runerror; bool needTrueVirtuals = virtualContributions() && !meCorrectionsOnly() && !loopSimCorrections(); for ( vector::ptr>::iterator amp = amplitudes().begin(); amp != amplitudes().end(); ++amp ) { if ( !needTrueVirtuals && (**amp).oneLoopAmplitude() ) { Repository::clog() << "One-loop contributions from '" << (**amp).name() << "' are not required and will be disabled.\n" << flush; (**amp).disableOneLoop(); } } if ( subtractionData() != "" && !subProcessGroups() ) { throw Exception() << "MatchboxFactory: Plain NLO settings are required for subtraction checks.\n" << "Please check your setup.\n" << Exception::runerror; } if ( showerApproximation() && !virtualContributions() && !realContributions() ) { Repository::clog() << "Warning: Matching requested for LO run. Matching disabled.\n" << flush; showerApproximation(Ptr::tptr()); } if ( showerApproximation() && (subtractionData() != "" || subProcessGroups()) ) { Repository::clog() << "Warning: Matching requested for plain NLO run. Matching disabled.\n" << flush; showerApproximation(Ptr::tptr()); } if ( showerApproximation() ) { if ( spinCorrelations() && !showerApproximation()->hasSpinCorrelations() ) { Repository::clog() << "Warning: Spin correlations have been requested but the matching " << "object is not capable of these. Spin correlations will be turned of.\n" << flush; theSpinCorrelations = false; } } inProductionMode = true; } void MatchboxFactory::setup() { useMe(); if ( !ranSetup ) { if ( !inProductionMode ) throw Exception() << "MatchboxFactory: The MatchboxFactory object '" << name() << "' has not been switched to production mode.\n" << "Did you use 'do " << name() << ":ProductionMode' before isolating the event generator?\n" << Exception::runerror; olpProcesses().clear(); externalAmplitudes().clear(); theHighestVirtualsize = 0; theIncoming.clear(); bool needTrueVirtuals = virtualContributions() && !meCorrectionsOnly() && !loopSimCorrections(); if ( bornMEs().empty() ) { if ( particleGroups().find("j") == particleGroups().end() ) throw Exception() << "MatchboxFactory: Could not find a jet particle group named 'j'" << Exception::runerror; // rebind the particle data objects for ( map::iterator g = particleGroups().begin(); g != particleGroups().end(); ++g ) for ( PDVector::iterator p = g->second.begin(); p != g->second.end(); ++p ) { #ifndef NDEBUG long checkid = (**p).id(); #endif *p = getParticleData((**p).id()); assert((**p).id() == checkid); } const PDVector& partons = particleGroups()["j"]; unsigned int nl = 0; for ( PDVector::const_iterator p = partons.begin(); p != partons.end(); ++p ) { if ( abs((**p).id()) < 7 && (**p).hardProcessMass() == ZERO ) ++nl; if ( (**p).id() > 0 && (**p).id() < 7 && (**p).hardProcessMass() == ZERO ) nLightJetVec( (**p).id() ); if ( (**p).id() > 0 && (**p).id() < 7 && (**p).hardProcessMass() != ZERO ) nHeavyJetVec( (**p).id() ); } nLight(nl/2); if ( particleGroups().find("p") == particleGroups().end() ) throw Exception() << "MatchboxFactory: Could not find a hadron particle group named 'p'" << Exception::runerror; const PDVector& partonsInP = particleGroups()["p"]; for ( PDVector::const_iterator pip = partonsInP.begin(); pip != partonsInP.end(); ++pip ) { if ( (**pip).id() > 0 && (**pip).id() < 7 && (**pip).hardProcessMass() == ZERO ) nLightProtonVec( (**pip).id() ); } vector::ptr> mes; for ( vector >::const_iterator p = processes.begin(); p != processes.end(); ++p ) { if( needTrueVirtuals ) { theHighestVirtualsize = max(theHighestVirtualsize,(int((*p).size()))); } mes = makeMEs(*p,orderInAlphaS(),needTrueVirtuals); copy(mes.begin(),mes.end(),back_inserter(bornMEs())); if ( realContributions() || meCorrectionsOnly() || (showerApproximation() && virtualContributions()) || (showerApproximation() && loopSimCorrections()) ) { if ( realEmissionProcesses.empty() ) { vector rproc = *p; rproc.push_back("j"); mes = makeMEs(rproc,orderInAlphaS()+1,false); copy(mes.begin(),mes.end(),back_inserter(realEmissionMEs())); } } } if ( realContributions() || meCorrectionsOnly() || (showerApproximation() && virtualContributions()) || (showerApproximation() && loopSimCorrections()) ) { if ( !realEmissionProcesses.empty() ) { for ( vector >::const_iterator q = realEmissionProcesses.begin(); q != realEmissionProcesses.end(); ++q ) { mes = makeMEs(*q,orderInAlphaS()+1,false); copy(mes.begin(),mes.end(),back_inserter(realEmissionMEs())); } } } } if ( loopInducedMEs().empty() ) { for ( vector >::const_iterator p = loopInducedProcesses.begin(); p != loopInducedProcesses.end(); ++p ) { vector::ptr> mes = makeMEs(*p,orderInAlphaS(),false); copy(mes.begin(),mes.end(),back_inserter(loopInducedMEs())); } } if( bornMEs().empty() && realEmissionMEs().empty() && loopInducedMEs().empty() ) throw Exception() << "MatchboxFactory: No matrix elements have been found.\n\ Please check if your order of Alpha_s and Alpha_ew have the right value.\n" << Exception::runerror; // check if we have virtual contributions bool haveVirtuals = true; // check DR conventions of virtual contributions bool virtualsAreDR = false; bool virtualsAreCDR = false; // check finite term conventions of virtual contributions bool virtualsAreCS = false; bool virtualsAreBDK = false; bool virtualsAreExpanded = false; // renormalization scheme bool virtualsAreDRbar = false; // check and prepare the Born and virtual matrix elements for ( vector::ptr>::iterator born = bornMEs().begin(); born != bornMEs().end(); ++born ) { prepareME(*born); haveVirtuals &= (**born).haveOneLoop(); if ( needTrueVirtuals ) { if ( (**born).haveOneLoop() ) { virtualsAreDRbar |= (**born).isDRbar(); virtualsAreDR |= (**born).isDR(); virtualsAreCDR |= !(**born).isDR(); virtualsAreCS |= (**born).isCS(); virtualsAreBDK |= (**born).isBDK(); virtualsAreExpanded |= (**born).isExpanded(); } } } // prepare the loop induced matrix elements for ( vector::ptr>::iterator looped = loopInducedMEs().begin(); looped != loopInducedMEs().end(); ++looped ) { prepareME(*looped); } if ( needTrueVirtuals ) { // check the additional insertion operators if ( !virtuals().empty() ) haveVirtuals = true; for ( vector::ptr>::const_iterator virt = virtuals().begin(); virt != virtuals().end(); ++virt ) { virtualsAreDRbar |= (**virt).isDRbar(); virtualsAreDR |= (**virt).isDR(); virtualsAreCDR |= !(**virt).isDR(); virtualsAreCS |= (**virt).isCS(); virtualsAreBDK |= (**virt).isBDK(); virtualsAreExpanded |= (**virt).isExpanded(); } // check for consistent conventions on virtuals, if we are to include them if ( virtualContributions() ) { if ( !haveVirtuals ) { throw Exception() << "MatchboxFactory: Could not find amplitudes for all virtual contributions needed.\n" << Exception::runerror; } if ( virtualsAreDR && virtualsAreCDR ) { throw Exception() << "MatchboxFactory: Virtual corrections use inconsistent regularization schemes.\n" << Exception::runerror; } if ( (virtualsAreCS && virtualsAreBDK) || (virtualsAreCS && virtualsAreExpanded) || (virtualsAreBDK && virtualsAreExpanded) || (!virtualsAreCS && !virtualsAreBDK && !virtualsAreExpanded) ) { throw Exception() << "MatchboxFactory: Virtual corrections use inconsistent conventions on finite terms.\n" << Exception::runerror; } } } // prepare the real emission matrix elements if ( realContributions() || meCorrectionsOnly() || (showerApproximation() && virtualContributions()) || (showerApproximation() && loopSimCorrections()) ) { for ( vector::ptr>::iterator real = realEmissionMEs().begin(); real != realEmissionMEs().end(); ++real ) { prepareME(*real); } } // start creating matrix elements MEs().clear(); // setup born and virtual contributions if ( bornContributions() || virtualContributions() ) { generator()->log() << "preparing Born" << (virtualContributions() ? " and virtual" : "") << " matrix elements.\n" << flush; } if ( (bornContributions() && !virtualContributions()) || (bornContributions() && meCorrectionsOnly()) || (bornContributions() && virtualContributions() && independentVirtuals()) ) { for ( vector::ptr>::iterator born = bornMEs().begin(); born != bornMEs().end(); ++born ) { if ( (**born).onlyOneLoop() ) continue; Ptr::ptr bornme = (**born).cloneMe(); string pname = fullName() + "/" + (**born).name(); if ( virtualContributions() && independentVirtuals() ) pname += ".Born"; if ( ! (generator()->preinitRegister(bornme,pname) ) ) throw Exception() << "MatchboxFactory: Matrix element " << pname << " already existing." << Exception::runerror; if ( bornme->isOLPTree() ) { int id = orderOLPProcess(bornme->subProcess(), (**born).matchboxAmplitude(), ProcessType::treeME2); bornme->olpProcess(ProcessType::treeME2,id); } bornme->needsNoCorrelations(); bornme->cloneDependencies(); MEs().push_back(bornme); } } if ( bornContributions() && !loopInducedMEs().empty() ) { for ( vector::ptr>::iterator looped = loopInducedMEs().begin(); looped != loopInducedMEs().end(); ++looped ) { Ptr::ptr loopme = (**looped).cloneMe(); string pname = fullName() + "/" + (**looped).name() + ".LoopInduced"; if ( ! (generator()->preinitRegister(loopme,pname) ) ) throw Exception() << "MatchboxFactory: Matrix element " << pname << " already existing." << Exception::runerror; if ( loopme->isOLPTree() ) { int id = orderOLPProcess(loopme->subProcess(), (**looped).matchboxAmplitude(), ProcessType::loopInducedME2); loopme->olpProcess(ProcessType::loopInducedME2,id); } loopme->needsNoCorrelations(); loopme->cloneDependencies(); MEs().push_back(loopme); } } if ( needTrueVirtuals ) { bornVirtualMEs().clear(); progress_display progressBar{ bornMEs().size(), generator()->log() }; if ( thePoleData != "" ) if ( thePoleData[thePoleData.size()-1] != '/' ) thePoleData += "/"; for ( vector::ptr>::iterator born = bornMEs().begin(); born != bornMEs().end(); ++born ) { Ptr::ptr nlo = (**born).cloneMe(); string pname = fullName() + "/" + (**born).name(); if ( !independentVirtuals() && !(!bornContributions() && virtualContributions()) ) pname += ".BornVirtual"; else if ( independentPKs() && !nlo->onlyOneLoop() ) pname += ".VirtualVI"; else pname += ".Virtual"; if ( ! (generator()->preinitRegister(nlo,pname) ) ) throw Exception() << "MatchboxFactory: NLO ME " << pname << " already existing." << Exception::runerror; nlo->virtuals().clear(); if ( !nlo->onlyOneLoop() ) { for ( vector::ptr>::const_iterator virt = virtuals().begin(); virt != virtuals().end(); ++virt ) { if ( (**virt).apply((**born).diagrams().front()->partons()) ) nlo->virtuals().push_back(*virt); } for ( vector::ptr>::const_iterator virt = DipoleRepository::insertionIOperators(dipoleSet()).begin(); virt != DipoleRepository::insertionIOperators(dipoleSet()).end(); ++virt ) { if ( (**virt).apply((**born).diagrams().front()->partons()) ) nlo->virtuals().push_back(*virt); } if ( !independentVirtuals() || ( independentVirtuals() && !independentPKs() ) ) { for ( vector::ptr>::const_iterator virt = DipoleRepository::insertionPKOperators(dipoleSet()).begin(); virt != DipoleRepository::insertionPKOperators(dipoleSet()).end(); ++virt ) { if ( (**virt).apply((**born).diagrams().front()->partons()) ) nlo->virtuals().push_back(*virt); } } if ( nlo->virtuals().empty() ) throw Exception() << "MatchboxFactory: No insertion operators have been found for " << (**born).name() << "\n" << Exception::runerror; if ( checkPoles() ) { if ( !virtualsAreExpanded ) { throw Exception() << "MatchboxFactory: Cannot check epsilon poles if virtuals are not in `expanded' convention.\n" << Exception::runerror; } } } if ( !bornContributions() || independentVirtuals() ) { nlo->doOneLoopNoBorn(); } else { nlo->doOneLoop(); } if ( nlo->isOLPLoop() ) { int id = orderOLPProcess(nlo->subProcess(), (**born).matchboxAmplitude(), ProcessType::oneLoopInterference); nlo->olpProcess(ProcessType::oneLoopInterference,id); if ( !nlo->onlyOneLoop() && nlo->needsOLPCorrelators() ) { id = orderOLPProcess(nlo->subProcess(), (**born).matchboxAmplitude(), ProcessType::colourCorrelatedME2); nlo->olpProcess(ProcessType::colourCorrelatedME2,id); } } nlo->needsCorrelations(); nlo->cloneDependencies(); bornVirtualMEs().push_back(nlo); MEs().push_back(nlo); if ( independentVirtuals() && independentPKs() && !nlo->onlyOneLoop() ) { Ptr::ptr nlopk = (**born).cloneMe(); string pnamepk = fullName() + "/" + (**born).name(); pnamepk += ".VirtualPK"; if ( ! (generator()->preinitRegister(nlopk,pnamepk) ) ) throw Exception() << "MatchboxFactory: NLO ME " << pnamepk << " already existing." << Exception::runerror; nlopk->virtuals().clear(); for ( vector::ptr>::const_iterator virt = DipoleRepository::insertionPKOperators(dipoleSet()).begin(); virt != DipoleRepository::insertionPKOperators(dipoleSet()).end(); ++virt ) { if ( (**virt).apply((**born).diagrams().front()->partons()) ) nlopk->virtuals().push_back(*virt); } if ( !nlopk->virtuals().empty() ) { nlopk->doOneLoopNoBorn(); nlopk->doOneLoopNoLoops(); if ( nlopk->isOLPLoop() ) { int id = orderOLPProcess(nlopk->subProcess(), (**born).matchboxAmplitude(), ProcessType::treeME2); nlopk->olpProcess(ProcessType::treeME2,id); if ( nlopk->needsOLPCorrelators() ) { id = orderOLPProcess(nlopk->subProcess(), (**born).matchboxAmplitude(), ProcessType::colourCorrelatedME2); nlopk->olpProcess(ProcessType::colourCorrelatedME2,id); } } nlopk->needsCorrelations(); nlopk->cloneDependencies(); bornVirtualMEs().push_back(nlopk); MEs().push_back(nlopk); } } ++progressBar; } generator()->log() << "---------------------------------------------------\n" << flush; } theSplittingDipoles.clear(); set bornProcs; if ( showerApproximation() ) { if ( showerApproximation()->needsSplittingGenerator() ) { for ( vector::ptr>::iterator born = bornMEs().begin(); born != bornMEs().end(); ++born ) for ( MEBase::DiagramVector::const_iterator d = (**born).diagrams().begin(); d != (**born).diagrams().end(); ++d ) bornProcs.insert((**d).partons()); } } if ( realContributions() || meCorrectionsOnly() || (showerApproximation() && virtualContributions()) || (showerApproximation() && loopSimCorrections()) ) { generator()->log() << "preparing subtracted matrix elements.\n" << flush; if ( theSubtractionData != "" ) if ( theSubtractionData[theSubtractionData.size()-1] != '/' ) theSubtractionData += "/"; subtractedMEs().clear(); for ( vector::ptr>::iterator born = bornMEs().begin(); born != bornMEs().end(); ++born ) { if ( (**born).onlyOneLoop() ) continue; (**born).needsCorrelations(); if ( (**born).isOLPTree() ) { int id = orderOLPProcess((**born).subProcess(), (**born).matchboxAmplitude(), ProcessType::colourCorrelatedME2); (**born).olpProcess(ProcessType::colourCorrelatedME2,id); bool haveGluon = false; for ( PDVector::const_iterator p = (**born).subProcess().legs.begin(); p != (**born).subProcess().legs.end(); ++p ) if ( (**p).id() == 21 ) { haveGluon = true; break; } if ( haveGluon ) { id = orderOLPProcess((**born).subProcess(), (**born).matchboxAmplitude(), ProcessType::spinColourCorrelatedME2); (**born).olpProcess(ProcessType::spinColourCorrelatedME2,id); } if ( showerApproximation() ) { id = orderOLPProcess((**born).subProcess(), (**born).matchboxAmplitude(), ProcessType::treeME2); (**born).olpProcess(ProcessType::treeME2,id); } } } progress_display progressBar{ realEmissionMEs().size(), generator()->log() }; for ( vector::ptr>::iterator real = realEmissionMEs().begin(); real != realEmissionMEs().end(); ++real ) { Ptr::ptr sub = new_ptr(SubtractedME()); string pname = fullName() + "/" + (**real).name() + ".SubtractedReal"; if ( ! (generator()->preinitRegister(sub,pname) ) ) throw Exception() << "MatchboxFactory: Subtracted ME " << pname << " already existing." << Exception::runerror; (**real).needsNoCorrelations(); if ( (**real).isOLPTree() ) { int id = orderOLPProcess((**real).subProcess(), (**real).matchboxAmplitude(), ProcessType::treeME2); (**real).olpProcess(ProcessType::treeME2,id); } sub->head(*real); sub->dependent().clear(); sub->getDipoles(); if ( sub->dependent().empty() ) { // finite real contribution if ( realContributions() ) { Ptr::ptr fme = dynamic_ptr_cast::ptr>(sub->head())->cloneMe(); string qname = fullName() + "/" + (**real).name() + ".FiniteReal"; if ( ! (generator()->preinitRegister(fme,qname) ) ) throw Exception() << "MatchboxFactory: ME " << qname << " already existing." << Exception::runerror; MEs().push_back(fme); finiteRealMEs().push_back(fme); } sub->head(tMEPtr()); ++progressBar; continue; } if ( realEmissionScales() ) sub->doRealEmissionScales(); subtractedMEs().push_back(sub); if ( realContributions() ) if ( !showerApproximation() || (showerApproximation() && showerApproximation()->hasHEvents()) ) MEs().push_back(sub); if ( showerApproximation() ) { if ( virtualContributions() && !meCorrectionsOnly() && !loopSimCorrections() ) { Ptr::ptr subv = new_ptr(*sub); string vname = sub->fullName() + ".SubtractionIntegral"; if ( ! (generator()->preinitRegister(subv,vname) ) ) throw Exception() << "MatchboxFactory: Subtracted ME " << vname << " already existing." << Exception::runerror; subv->cloneDependencies(vname); subv->doVirtualShowerSubtraction(); subtractedMEs().push_back(subv); MEs().push_back(subv); } if ( loopSimCorrections() ) { Ptr::ptr subv = new_ptr(*sub); string vname = sub->fullName() + ".SubtractionIntegral"; if ( ! (generator()->preinitRegister(subv,vname) ) ) throw Exception() << "MatchboxFactory: Subtracted ME " << vname << " already existing." << Exception::runerror; subv->cloneDependencies(vname); subv->doLoopSimSubtraction(); subtractedMEs().push_back(subv); MEs().push_back(subv); } sub->doRealShowerSubtraction(); if ( showerApproximation()->needsSplittingGenerator() ) for ( set::const_iterator p = bornProcs.begin(); p != bornProcs.end(); ++p ) { vector::ptr> sdip = sub->splitDipoles(*p); set::ptr>& dips = theSplittingDipoles[*p]; copy(sdip.begin(),sdip.end(),inserter(dips,dips.begin())); } } ++progressBar; } generator()->log() << "---------------------------------------------------\n" << flush; } if ( !theSplittingDipoles.empty() ) { map::ptr,Ptr::ptr> cloneMap; for ( map::ptr> >::const_iterator sd = theSplittingDipoles.begin(); sd != theSplittingDipoles.end(); ++sd ) { for ( set::ptr>::const_iterator d = sd->second.begin(); d != sd->second.end(); ++d ) { cloneMap[*d] = Ptr::ptr(); } } for ( map::ptr,Ptr::ptr>::iterator cd = cloneMap.begin(); cd != cloneMap.end(); ++cd ) { Ptr::ptr cloned = cd->first->cloneMe(); string dname = cd->first->fullName() + ".splitting"; if ( ! (generator()->preinitRegister(cloned,dname)) ) throw Exception() << "MatchboxFactory: Dipole '" << dname << "' already existing." << Exception::runerror; cloned->cloneDependencies(); cloned->showerApproximation(Ptr::tptr()); cloned->doSplitting(); cd->second = cloned; } for ( map::ptr> >::iterator sd = theSplittingDipoles.begin(); sd != theSplittingDipoles.end(); ++sd ) { set::ptr> cloned; for ( set::ptr>::iterator d = sd->second.begin(); d != sd->second.end(); ++d ) { cloned.insert(cloneMap[*d]); } sd->second = cloned; } } if ( !externalAmplitudes().empty() ) { generator()->log() << "Initializing external amplitudes.\n" << flush; for ( set::tptr>::const_iterator ext = externalAmplitudes().begin(); ext != externalAmplitudes().end(); ++ext ) { if ( !(**ext).initializeExternal() ) { throw Exception() << "Failed to initialize amplitude '" << (**ext).name() << "'\n" << Exception::runerror; } } generator()->log() << "---------------------------------------------------\n" << flush; } if ( !olpProcesses().empty() ) { generator()->log() << "Initializing one-loop provider(s).\n" << flush; map::tptr,map,int> > olps; for ( map::tptr,map,int> >::const_iterator oit = olpProcesses().begin(); oit != olpProcesses().end(); ++oit ) { olps[oit->first] = oit->second; } for ( map::tptr,map,int> >::const_iterator olpit = olps.begin(); olpit != olps.end(); ++olpit ) { if ( !olpit->first->startOLP(olpit->second) ) { throw Exception() << "MatchboxFactory: Failed to start OLP for amplitude '" << olpit->first->name() << "'\n" << Exception::runerror; } } generator()->log() << "---------------------------------------------------\n" << flush; } generator()->log() << "Process setup finished.\n" << flush; ranSetup = true; } } void MatchboxFactory::SplittingChannel::print(ostream& os) const { os << "--- SplittingChannel setup -----------------------------------------------------\n"; os << " Born process "; const StandardXComb& bxc = *bornXComb; os << bxc.mePartonData()[0]->PDGName() << " " << bxc.mePartonData()[1]->PDGName() << " -> "; for ( cPDVector::const_iterator p = bxc.mePartonData().begin() + 2; p != bxc.mePartonData().end(); ++p ) { os << (**p).PDGName() << " "; } os << "\n"; os << " to real emission process "; const StandardXComb& rxc = *realXComb; os << rxc.mePartonData()[0]->PDGName() << " " << rxc.mePartonData()[1]->PDGName() << " -> "; for ( cPDVector::const_iterator p = rxc.mePartonData().begin() + 2; p != rxc.mePartonData().end(); ++p ) { os << (**p).PDGName() << " "; } os << "\n"; os << " with dipole:\n"; dipole->print(os); os << "---------------------------------------------------\n"; os << flush; } list MatchboxFactory::getSplittingChannels(tStdXCombPtr xcptr) const { if ( xcptr->lastProjector() ) xcptr = xcptr->lastProjector(); const StandardXComb& xc = *xcptr; cPDVector proc = xc.mePartonData(); map::ptr> >::const_iterator splitEntries = splittingDipoles().find(proc); list res; if ( splitEntries == splittingDipoles().end() ) return res; const set::ptr>& splitDipoles = splitEntries->second; SplittingChannel channel; if ( !splitDipoles.empty() ) { Ptr::tptr bornME = const_ptr_cast::tptr>((**splitDipoles.begin()).underlyingBornME()); channel.bornXComb = bornME->makeXComb(xc.maxEnergy(),xc.particles(),xc.eventHandlerPtr(), const_ptr_cast(xc.subProcessHandler()), xc.pExtractor(),xc.CKKWHandler(), xc.partonBins(),xc.cuts(),xc.diagrams(),xc.mirror(), PartonPairVec()); } for ( set::ptr>::const_iterator sd = splitDipoles.begin(); sd != splitDipoles.end(); ++sd ) { channel.dipole = *sd; vector realXCombs = (**sd).makeRealXCombs(channel.bornXComb); for ( vector::const_iterator rxc = realXCombs.begin(); rxc != realXCombs.end(); ++rxc ) { channel.realXComb = *rxc; if ( showerApproximation()->needsTildeXCombs() ) { channel.tildeXCombs.clear(); assert(!channel.dipole->partnerDipoles().empty()); for ( vector::tptr>::const_iterator p = channel.dipole->partnerDipoles().begin(); p != channel.dipole->partnerDipoles().end(); ++p ) { StdXCombPtr txc = channel.dipole->makeBornXComb(channel.realXComb); if ( txc ) channel.tildeXCombs.push_back(txc); } } res.push_back(channel); } } if ( initVerbose() ) { generator()->log() << "--- MatchboxFactory splitting channels ----------------------------------------------\n"; const StandardXComb& bxc = *xcptr; generator()->log() << " hard process handled is: "; generator()->log() << bxc.mePartonData()[0]->PDGName() << " " << bxc.mePartonData()[1]->PDGName() << " -> "; for ( cPDVector::const_iterator p = bxc.mePartonData().begin() + 2; p != bxc.mePartonData().end(); ++p ) { generator()->log() << (**p).PDGName() << " "; } generator()->log() << "\n"; for ( list::const_iterator sp = res.begin(); sp != res.end(); ++sp ) { sp->print(generator()->log()); } generator()->log() << "--------------------------------------------------------\n" << flush; } return res; } void MatchboxFactory::print(ostream& os) const { os << "--- MatchboxFactory setup -----------------------------------------------------------\n"; if ( !amplitudes().empty() ) { os << " generated Born matrix elements:\n"; for ( vector::ptr>::const_iterator m = bornMEs().begin(); m != bornMEs().end(); ++m ) { (**m).print(os); } os << flush; os << " generated real emission matrix elements:\n"; for ( vector::ptr>::const_iterator m = realEmissionMEs().begin(); m != realEmissionMEs().end(); ++m ) { (**m).print(os); } os << flush; } os << " generated Born+virtual matrix elements:\n"; for ( vector::ptr>::const_iterator bv = bornVirtualMEs().begin(); bv != bornVirtualMEs().end(); ++bv ) { (**bv).print(os); } os << " generated subtracted matrix elements:\n"; for ( vector::ptr>::const_iterator sub = subtractedMEs().begin(); sub != subtractedMEs().end(); ++sub ) { os << " '" << (**sub).name() << "'\n"; } os << "---------------------------------------------------\n"; os << flush; } void MatchboxFactory::summary(ostream& os) const { os << "\n\n================================================================================\n" << " Matchbox hard process summary\n" << "================================================================================\n\n"; os << " Electro-weak parameter summary:\n" << "---------------------------------------------------\n\n"; os << " Electro-weak scheme : "; switch ( SM().ewScheme() ) { case 0: os << "Default"; break; case 1: os << "GMuScheme"; break; case 2: os << "alphaMZScheme"; break; case 3: os << "NoMass"; break; case 4: os << "mW"; break; case 5: os << "mZ"; break; case 6: os << "Independent"; break; case 7: os << "FeynRulesUFO"; break; default: assert(false); } os << "\n"; os << " alphaEM is " << (SM().ewScheme() == 0 && !theFixedQEDCouplings ? "running" : "fixed at alphaEM(m(Z))") << "\n"; if ( SM().ewScheme() == 0 && !theFixedQEDCouplings ) os << " alphaEM is running at " << SM().alphaEMPtr()->nloops() << " loops\n\n"; else os << "\n"; os << (SM().ewScheme() != 0 ? " Tree level relations " : " Best values ") << "yield:\n\n" << " m(Z)/GeV = " << getParticleData(ParticleID::Z0)->hardProcessMass()/GeV << "\n" << " g(Z)/GeV = " << getParticleData(ParticleID::Z0)->hardProcessWidth()/GeV << "\n" << " m(W)/GeV = " << getParticleData(ParticleID::Wplus)->hardProcessMass()/GeV << "\n" << " g(W)/GeV = " << getParticleData(ParticleID::Wplus)->hardProcessWidth()/GeV << "\n" << " m(H)/GeV = " << getParticleData(ParticleID::h0)->hardProcessMass()/GeV << "\n" << " g(H)/GeV = " << getParticleData(ParticleID::h0)->hardProcessWidth()/GeV << "\n" << " alphaEM(m(Z)) = " << SM().alphaEMME(sqr(getParticleData(ParticleID::Z0)->hardProcessMass())) << "\n" << " sin^2(theta) = " << SM().sin2ThetaW() << "\n" << " GeV^2 GF = " << GeV2*SM().fermiConstant() << "\n\n"; os << " Quark masses and widths are:\n" << "---------------------------------------------------\n\n" << " m(u)/GeV = " << getParticleData(ParticleID::u)->hardProcessMass()/GeV << "\n" << " m(d)/GeV = " << getParticleData(ParticleID::d)->hardProcessMass()/GeV << "\n" << " m(c)/GeV = " << getParticleData(ParticleID::c)->hardProcessMass()/GeV << "\n" << " m(s)/GeV = " << getParticleData(ParticleID::s)->hardProcessMass()/GeV << "\n" << " m(t)/GeV = " << getParticleData(ParticleID::t)->hardProcessMass()/GeV << "\n" << " g(t)/GeV = " << getParticleData(ParticleID::t)->hardProcessWidth()/GeV << "\n" << " m(b)/GeV = " << getParticleData(ParticleID::b)->hardProcessMass()/GeV << "\n\n"; os << " Lepton masses and widths are:\n" << "---------------------------------------------------\n\n" << " m(n_e)/GeV = " << getParticleData(ParticleID::nu_e)->hardProcessMass()/GeV << "\n" << " m(e)/GeV = " << getParticleData(ParticleID::eminus)->hardProcessMass()/GeV << "\n" << " m(n_mu)/GeV = " << getParticleData(ParticleID::nu_mu)->hardProcessMass()/GeV << "\n" << " m(mu)/GeV = " << getParticleData(ParticleID::muminus)->hardProcessMass()/GeV << "\n" << " m(nu_tau)/GeV = " << getParticleData(ParticleID::nu_tau)->hardProcessMass()/GeV << "\n" << " m(tau)/GeV = " << getParticleData(ParticleID::tauminus)->hardProcessMass()/GeV << "\n\n"; os << " Strong coupling summary:\n" << "---------------------------------------------------\n\n"; os << " alphaS is"; if ( !theFixedCouplings ) { os << " running at " << SM().alphaSPtr()->nloops() << " loops with\n" << " alphaS(m(Z)) = " << SM().alphaSPtr()->value(sqr(getParticleData(ParticleID::Z0)->mass())) << "\n\n"; } else { os << " fixed at " << SM().alphaS() << "\n\n"; } if ( !theFixedCouplings ) { os << " flavour thresholds are matched at\n"; for ( long id = 1; id <= 6; ++id ) { os << " m(" << id << ")/GeV = " << (SM().alphaSPtr()->quarkMasses().empty() ? getParticleData(id)->mass()/GeV : SM().alphaSPtr()->quarkMasses()[id-1]/GeV) << "\n"; } } os << "\n\n" << flush; } void MatchboxFactory::doinit() { theIsMatchboxRun() = true; theCurrentFactory = Ptr::tptr(this); if ( RunDirectories::empty() ) RunDirectories::pushRunId(generator()->runName()); setup(); if ( theShowerApproximation ) theShowerApproximation->init(); if ( initVerbose() && !ranSetup ) print(Repository::clog()); Ptr::tptr eh = dynamic_ptr_cast::tptr>(generator()->eventHandler()); assert(eh); if ( initVerbose() && !ranSetup ) { assert(standardModel()); standardModel()->init(); summary(Repository::clog()); } SubProcessHandler::doinit(); } void MatchboxFactory::doinitrun() { theIsMatchboxRun() = true; theCurrentFactory = Ptr::tptr(this); if ( theShowerApproximation ) theShowerApproximation->initrun(); Ptr::tptr eh = dynamic_ptr_cast::tptr>(generator()->eventHandler()); assert(eh); SubProcessHandler::doinitrun(); } const string& MatchboxFactory::buildStorage() { return RunDirectories::buildStorage(); } const string& MatchboxFactory::runStorage() { return RunDirectories::runStorage(); } void MatchboxFactory::persistentOutput(PersistentOStream & os) const { os << theDiagramGenerator << theProcessData << theNLight << theNLightJetVec << theNHeavyJetVec << theNLightProtonVec << theOrderInAlphaS << theOrderInAlphaEW << theBornContributions << theVirtualContributions << theRealContributions << theIndependentVirtuals << theIndependentPKs << thePhasespace << theScaleChoice << theFactorizationScaleFactor << theRenormalizationScaleFactor << theFixedCouplings << theFixedQEDCouplings << theVetoScales << theAmplitudes << theBornMEs << theVirtuals << theRealEmissionMEs << theLoopInducedMEs << theBornVirtualMEs << theSubtractedMEs << theFiniteRealMEs << theVerbose << theInitVerbose << theSubtractionData << theSubtractionPlotType << theSubtractionScatterPlot << thePoleData << theParticleGroups << processes << loopInducedProcesses << realEmissionProcesses << theShowerApproximation << theSplittingDipoles << theRealEmissionScales << theAllProcesses << theOLPProcesses << theExternalAmplitudes << theSelectedAmplitudes << theDeselectedAmplitudes << theDipoleSet << theReweighters << thePreweighters << theMECorrectionsOnly<< theLoopSimCorrections<> theDiagramGenerator >> theProcessData >> theNLight >> theNLightJetVec >> theNHeavyJetVec >> theNLightProtonVec >> theOrderInAlphaS >> theOrderInAlphaEW >> theBornContributions >> theVirtualContributions >> theRealContributions >> theIndependentVirtuals >> theIndependentPKs >> thePhasespace >> theScaleChoice >> theFactorizationScaleFactor >> theRenormalizationScaleFactor >> theFixedCouplings >> theFixedQEDCouplings >> theVetoScales >> theAmplitudes >> theBornMEs >> theVirtuals >> theRealEmissionMEs >> theLoopInducedMEs >> theBornVirtualMEs >> theSubtractedMEs >> theFiniteRealMEs >> theVerbose >> theInitVerbose >> theSubtractionData >> theSubtractionPlotType >> theSubtractionScatterPlot >> thePoleData >> theParticleGroups >> processes >> loopInducedProcesses >> realEmissionProcesses >> theShowerApproximation >> theSplittingDipoles >> theRealEmissionScales >> theAllProcesses >> theOLPProcesses >> theExternalAmplitudes >> theSelectedAmplitudes >> theDeselectedAmplitudes >> theDipoleSet >> theReweighters >> thePreweighters >> theMECorrectionsOnly>> theLoopSimCorrections>>theHighestVirtualsize >> ranSetup >> theIncoming >> theFirstPerturbativePDF >> theSecondPerturbativePDF >> inProductionMode >> theSpinCorrelations >> theAlphaParameter >> theEnforceChargeConservation >> theEnforceColourConservation >> theEnforceLeptonNumberConservation >> theEnforceQuarkNumberConservation >> theLeptonFlavourDiagonal >> theQuarkFlavourDiagonal; } string MatchboxFactory::startParticleGroup(string name) { particleGroupName = StringUtils::stripws(name); particleGroup.clear(); return ""; } string MatchboxFactory::endParticleGroup(string) { if ( particleGroup.empty() ) throw Exception() << "MatchboxFactory: Empty particle group." << Exception::runerror; particleGroups()[particleGroupName] = particleGroup; particleGroup.clear(); return ""; } vector MatchboxFactory::parseProcess(string in) { vector process = StringUtils::split(in); if ( process.size() < 3 ) throw Exception() << "MatchboxFactory: Invalid process." << Exception::runerror; for ( vector::iterator p = process.begin(); p != process.end(); ++p ) { *p = StringUtils::stripws(*p); } vector pprocess; for ( vector::const_iterator p = process.begin(); p != process.end(); ++p ) { if ( *p == "->" ) continue; pprocess.push_back(*p); } return pprocess; } string MatchboxFactory::doProcess(string in) { processes.push_back(parseProcess(in)); return ""; } string MatchboxFactory::doLoopInducedProcess(string in) { loopInducedProcesses.push_back(parseProcess(in)); return ""; } string MatchboxFactory::doSingleRealProcess(string in) { realEmissionProcesses.push_back(parseProcess(in)); return ""; } struct SortPID { inline bool operator()(PDPtr a, PDPtr b) const { return a->id() < b->id(); } }; // // @TODO // // SP: After improving this for standard model process building this should // actually got into a separate process builder class or something along these // lines to have it better factored for use with BSM models. // // set MatchboxFactory:: makeSubProcesses(const vector& proc) const { if ( proc.empty() ) throw Exception() << "MatchboxFactory: No process specified." << Exception::runerror; vector groups; typedef map::const_iterator GroupIterator; for ( vector::const_iterator gr = proc.begin(); gr != proc.end(); ++gr ) { GroupIterator git = particleGroups().find(*gr); if ( git == particleGroups().end() ) { throw Exception() << "MatchboxFactory: Particle group '" << *gr << "' not defined." << Exception::runerror; } groups.push_back(git->second); } vector counts(groups.size(),0); PDVector proto(groups.size()); set allProcs; while ( true ) { for ( size_t k = 0; k < groups.size(); ++k ) proto[k] = groups[k][counts[k]]; int charge = 0; int colour = 0; int nleptons = 0; int nquarks = 0; int ncolour = 0; int nleptonsGen[4]; int nquarksGen[4]; for ( size_t i = 0; i < 4; ++i ) { nleptonsGen[i] = 0; nquarksGen[i] = 0; } for ( size_t k = 0; k < proto.size(); ++k ) { int sign = k > 1 ? 1 : -1; charge += sign * proto[k]->iCharge(); colour += sign * proto[k]->iColour(); if ( abs(proto[k]->id()) <= 8 ) { int generation = (abs(proto[k]->id()) - 1)/2; nquarks += sign * ( proto[k]->id() < 0 ? -1 : 1); nquarksGen[generation] += sign * ( proto[k]->id() < 0 ? -1 : 1); } if ( abs(proto[k]->id()) > 10 && abs(proto[k]->id()) <= 18 ) { int generation = (abs(proto[k]->id()) - 11)/2; nleptons += sign * ( proto[k]->id() < 0 ? -1 : 1); nleptonsGen[generation] += sign * ( proto[k]->id() < 0 ? -1 : 1); } if ( proto[k]->coloured() ) ++ncolour; } bool pass = true; if ( theEnforceChargeConservation ) pass &= (charge == 0); if ( theEnforceColourConservation ) pass &= (colour % 8 == 0); if ( theEnforceLeptonNumberConservation ) { pass &= (nleptons == 0); if ( theLeptonFlavourDiagonal ) { for ( size_t i = 0; i < 4; ++i ) pass &= (nleptonsGen[i] == 0); } } if ( theEnforceQuarkNumberConservation ) { pass &= (nquarks == 0); if ( theQuarkFlavourDiagonal ) { for ( size_t i = 0; i < 4; ++i ) pass &= (nquarksGen[i] == 0); } } if ( pass ) { for ( int i = 0; i < 2; ++i ) { if ( proto[i]->coloured() && proto[i]->hardProcessMass() != ZERO ) throw Exception() << "Inconsistent flavour scheme detected with massive incoming " << proto[i]->PDGName() << ". Check your setup." << Exception::runerror; } sort(proto.begin()+2,proto.end(),SortPID()); allProcs.insert(proto); } vector::reverse_iterator c = counts.rbegin(); vector::const_reverse_iterator g = groups.rbegin(); while ( c != counts.rend() ) { if ( ++(*c) == g->size() ) { *c = 0; ++c; ++g; } else { break; } } if ( c == counts.rend() ) break; } return allProcs; } void MatchboxFactory::Init() { static ClassDocumentation documentation ("MatchboxFactory", "NLO QCD corrections have been calculated " "using Matchbox \\cite{Platzer:2011bc}, \\cite{Matchbox:2015}", "%\\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;%%\n" "%\\cite{Matchbox:2015}\n" "\\bibitem{Matchbox:2015}\n" "Herwig collaboration,\n" "``Precision LHC Event Generation with Herwig,''\n" "in preparation."); static Reference interfaceDiagramGenerator ("DiagramGenerator", "Set the diagram generator.", &MatchboxFactory::theDiagramGenerator, false, false, true, true, false); interfaceDiagramGenerator.rank(-1); static Reference interfaceProcessData ("ProcessData", "Set the process data object to be used.", &MatchboxFactory::theProcessData, false, false, true, true, false); interfaceProcessData.rank(-1); static Parameter interfaceOrderInAlphaS ("OrderInAlphaS", "The order in alpha_s to consider.", &MatchboxFactory::theOrderInAlphaS, 0, 0, 0, false, false, Interface::lowerlim); static Parameter interfaceOrderInAlphaEW ("OrderInAlphaEW", "The order in alpha_EW to consider.", &MatchboxFactory::theOrderInAlphaEW, 2, 0, 0, false, false, Interface::lowerlim); static Switch interfaceBornContributions ("BornContributions", "Switch on or off the Born contributions.", &MatchboxFactory::theBornContributions, true, false, false); static SwitchOption interfaceBornContributionsYes (interfaceBornContributions, "Yes", "Switch on Born contributions.", true); static SwitchOption interfaceBornContributionsNo (interfaceBornContributions, "No", "Switch off Born contributions.", false); static Switch interfaceVirtualContributions ("VirtualContributions", "Switch on or off the virtual contributions.", &MatchboxFactory::theVirtualContributions, true, false, false); static SwitchOption interfaceVirtualContributionsYes (interfaceVirtualContributions, "Yes", "Switch on virtual contributions.", true); static SwitchOption interfaceVirtualContributionsNo (interfaceVirtualContributions, "No", "Switch off virtual contributions.", false); static Switch interfaceRealContributions ("RealContributions", "Switch on or off the real contributions.", &MatchboxFactory::theRealContributions, true, false, false); static SwitchOption interfaceRealContributionsYes (interfaceRealContributions, "Yes", "Switch on real contributions.", true); static SwitchOption interfaceRealContributionsNo (interfaceRealContributions, "No", "Switch off real contributions.", false); static Switch interfaceIndependentVirtuals ("IndependentVirtuals", "Switch on or off virtual contributions as separate subprocesses.", &MatchboxFactory::theIndependentVirtuals, true, false, false); static SwitchOption interfaceIndependentVirtualsYes (interfaceIndependentVirtuals, "Yes", "Switch on virtual contributions as separate subprocesses.", true); static SwitchOption interfaceIndependentVirtualsNo (interfaceIndependentVirtuals, "No", "Switch off virtual contributions as separate subprocesses.", false); static Switch interfaceIndependentPKs ("IndependentPKOperators", "Switch on or off PK oeprators as separate subprocesses.", &MatchboxFactory::theIndependentPKs, true, false, false); static SwitchOption interfaceIndependentPKsYes (interfaceIndependentPKs, "Yes", "Switch on PK operators as separate subprocesses.", true); static SwitchOption interfaceIndependentPKsNo (interfaceIndependentPKs, "No", "Switch off PK operators as separate subprocesses.", false); static Reference interfacePhasespace ("Phasespace", "Set the phasespace generator.", &MatchboxFactory::thePhasespace, false, false, true, true, false); static Reference interfaceScaleChoice ("ScaleChoice", "Set the scale choice object.", &MatchboxFactory::theScaleChoice, false, false, true, true, false); static Parameter interfaceFactorizationScaleFactor ("FactorizationScaleFactor", "The factorization scale factor.", &MatchboxFactory::theFactorizationScaleFactor, 1.0, 0.0, 0, false, false, Interface::lowerlim); static Parameter interfaceRenormalizationScaleFactor ("RenormalizationScaleFactor", "The renormalization scale factor.", &MatchboxFactory::theRenormalizationScaleFactor, 1.0, 0.0, 0, false, false, Interface::lowerlim); static Switch interfaceFixedCouplings ("FixedCouplings", "Switch on or off fixed couplings.", &MatchboxFactory::theFixedCouplings, true, false, false); static SwitchOption interfaceFixedCouplingsYes (interfaceFixedCouplings, "Yes", "Yes", true); static SwitchOption interfaceFixedCouplingsNo (interfaceFixedCouplings, "No", "No", false); interfaceFixedCouplings.rank(-1); static Switch interfaceFixedQEDCouplings ("FixedQEDCouplings", "Switch on or off fixed QED couplings.", &MatchboxFactory::theFixedQEDCouplings, true, false, false); static SwitchOption interfaceFixedQEDCouplingsYes (interfaceFixedQEDCouplings, "Yes", "Yes", true); static SwitchOption interfaceFixedQEDCouplingsNo (interfaceFixedQEDCouplings, "No", "No", false); interfaceFixedQEDCouplings.rank(-1); // @TDOO SP to remove this in the code as well /* static Switch interfaceVetoScales ("VetoScales", "Switch on or setting veto scales.", &MatchboxFactory::theVetoScales, false, false, false); static SwitchOption interfaceVetoScalesYes (interfaceVetoScales, "Yes", "Yes", true); static SwitchOption interfaceVetoScalesNo (interfaceVetoScales, "No", "No", false); */ static RefVector interfaceAmplitudes ("Amplitudes", "The amplitude objects.", &MatchboxFactory::theAmplitudes, -1, false, false, true, true, false); static Switch interfaceVerbose ("Verbose", "Print full infomation on each evaluated phase space point.", &MatchboxFactory::theVerbose, false, false, false); static SwitchOption interfaceVerboseYes (interfaceVerbose, "Yes", "Yes", true); static SwitchOption interfaceVerboseNo (interfaceVerbose, "No", "No", false); interfaceVerbose.rank(-1); static Switch interfaceInitVerbose ("InitVerbose", "Print setup information.", &MatchboxFactory::theInitVerbose, false, false, false); static SwitchOption interfaceInitVerboseYes (interfaceInitVerbose, "Yes", "Yes", true); static SwitchOption interfaceInitVerboseNo (interfaceInitVerbose, "No", "No", false); interfaceInitVerbose.rank(-1); static Parameter interfaceSubtractionData ("SubtractionData", "Prefix for subtraction check data.", &MatchboxFactory::theSubtractionData, "", false, false); static Switch interfaceSubtractionPlotType ("SubtractionPlotType", "Switch for controlling what kind of plot is generated for checking the subtraction", &MatchboxFactory::theSubtractionPlotType, 1, false, false); static SwitchOption interfaceSubtractionPlotTypeLinearRatio (interfaceSubtractionPlotType, "LinRatio", "Switch on the linear plot of the ratio", 1); static SwitchOption interfaceSubtractionPlotTypeLogRelDiff (interfaceSubtractionPlotType, "LogRelDiff", "Switch on the logarithmic plot of the relative difference", 2); static Switch interfaceSubtractionScatterPlot ("SubtractionScatterPlot", "Switch for controlling whether subtraction data should be plotted for each phase space point individually", &MatchboxFactory::theSubtractionScatterPlot, false, false, false); static SwitchOption interfaceSubtractionScatterPlotNo (interfaceSubtractionScatterPlot, "No", "Switch off the scatter plot", false); static SwitchOption interfaceSubtractionScatterPlotYes (interfaceSubtractionScatterPlot, "Yes", "Switch on the scatter plot", true); static Parameter interfacePoleData ("PoleData", "Prefix for subtraction check data.", &MatchboxFactory::thePoleData, "", false, false); static RefVector interfaceParticleGroup ("ParticleGroup", "The particle group just started.", &MatchboxFactory::particleGroup, -1, false, false, true, false, false); static Command interfaceStartParticleGroup ("StartParticleGroup", "Start a particle group.", &MatchboxFactory::startParticleGroup, false); static Command interfaceEndParticleGroup ("EndParticleGroup", "End a particle group.", &MatchboxFactory::endParticleGroup, false); static Command interfaceProcess ("Process", "Set the process(es) to consider.", &MatchboxFactory::doProcess, false); static Command interfaceLoopInducedProcess ("LoopInducedProcess", "Set the loop induced process(es) to consider.", &MatchboxFactory::doLoopInducedProcess, false); static Command interfaceSingleRealProcess ("SingleRealProcess", "Set the real emission process(es) to consider.", &MatchboxFactory::doSingleRealProcess, false); static Reference interfaceShowerApproximation ("ShowerApproximation", "Set the shower approximation to be considered.", &MatchboxFactory::theShowerApproximation, false, false, true, true, false); static Switch interfaceRealEmissionScales ("RealEmissionScales", "Switch on or off calculation of subtraction scales from real emission kinematics.", &MatchboxFactory::theRealEmissionScales, false, false, false); static SwitchOption interfaceRealEmissionScalesYes (interfaceRealEmissionScales, "Yes", "Yes", true); static SwitchOption interfaceRealEmissionScalesNo (interfaceRealEmissionScales, "No", "No", false); interfaceRealEmissionScales.rank(-1); static Switch interfaceAllProcesses ("AllProcesses", "Consider all processes up to a maximum coupling order specified by the coupling order interfaces.", &MatchboxFactory::theAllProcesses, false, false, false); static SwitchOption interfaceAllProcessesYes (interfaceAllProcesses, "Yes", "Include all processes.", true); static SwitchOption interfaceAllProcessesNo (interfaceAllProcesses, "No", "Only consider processes matching the exact order in the couplings.", false); interfaceAllProcesses.rank(-1); static RefVector interfaceSelectAmplitudes ("SelectAmplitudes", "The amplitude objects to be favoured in clashing responsibilities.", &MatchboxFactory::theSelectedAmplitudes, -1, false, false, true, true, false); static RefVector interfaceDeselectAmplitudes ("DeselectAmplitudes", "The amplitude objects to be disfavoured in clashing responsibilities.", &MatchboxFactory::theDeselectedAmplitudes, -1, false, false, true, true, false); static Switch interfaceDipoleSet ("DipoleSet", "The set of subtraction terms to be considered.", &MatchboxFactory::theDipoleSet, 0, false, false); static SwitchOption interfaceDipoleSetCataniSeymour (interfaceDipoleSet, "CataniSeymour", "Use default Catani-Seymour dipoles.", 0); interfaceDipoleSet.rank(-1); static RefVector interfaceReweighters ("Reweighters", "Reweight objects for matrix elements.", &MatchboxFactory::theReweighters, -1, false, false, true, false, false); static RefVector interfacePreweighters ("Preweighters", "Preweight objects for matrix elements.", &MatchboxFactory::thePreweighters, -1, false, false, true, false, false); static Switch interfaceMECorrectionsOnly ("MECorrectionsOnly", "Prepare only ME corrections, but no NLO calculation.", &MatchboxFactory::theMECorrectionsOnly, false, false, false); static SwitchOption interfaceMECorrectionsOnlyYes (interfaceMECorrectionsOnly, "Yes", "Produce only ME corrections.", true); static SwitchOption interfaceMECorrectionsOnlyNo (interfaceMECorrectionsOnly, "No", "Produce full NLO.", false); static Switch interfaceLoopSimCorrections ("LoopSimCorrections", "Prepare LoopSim corrections.", &MatchboxFactory::theLoopSimCorrections, false, false, false); static SwitchOption interfaceLoopSimCorrectionsYes (interfaceLoopSimCorrections, "Yes", "Produce loopsim corrections.", true); static SwitchOption interfaceLoopSimCorrectionsNo (interfaceLoopSimCorrections, "No", "Produce full NLO.", false); static Switch interfaceFirstPerturbativePDF ("FirstPerturbativePDF", "", &MatchboxFactory::theFirstPerturbativePDF, true, false, false); static SwitchOption interfaceFirstPerturbativePDFYes (interfaceFirstPerturbativePDF, "Yes", "", true); static SwitchOption interfaceFirstPerturbativePDFNo (interfaceFirstPerturbativePDF, "No", "", false); interfaceFirstPerturbativePDF.rank(-1); static Switch interfaceSecondPerturbativePDF ("SecondPerturbativePDF", "", &MatchboxFactory::theSecondPerturbativePDF, true, false, false); static SwitchOption interfaceSecondPerturbativePDFYes (interfaceSecondPerturbativePDF, "Yes", "", true); static SwitchOption interfaceSecondPerturbativePDFNo (interfaceSecondPerturbativePDF, "No", "", false); interfaceSecondPerturbativePDF.rank(-1); static Command interfaceProductionMode ("ProductionMode", "Switch this factory to production mode.", &MatchboxFactory::doProductionMode, false); static Switch interfaceSpinCorrelations ("SpinCorrelations", "Fill information for the spin correlations, if possible.", &MatchboxFactory::theSpinCorrelations, false, false, false); static SwitchOption interfaceSpinCorrelationsYes (interfaceSpinCorrelations, "Yes", "", true); static SwitchOption interfaceSpinCorrelationsNo (interfaceSpinCorrelations, "No", "", false); static Parameter interfaceAlphaParameter ("AlphaParameter", "Nagy-AlphaParameter.", &MatchboxFactory::theAlphaParameter, 1.0, 0.0, 0, false, false, Interface::lowerlim); static Switch interfaceEnforceChargeConservation ("EnforceChargeConservation", "Enforce charge conservation while generating the hard process.", &MatchboxFactory::theEnforceChargeConservation, true, false, false); static SwitchOption interfaceEnforceChargeConservationYes (interfaceEnforceChargeConservation, "Yes", "Enforce charge conservation.", true); static SwitchOption interfaceEnforceChargeConservationNo (interfaceEnforceChargeConservation, "No", "Do not enforce charge conservation.", false); interfaceEnforceChargeConservation.rank(-1); static Switch interfaceEnforceColourConservation ("EnforceColourConservation", "Enforce colour conservation while generating the hard process.", &MatchboxFactory::theEnforceColourConservation, false, false, false); static SwitchOption interfaceEnforceColourConservationYes (interfaceEnforceColourConservation, "Yes", "Enforce colour conservation.", true); static SwitchOption interfaceEnforceColourConservationNo (interfaceEnforceColourConservation, "No", "Do not enforce colour conservation.", false); interfaceEnforceColourConservation.rank(-1); static Switch interfaceEnforceLeptonNumberConservation ("EnforceLeptonNumberConservation", "Enforce lepton number conservation while generating the hard process.", &MatchboxFactory::theEnforceLeptonNumberConservation, false, false, false); static SwitchOption interfaceEnforceLeptonNumberConservationYes (interfaceEnforceLeptonNumberConservation, "Yes", "Enforce lepton number conservation.", true); static SwitchOption interfaceEnforceLeptonNumberConservationNo (interfaceEnforceLeptonNumberConservation, "No", "Do not enforce lepton number conservation.", false); interfaceEnforceLeptonNumberConservation.rank(-1); static Switch interfaceEnforceQuarkNumberConservation ("EnforceQuarkNumberConservation", "Enforce quark number conservation while generating the hard process.", &MatchboxFactory::theEnforceQuarkNumberConservation, false, false, false); static SwitchOption interfaceEnforceQuarkNumberConservationYes (interfaceEnforceQuarkNumberConservation, "Yes", "Enforce quark number conservation.", true); static SwitchOption interfaceEnforceQuarkNumberConservationNo (interfaceEnforceQuarkNumberConservation, "No", "Do not enforce quark number conservation.", false); interfaceEnforceQuarkNumberConservation.rank(-1); static Switch interfaceLeptonFlavourDiagonal ("LeptonFlavourDiagonal", "Assume that lepton interactions are flavour diagonal while generating the hard process.", &MatchboxFactory::theLeptonFlavourDiagonal, false, false, false); static SwitchOption interfaceLeptonFlavourDiagonalYes (interfaceLeptonFlavourDiagonal, "Yes", "Assume that lepton interactions are flavour diagonal.", true); static SwitchOption interfaceLeptonFlavourDiagonalNo (interfaceLeptonFlavourDiagonal, "No", "Do not assume that lepton interactions are flavour diagonal.", false); interfaceLeptonFlavourDiagonal.rank(-1); static Switch interfaceQuarkFlavourDiagonal ("QuarkFlavourDiagonal", "Assume that quark interactions are flavour diagonal while generating the hard process.", &MatchboxFactory::theQuarkFlavourDiagonal, false, false, false); static SwitchOption interfaceQuarkFlavourDiagonalYes (interfaceQuarkFlavourDiagonal, "Yes", "Assume that quark interactions are flavour diagonal.", true); static SwitchOption interfaceQuarkFlavourDiagonalNo (interfaceQuarkFlavourDiagonal, "No", "Do not assume that quark interactions are flavour diagonal.", false); interfaceQuarkFlavourDiagonal.rank(-1); } // *** 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 describeHerwigMatchboxFactory("Herwig::MatchboxFactory", "Herwig.so"); diff --git a/MatrixElement/Matchbox/MatchboxFactory.h b/MatrixElement/Matchbox/MatchboxFactory.h --- a/MatrixElement/Matchbox/MatchboxFactory.h +++ b/MatrixElement/Matchbox/MatchboxFactory.h @@ -1,1305 +1,1297 @@ // -*- C++ -*- // // MatchboxFactory.h is a part of Herwig - A multi-purpose Monte Carlo event generator // Copyright (C) 2002-2019 The Herwig Collaboration // // Herwig is licenced under version 3 of the GPL, see COPYING for details. // Please respect the MCnet academic guidelines, see GUIDELINES for details. // #ifndef HERWIG_MatchboxFactory_H #define HERWIG_MatchboxFactory_H // // This is the declaration of the MatchboxFactory class. // #include "ThePEG/Handlers/SubProcessHandler.h" #include "Herwig/MatrixElement/Matchbox/Base/MatchboxAmplitude.h" #include "Herwig/MatrixElement/Matchbox/Utility/Tree2toNGenerator.h" #include "Herwig/MatrixElement/Matchbox/Utility/ProcessData.h" #include "Herwig/MatrixElement/Matchbox/Utility/MatchboxScaleChoice.h" #include "Herwig/MatrixElement/Matchbox/Phasespace/MatchboxPhasespace.h" #include "Herwig/MatrixElement/Matchbox/Base/MatchboxMEBase.h" #include "Herwig/MatrixElement/Matchbox/Base/SubtractedME.h" #include "Herwig/MatrixElement/Matchbox/MatchboxFactory.fh" namespace Herwig { using namespace ThePEG; /** * \ingroup Matchbox * \author Simon Platzer * * \brief MatchboxFactory automatically sets up a NLO * QCD calculation carried out in dipole subtraction. * * @see \ref MatchboxFactoryInterfaces "The interfaces" * defined for MatchboxFactory. */ class MatchboxFactory: public SubProcessHandler { public: - /** @name Standard constructors and destructors. */ - //@{ /** * The default constructor. */ MatchboxFactory(); - /** - * The destructor. - */ - virtual ~MatchboxFactory(); - //@} - public: /** * Pointer to the current factory object */ static const Ptr::tptr currentFactory() { assert(theCurrentFactory); return theCurrentFactory; } private: /** * Pointer to the current factory object */ static Ptr::tptr theCurrentFactory; public: /** * Flag to indicate that at least one MatchboxFactory object is in action */ static bool isMatchboxRun() { return theIsMatchboxRun(); } /** @name Process and diagram information */ //@{ /** * Return the diagram generator. */ Ptr::tptr diagramGenerator() const { return theDiagramGenerator; } /** * Set the diagram generator. */ void diagramGenerator(Ptr::ptr dg) { theDiagramGenerator = dg; } /** * Return the process data. */ Ptr::tptr processData() const { return theProcessData; } /** * Set the process data. */ void processData(Ptr::ptr pd) { theProcessData = pd; } /** * Return the number of light flavours, this matrix * element is calculated for. */ unsigned int nLight() const { return theNLight; } /** * Set the number of light flavours, this matrix * element is calculated for. */ void nLight(unsigned int n) { theNLight = n; } /** * Return the vector that contains the PDG ids of * the light flavours, which are contained in the * jet particle group. */ vector nLightJetVec() const { return theNLightJetVec; } /** * Set the elements of the vector that contains the PDG * ids of the light flavours, which are contained in the * jet particle group. */ void nLightJetVec(long n) { theNLightJetVec.push_back(n); } /** * Return the vector that contains the PDG ids of * the heavy flavours, which are contained in the * jet particle group. */ vector nHeavyJetVec() const { return theNHeavyJetVec; } /** * Set the elements of the vector that contains the PDG * ids of the heavy flavours, which are contained in the * jet particle group. */ void nHeavyJetVec(long n) { theNHeavyJetVec.push_back(n); } /** * Return the vector that contains the PDG ids of * the light flavours, which are contained in the * proton particle group. */ vector nLightProtonVec() const { return theNLightProtonVec; } /** * Set the elements of the vector that contains the PDG * ids of the light flavours, which are contained in the * proton particle group. */ void nLightProtonVec(long n) { theNLightProtonVec.push_back(n); } /** * Return the order in \f$\alpha_S\f$. */ unsigned int orderInAlphaS() const { return theOrderInAlphaS; } /** * Set the order in \f$\alpha_S\f$. */ void orderInAlphaS(unsigned int o) { theOrderInAlphaS = o; } /** * Return the order in \f$\alpha_{EM}\f$. */ unsigned int orderInAlphaEW() const { return theOrderInAlphaEW; } /** * Set the order in \f$\alpha_{EM}\f$. */ void orderInAlphaEW(unsigned int o) { theOrderInAlphaEW = o; } /** * The multiplicity of legs with virtual contributions. */ size_t highestVirt() const {return theHighestVirtualSize;} /** * Set the highest **/ void setHighestVirt(size_t n){theHighestVirtualSize=n;} /** * Access the processes vector. */ const vector > getProcesses() const {return processes;} /** * Return true, if all processes up to a maximum order are considered */ bool allProcesses() const { return theAllProcesses; } /** * Switch on/off inclusino off all processes up to a maximum order */ void setAllProcesses(bool on = true) { theAllProcesses = on; } /** * Return true, if Born contributions should be included. */ bool bornContributions() const { return theBornContributions; } /** * Switch on or off Born contributions */ void setBornContributions(bool on = true) { theBornContributions = on; } /** * Return true, if virtual contributions should be included. */ bool virtualContributions() const { return theVirtualContributions; } /** * Switch on or off virtual contributions */ void setVirtualContributions(bool on = true) { theVirtualContributions = on; } /** * Produce matrix element corrections, but no NLO */ bool meCorrectionsOnly() const { return theMECorrectionsOnly; } /** * Switch to produce matrix element corrections, but no NLO */ void setMECorrectionsOnly(bool on = true) { theMECorrectionsOnly = on; } /** * Produce matrix element corrections, with LoopSim NLO */ bool loopSimCorrections() const { return theLoopSimCorrections; } /** * Switch to produce matrix element corrections, with LoopSim NLO */ void setLoopSimCorrections(bool on = true) { theLoopSimCorrections = on; } /** * Return true, if subtracted real emission contributions should be included. */ bool realContributions() const { return theRealContributions; } /** * Switch on or off subtracted real emission contributions */ void setRealContributions(bool on = true) { theRealContributions = on; } /** * Return true, if virtual contributions should be treated as independent subprocesses */ bool independentVirtuals() const { return theIndependentVirtuals; } /** * Switch on/off virtual contributions should be treated as independent subprocesses */ void setIndependentVirtuals(bool on = true) { theIndependentVirtuals = on; } /** * Return true, if PK operator contributions should be treated as independent subprocesses */ bool independentPKs() const { return theIndependentPKs; } /** * Switch on/off PK operator contributions should be treated as independent subprocesses */ void setIndependentPKs(bool on = true) { theIndependentPKs = on; } /** * Return true, if SubProcessGroups should be * setup from this MEGroup. If not, a single SubProcess * is constructed from the data provided by the * head matrix element. */ virtual bool subProcessGroups() const { return !showerApproximation(); } /** * Return true, if subtraction scales should be caluclated from real emission kinematics */ bool realEmissionScales() const { return theRealEmissionScales; } /** * Switch on/off that subtraction scales should be caluclated from real emission kinematics */ void setRealEmissionScales(bool on = true) { theRealEmissionScales = on; } /** * Set the shower approximation. */ void showerApproximation(Ptr::tptr app) { theShowerApproximation = app; } /** * Return the shower approximation. */ Ptr::tptr showerApproximation() const { return theShowerApproximation; } //@} /** @name Phasespace generation and scale choice */ //@{ /** * Return the phase space generator to be used. */ Ptr::tptr phasespace() const { return thePhasespace; } /** * Set the phase space generator to be used. */ void phasespace(Ptr::ptr ps) { thePhasespace = ps; } /** * Set the scale choice object */ void scaleChoice(Ptr::ptr sc) { theScaleChoice = sc; } /** * Return the scale choice object */ Ptr::tptr scaleChoice() const { return theScaleChoice; } /** * Get the factorization scale factor */ double factorizationScaleFactor() const { return theFactorizationScaleFactor; } /** * Set the factorization scale factor */ void factorizationScaleFactor(double f) { theFactorizationScaleFactor = f; } /** * Get the renormalization scale factor */ double renormalizationScaleFactor() const { return theRenormalizationScaleFactor; } /** * Set the renormalization scale factor */ void renormalizationScaleFactor(double f) { theRenormalizationScaleFactor = f; } /** * Return true, if fixed couplings are used. */ bool fixedCouplings() const { return theFixedCouplings; } /** * Switch on fixed couplings. */ void setFixedCouplings(bool on = true) { theFixedCouplings = on; } /** * Return true, if fixed couplings are used. */ bool fixedQEDCouplings() const { return theFixedQEDCouplings; } /** * Switch on fixed couplings. */ void setFixedQEDCouplings(bool on = true) { theFixedQEDCouplings = on; } /** * Return true, if veto scales should be set * for the real emission */ bool vetoScales() const { return theVetoScales; } /** * Switch on setting veto scales */ void doVetoScales() { theVetoScales = true; } /** * Switch off setting veto scales */ void noVetoScales() { theVetoScales = true; } //@} /** @name Amplitudes and caching */ //@{ /** * Return the amplitudes to be considered */ const vector::ptr>& amplitudes() const { return theAmplitudes; } /** * Access the amplitudes to be considered */ vector::ptr>& amplitudes() { return theAmplitudes; } //@} /** @name Matrix element objects. */ //@{ /** * Return the Born matrix elements to be considered */ const vector::ptr>& bornMEs() const { return theBornMEs; } /** * Access the Born matrix elements to be considered */ vector::ptr>& bornMEs() { return theBornMEs; } /** * Return the loop induced matrix elements to be considered */ const vector::ptr>& loopInducedMEs() const { return theLoopInducedMEs; } /** * Access the loop induced matrix elements to be considered */ vector::ptr>& loopInducedMEs() { return theLoopInducedMEs; } /** * Return the processes to be ordered from an OLP */ const map::tptr, map,int> >& olpProcesses() const { return theOLPProcesses; } /** * Access the processes to be ordered from an OLP */ map::tptr, map,int> >& olpProcesses() { return theOLPProcesses; } /** * Order an OLP process and return its id */ int orderOLPProcess(const Process& p, Ptr::tptr amp, int type); /** * Return the amplitudes which need external initialization */ const set::tptr>& externalAmplitudes() const { return theExternalAmplitudes; } /** * Access the amplitudes which need external initialization */ set::tptr>& externalAmplitudes() { return theExternalAmplitudes; } /** * Return the virtual corrections to be considered */ const vector::ptr>& virtuals() const { return theVirtuals; } /** * Access the virtual corrections to be considered */ vector::ptr>& virtuals() { return theVirtuals; } /** * Return the produced NLO matrix elements */ const vector::ptr>& bornVirtualMEs() const { return theBornVirtualMEs; } /** * Access the produced NLO matrix elements */ vector::ptr>& bornVirtualMEs() { return theBornVirtualMEs; } /** * Return the real emission matrix elements to be considered */ const vector::ptr>& realEmissionMEs() const { return theRealEmissionMEs; } /** * Access the real emission matrix elements to be considered */ vector::ptr>& realEmissionMEs() { return theRealEmissionMEs; } /** * Return, which set of dipoles should be considered */ int dipoleSet() const { return theDipoleSet; } /** * Return, which set of dipoles should be considered */ void dipoleSet(int s) { theDipoleSet = s; } /** * Return the produced subtracted matrix elements */ const vector::ptr>& subtractedMEs() const { return theSubtractedMEs; } /** * Access the produced subtracted matrix elements */ vector::ptr>& subtractedMEs() { return theSubtractedMEs; } /** * Return the produced finite real emission matrix elements */ const vector::ptr>& finiteRealMEs() const { return theFiniteRealMEs; } /** * Access the produced finite real emission elements */ vector::ptr>& finiteRealMEs() { return theFiniteRealMEs; } /** * Return the map of Born processes to splitting dipoles */ const map::ptr> >& splittingDipoles() const { return theSplittingDipoles; } /** * Identify a splitting channel */ struct SplittingChannel { /** * The Born XComb */ StdXCombPtr bornXComb; /** * The real XComb */ StdXCombPtr realXComb; /** * The set of tilde XCombs to consider for the real xcomb */ vector tildeXCombs; /** * The dipole in charge of the splitting */ Ptr::ptr dipole; /** * Dump the setup */ void print(ostream&) const; }; /** * Generate all splitting channels for the Born process handled by * the given XComb */ list getSplittingChannels(tStdXCombPtr xc) const; /** * Return the reweight objects for matrix elements */ const vector& reweighters() const { return theReweighters; } /** * Access the reweight objects for matrix elements */ vector& reweighters() { return theReweighters; } /** * Return the preweight objects for matrix elements */ const vector& preweighters() const { return thePreweighters; } /** * Access the preweight objects for matrix elements */ vector& preweighters() { return thePreweighters; } //@} /** @name Setup the matrix elements */ //@{ /** * Return true if this object needs to be initialized before all * other objects (except those for which this function also returns * true). This default version always returns false, but subclasses * may override it to return true. */ virtual bool preInitialize() const { return true; } /** * Prepare a matrix element. */ void prepareME(Ptr::ptr); /** * Check consistency and switch to porduction mode. */ virtual void productionMode(); /** * Setup everything */ virtual void setup(); /** * The highest multiplicity of legs having virtual contributions.(needed for madgraph) */ size_t highestVirt(){return theHighestVirtualsize;} //@} /** @name Diagnostic information */ //@{ /** * Return true, if verbose */ bool verbose() const { return theVerbose; } /** * Switch on diagnostic information. */ void setVerbose(bool on = true) { theVerbose = on; } /** * Return true, if verbose while initializing */ bool initVerbose() const { return theInitVerbose || verbose(); } /** * Switch on diagnostic information while initializing */ void setInitVerbose(bool on = true) { theInitVerbose = on; } /** * Dump the setup */ void print(ostream&) const; /** * Return the subtraction data prefix. */ const string& subtractionData() const { return theSubtractionData; } /** * Set the subtraction data prefix. */ void subtractionData(const string& s) { theSubtractionData = s; } /** * Return the subtraction plot type. */ const int& subtractionPlotType() const { return theSubtractionPlotType; } /** * Set the subtraction plot type. */ void subtractionPlotType(const int& t) { theSubtractionPlotType = t; } /** * Return whether subtraction data should be plotted for all phase space points individually */ const bool& subtractionScatterPlot() const { return theSubtractionScatterPlot; } /** * Set whether subtraction data should be plotted for all phase space points individually */ void subtractionScatterPlot(const bool& s) { theSubtractionScatterPlot = s; } /** * Return the pole data prefix. */ const string& poleData() const { return thePoleData; } /** * Set the pole data prefix. */ void poleData(const string& s) { thePoleData = s; } /** * Return true, if cancellationn of epsilon poles should be checked. */ bool checkPoles() const { return poleData() != ""; } //@} /** @name Process generation */ //@{ /** * Return the particle groups. */ const map& particleGroups() const { return theParticleGroups; } /** * Access the particle groups. */ map& particleGroups() { return theParticleGroups; } /** * Return true, if the given particle is incoming */ bool isIncoming(cPDPtr p) const { return theIncoming.find(p->id()) != theIncoming.end(); } /** * Return true, if spin correlation information should be provided, if possible. */ bool spinCorrelations() const { return theSpinCorrelations; } /** * Indicate that spin correlation information should be provided, if possible. */ void setSpinCorrelations(bool yes) { theSpinCorrelations = yes; } //@} /** @name Truncated qtilde shower information */ //@{ /** * Return the subprocess of the real emission */ tSubProPtr hardTreeSubprocess() { return theHardtreeSubprocess; } /** * Set the subprocess of the real emission for use in calculating the shower hardtree */ void setHardTreeSubprocess(tSubProPtr hardTree) { theHardtreeSubprocess = hardTree; } /** * Return the born emitter */ int hardTreeEmitter() { return theHardtreeEmitter; } /** * Set the born emitter for use in calculating the shower hardtree */ void setHardTreeEmitter(int emitter) { theHardtreeEmitter = emitter; } /** * Return the born spectator */ int hardTreeSpectator() { return theHardtreeSpectator; } /** * Set the born spectator for use in calculating the shower hardtree */ void setHardTreeSpectator(int spectator) { theHardtreeSpectator = spectator; } //@} /** @name Data handling */ //@{ /** * Return (and possibly create) a directory to contain amplitude * information. */ const string& buildStorage(); /** * Return (and possibly create) a directory to contain integration grid * information. */ const string& runStorage(); /** * alpha of http://arxiv.org/pdf/hep-ph/0307268v2.pdf to restrict * dipole phase space */ double alphaParameter() const { return theAlphaParameter; } /** * set the alpha parameter (needed for massive PK-Operator) */ void setAlphaParameter(double a)const { theAlphaParameter = a; } //@} public: /** * Print a summary of the parameters used */ void summary(ostream&) 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; //@} protected: /** @name Standard Interfaced functions. */ //@{ /** * Initialize this object after the setup phase before saving an * EventGenerator to disk. * @throws InitException if object could not be initialized properly. */ virtual void doinit(); /** * Initialize this object. Called in the run phase just before * a run begins. */ virtual void doinitrun(); //@} private: /** * Flag to indicate that at least one MatchboxFactory object is in action */ static bool& theIsMatchboxRun(); /** * The diagram generator. */ Ptr::ptr theDiagramGenerator; /** * The process data object to be used */ Ptr::ptr theProcessData; /** * The number of light flavours, this matrix * element is calculated for. */ unsigned int theNLight; /** * Vector with the PDG ids of the light quark flavours, * which are contained in the jet particle group. */ vector theNLightJetVec; /** * Vector with the PDG ids of the heavy quark flavours, * which are contained in the jet particle group. */ vector theNHeavyJetVec; /** * Vector with the PDG ids of the light quark flavours, * which are contained in the proton particle group. */ vector theNLightProtonVec; /** * The order in \f$\alpha_S\f$. */ unsigned int theOrderInAlphaS; /** * The order in \f$\alpha_{EM}\f$. */ unsigned int theOrderInAlphaEW; /** * The maximum number of legs with virtual corrections. **/ unsigned int theHighestVirtualSize; /** * Switch on or off Born contributions */ bool theBornContributions; /** * Switch on or off virtual contributions */ bool theVirtualContributions; /** * Switch on or off subtracted real emission contributions should be included. */ bool theRealContributions; /** * True if virtual contributions should be treated as independent subprocesses */ bool theIndependentVirtuals; /** * True if PK operator contributions should be treated as independent subprocesses */ bool theIndependentPKs; /** * The phase space generator to be used. */ Ptr::ptr thePhasespace; /** * The scale choice object */ Ptr::ptr theScaleChoice; /** * The factorization scale factor. */ double theFactorizationScaleFactor; /** * The renormalization scale factor. */ double theRenormalizationScaleFactor; /** * Use non-running couplings. */ bool theFixedCouplings; /** * Use non-running couplings. */ bool theFixedQEDCouplings; /** * True, if veto scales should be set * for the real emission */ bool theVetoScales; /** * The amplitudes to be considered */ vector::ptr> theAmplitudes; /** * The Born matrix elements to be considered */ vector::ptr> theBornMEs; /** * The loop induced matrix elements to be considered */ vector::ptr> theLoopInducedMEs; /** * The virtual corrections to be considered */ vector::ptr> theVirtuals; /** * The real emission matrix elements to be considered */ vector::ptr> theRealEmissionMEs; /** * The produced NLO matrix elements */ vector::ptr> theBornVirtualMEs; /** * The produced subtracted matrix elements */ vector::ptr> theSubtractedMEs; /** * The produced finite real emission matrix elements */ vector::ptr> theFiniteRealMEs; /** * Which set of dipoles should be considered */ int theDipoleSet; /** * Switch on or off verbosity */ bool theVerbose; /** * True, if verbose while initializing */ bool theInitVerbose; /** * Prefix for subtraction data */ string theSubtractionData; /** * Set the type of plot that is to be generated for subtraction checking */ int theSubtractionPlotType; /** * Set whether subtraction data should be plotted for all phase space points individually */ bool theSubtractionScatterPlot; /** * Prefix for pole data. */ string thePoleData; /** * Command to limit the real emission process to be considered. */ string doSingleRealProcess(string); /** * The real emission process to be included; if empty, all possible * ones will be considered. */ vector > realEmissionProcesses; /** * Particle groups. */ map theParticleGroups; /** * Command to start a particle group. */ string startParticleGroup(string); /** * The name of the particle group currently edited. */ string particleGroupName; /** * The particle group currently edited. */ PDVector particleGroup; /** * Command to end a particle group. */ string endParticleGroup(string); protected: /** * Parse a process description */ virtual vector parseProcess(string); private: /** * Command to set the process. */ string doProcess(string); /** * Command to set the process. */ string doLoopInducedProcess(string); /** * The process to consider in terms of particle groups. */ vector > processes; /** * The loop induced process to consider in terms of particle groups. */ vector > loopInducedProcesses; /** * Generate subprocesses. */ set makeSubProcesses(const vector&) const; public: /** * Generate matrix element objects for the given process. */ vector::ptr> makeMEs(const vector&, unsigned int orderas, bool virt); private: /** * The shower approximation. */ Ptr::ptr theShowerApproximation; /** * The map of Born processes to splitting dipoles */ map::ptr> > theSplittingDipoles; /** * True, if subtraction scales should be caluclated from real emission kinematics */ bool theRealEmissionScales; /** * Consider all processes with order in couplings specifying the * maximum order. */ bool theAllProcesses; /** * The processes to be ordered from an OLP */ map::tptr,map,int> > theOLPProcesses; /** * Amplitudes which need external initialization */ set::tptr> theExternalAmplitudes; /** * Amplitudes to be selected on clashing responsibilities. */ vector::ptr> theSelectedAmplitudes; /** * Amplitudes to be deselected on clashing responsibilities. */ vector::ptr> theDeselectedAmplitudes; /** * Reweight objects for matrix elements */ vector theReweighters; /** * Preweight objects for matrix elements */ vector thePreweighters; /** * Produce matrix element corrections, but no NLO */ bool theMECorrectionsOnly; /** * The highest multiplicity of legs having virtual contributions.(needed for madgraph) */ int theHighestVirtualsize; /** * Produce matrix element corrections, with LoopSim NLO */ bool theLoopSimCorrections; /** * True, if the setup has already been run. */ bool ranSetup; /** * PDG ids of incoming particles */ set theIncoming; /** * True, if first incoming partons originate from perturbative PDF */ bool theFirstPerturbativePDF; /** * True, if second incoming partons originate from perturbative PDF */ bool theSecondPerturbativePDF; /** * True, if this Factory is in production mode. */ bool inProductionMode; /** * The real emission subprocess used when calculating the hardtree * in the truncated qtilde shower */ tSubProPtr theHardtreeSubprocess; /** * The born emitter used when calculating the hardtree in * the truncated shower */ int theHardtreeEmitter; /** * The born spectator used when calculating the hardtree in * the truncated shower */ int theHardtreeSpectator; /** * True, if spin correlation information should be provided, if possible. */ bool theSpinCorrelations; /** * The alpha parameter to be used for the dipole subtraction * JB: The parameter is muatble, since we need to be able to change it * while calculating the difference of IPK with and without alpha. */ mutable double theAlphaParameter; /** * Wether or not charge conservation should be enforced for the processes * constructed. */ bool theEnforceChargeConservation; /** * Wether or not colour conservation should be enforced for the processes * constructed. */ bool theEnforceColourConservation; /** * Wether or not lepton number conservation should be enforced for the processes * constructed. */ bool theEnforceLeptonNumberConservation; /** * Wether or not quark number conservation should be enforced for the processes * constructed. */ bool theEnforceQuarkNumberConservation; /** * Assume flavour diagonal lepton interactions */ bool theLeptonFlavourDiagonal; /** * Assume flavour diagonal quark interactions */ bool theQuarkFlavourDiagonal; /** * Command for production mode */ string doProductionMode(string) { productionMode(); return ""; } private: /** * The assignment operator is private and must never be called. * In fact, it should not even be implemented. */ MatchboxFactory & operator=(const MatchboxFactory &) = delete; }; } #endif /* HERWIG_MatchboxFactory_H */ diff --git a/MatrixElement/Matchbox/Matching/DipoleMatching.cc b/MatrixElement/Matchbox/Matching/DipoleMatching.cc --- a/MatrixElement/Matchbox/Matching/DipoleMatching.cc +++ b/MatrixElement/Matchbox/Matching/DipoleMatching.cc @@ -1,147 +1,141 @@ // -*- C++ -*- // // DipoleMatching.cc is a part of Herwig - A multi-purpose Monte Carlo event generator // Copyright (C) 2002-2019 The Herwig Collaboration // // Herwig is licenced under version 3 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 DipoleMatching class. // #include "DipoleMatching.h" #include "ThePEG/Interface/ClassDocumentation.h" #include "ThePEG/Interface/Switch.h" #include "ThePEG/Interface/Reference.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; -DipoleMatching::DipoleMatching() {} - -DipoleMatching::~DipoleMatching() {} - IBPtr DipoleMatching::clone() const { return new_ptr(*this); } IBPtr DipoleMatching::fullclone() const { return new_ptr(*this); } CrossSection DipoleMatching::dSigHatDR() const { double xme2 = 0.; pair ij(dipole()->bornEmitter(), dipole()->bornSpectator()); double ccme2 = dipole()->underlyingBornME()->largeNColourCorrelatedME2(ij,theLargeNBasis); if(ccme2==0.)return 0.*nanobarn; double lnme2=dipole()->underlyingBornME()->largeNME2(theLargeNBasis); if(lnme2==0){ generator()->log() <<"\nDipoleMatching: "; generator()->log() <<"\n LargeNME2 is ZERO, while largeNColourCorrelatedME2 is not ZERO." ; generator()->log() <<"\n This is too seriuos.\n" ; generator()->log() << Exception::runerror; } ccme2 *= dipole()->underlyingBornME()->me2() /lnme2; xme2 = dipole()->me2Avg(ccme2); xme2 /= dipole()->underlyingBornME()->lastXComb().lastAlphaS(); double bornPDF = bornPDFWeight(dipole()->underlyingBornME()->lastScale()); if ( bornPDF == 0.0 ) return ZERO; xme2 *= bornPDF; if ( profileScales() ) xme2 *= profileScales()->hardScaleProfile(dipole()->showerHardScale(),dipole()->lastPt()); CrossSection res = sqr(hbarc) * realXComb()->jacobian() * subtractionScaleWeight() * xme2 / (2. * realXComb()->lastSHat()); return res; } double DipoleMatching::me2() const { throw Exception() << "DipoleMatching::me2(): Not intented to use. Disable the ShowerApproximationGenerator." << Exception::runerror; return 0.; } // If needed, insert default implementations of virtual function defined // in the InterfacedBase class here (using ThePEG-interfaced-impl in Emacs). void DipoleMatching::persistentOutput(PersistentOStream & os) const { os << theShowerHandler; } void DipoleMatching::persistentInput(PersistentIStream & is, int) { is >> theShowerHandler; } void DipoleMatching::doinit() { if ( theShowerHandler ) { theShowerHandler->init(); hardScaleFactor(theShowerHandler->hardScaleFactor()); factorizationScaleFactor(theShowerHandler->factorizationScaleFactor()); renormalizationScaleFactor(theShowerHandler->renormalizationScaleFactor()); profileScales(theShowerHandler->profileScales()); restrictPhasespace(theShowerHandler->restrictPhasespace()); hardScaleIsMuF(theShowerHandler->hardScaleIsMuF()); if ( theShowerHandler->showerPhaseSpaceOption() == 0 ) { useOpenZ(false); } else if ( theShowerHandler->showerPhaseSpaceOption() == 1 ) { useOpenZ(true); } else { throw InitException() << "DipoleMatching::doinit(): Choice of shower phase space cannot be handled by the matching"; } } // need to fo this after for consistency checks ShowerApproximation::doinit(); } // *** 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 describeHerwigDipoleMatching("Herwig::DipoleMatching", "HwDipoleMatching.so HwShower.so"); void DipoleMatching::Init() { static ClassDocumentation documentation ("DipoleMatching implements NLO matching with the dipole shower."); static Reference interfaceShowerHandler ("ShowerHandler", "The dipole shower handler object to use.", &DipoleMatching::theShowerHandler, false, false, true, true, false); interfaceShowerHandler.rank(-1); } diff --git a/MatrixElement/Matchbox/Matching/DipoleMatching.h b/MatrixElement/Matchbox/Matching/DipoleMatching.h --- a/MatrixElement/Matchbox/Matching/DipoleMatching.h +++ b/MatrixElement/Matchbox/Matching/DipoleMatching.h @@ -1,140 +1,125 @@ // -*- C++ -*- // // DipoleMatching.h is a part of Herwig - A multi-purpose Monte Carlo event generator // Copyright (C) 2002-2019 The Herwig Collaboration // // Herwig is licenced under version 3 of the GPL, see COPYING for details. // Please respect the MCnet academic guidelines, see GUIDELINES for details. // #ifndef Herwig_DipoleMatching_H #define Herwig_DipoleMatching_H // // This is the declaration of the DipoleMatching class. // #include "Herwig/Shower/ShowerHandler.h" #include "Herwig/MatrixElement/Matchbox/Matching/ShowerApproximation.h" namespace Herwig { using namespace ThePEG; /** * \ingroup Matchbox * \author Simon Platzer * * \brief DipoleMatching implements NLO matching with the dipole shower. * */ class DipoleMatching: public Herwig::ShowerApproximation { public: - /** @name Standard constructors and destructors. */ - //@{ - /** - * The default constructor. - */ - DipoleMatching(); - - /** - * The destructor. - */ - virtual ~DipoleMatching(); - //@} - -public: - /** * Return the shower approximation to the real emission cross * section for the given pair of Born and real emission * configurations. */ virtual CrossSection dSigHatDR() const; /** * Return the shower approximation splitting kernel for the given * pair of Born and real emission configurations in units of the * Born center of mass energy squared, and including a weight to * project onto the splitting given by the dipole used. */ virtual double me2() 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). protected: /** @name Standard Interfaced functions. */ //@{ /** * Initialize this object after the setup phase before saving an * EventGenerator to disk. * @throws InitException if object could not be initialized properly. */ virtual void doinit(); //@} private: /** * The shower handler to be used */ Ptr::ptr theShowerHandler; /** * The assignment operator is private and must never be called. * In fact, it should not even be implemented. */ DipoleMatching & operator=(const DipoleMatching &) = delete; }; } #endif /* Herwig_DipoleMatching_H */ diff --git a/MatrixElement/Matchbox/Matching/HardScaleProfile.cc b/MatrixElement/Matchbox/Matching/HardScaleProfile.cc --- a/MatrixElement/Matchbox/Matching/HardScaleProfile.cc +++ b/MatrixElement/Matchbox/Matching/HardScaleProfile.cc @@ -1,134 +1,132 @@ // -*- C++ -*- // // HardScaleProfile.cc is a part of Herwig - A multi-purpose Monte Carlo event generator // Copyright (C) 2002-2019 The Herwig Collaboration // // Herwig is licenced under version 3 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 HardScaleProfile class. // #include "HardScaleProfile.h" #include "ThePEG/Interface/ClassDocumentation.h" #include "ThePEG/EventRecord/Particle.h" #include "ThePEG/Repository/UseRandom.h" #include "ThePEG/Repository/EventGenerator.h" #include "ThePEG/Utilities/DescribeClass.h" #include "ThePEG/Interface/Parameter.h" #include "ThePEG/Interface/Switch.h" #include "ThePEG/Persistency/PersistentOStream.h" #include "ThePEG/Persistency/PersistentIStream.h" using namespace Herwig; HardScaleProfile::HardScaleProfile() : theFixedHardScale(ZERO), theProfileRho(0.3), theProfileType(resummation) {} -HardScaleProfile::~HardScaleProfile() {} - IBPtr HardScaleProfile::clone() const { return new_ptr(*this); } IBPtr HardScaleProfile::fullclone() const { return new_ptr(*this); } double HardScaleProfile::hardScaleProfile(Energy hard, Energy soft) const { if ( theFixedHardScale > ZERO ) hard = theFixedHardScale; double x = soft/hard; if ( theProfileType == theta ) { return x <= 1. ? 1.0 : 0.0; } if ( theProfileType == resummation ) { 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 ( theProfileType == hfact ) { return 1./(1.+x); } return 1.; } bool HardScaleProfile::unrestrictedPhasespace() const { if ( theProfileType == theta || theProfileType == resummation ) { return false; } return true; } // If needed, insert default implementations of virtual function defined // in the InterfacedBase class here (using ThePEG-interfaced-impl in Emacs). void HardScaleProfile::persistentOutput(PersistentOStream & os) const { os << ounit(theFixedHardScale,GeV) << theProfileRho << theProfileType; } void HardScaleProfile::persistentInput(PersistentIStream & is, int) { is >> iunit(theFixedHardScale,GeV) >> theProfileRho >> theProfileType; } // *** 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 describeHerwigHardScaleProfile("Herwig::HardScaleProfile", "Herwig.so"); void HardScaleProfile::Init() { static ClassDocumentation documentation ("HardScaleProfile implements profile scales."); static Parameter interfaceFixedHardScale ("FixedHardScale", "A fixed hard scale to be used instead of the process specific choice.", &HardScaleProfile::theFixedHardScale, GeV, ZERO, 0.0*GeV, 0*GeV, false, false, Interface::lowerlim); static Parameter interfaceProfileRho ("ProfileRho", "The profile width parameter", &HardScaleProfile::theProfileRho, 0.3, 0.0, 1.0, false, false, Interface::limited); static Switch interfaceProfileType ("ProfileType", "The type of profile to use.", &HardScaleProfile::theProfileType, resummation, false, false); static SwitchOption interfaceProfileTypeTheta (interfaceProfileType, "Theta", "Use a hard cutoff.", theta); static SwitchOption interfaceProfileTypeResummation (interfaceProfileType, "Resummation", "Use the resummation profile with quadratic interpolation.", resummation); static SwitchOption interfaceProfileTypeHFact (interfaceProfileType, "HFact", "Use the hfact profile.", hfact); } diff --git a/MatrixElement/Matchbox/Matching/HardScaleProfile.h b/MatrixElement/Matchbox/Matching/HardScaleProfile.h --- a/MatrixElement/Matchbox/Matching/HardScaleProfile.h +++ b/MatrixElement/Matchbox/Matching/HardScaleProfile.h @@ -1,150 +1,142 @@ // -*- C++ -*- // // HardScaleProfile.h is a part of Herwig - A multi-purpose Monte Carlo event generator // Copyright (C) 2002-2019 The Herwig Collaboration // // Herwig is licenced under version 3 of the GPL, see COPYING for details. // Please respect the MCnet academic guidelines, see GUIDELINES for details. // #ifndef Herwig_HardScaleProfile_H #define Herwig_HardScaleProfile_H // // This is the declaration of the HardScaleProfile class. // #include "ThePEG/Interface/Interfaced.h" namespace Herwig { using namespace ThePEG; /** * \ingroup Matchbox * \author Simon Platzer * * \brief HardScaleProfile is the base class for profile scales. A few * standard choices are provided by this implementation. * */ class HardScaleProfile: public Interfaced { public: - /** @name Standard constructors and destructors. */ - //@{ /** * The default constructor. */ HardScaleProfile(); - /** - * The destructor. - */ - virtual ~HardScaleProfile(); - //@} - public: /** * Return a scale profile towards the hard scale */ virtual double hardScaleProfile(Energy hard, Energy soft) const; /** * Return true, if this hard scale profile requires an unrestricted * radiation phase space. */ virtual bool unrestrictedPhasespace() 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). protected: /** * Enumerate the possible profiles */ enum ProfileTypes { theta = 0, /** hard theta cut */ resummation = 1, /** `resummation' profile with quadratic interpolation */ hfact = 2 /** hfact profile */ }; /** * A fixed hard scale to be used instead of the hard scale decided * for the process in question. */ Energy theFixedHardScale; /** * A dimensionless width parameter setting the smearing size * relative to the hard scale; this may have different * interpretations depending on the profile type chosen. */ double theProfileRho; /** * The profile type to be used */ int theProfileType; private: /** * The assignment operator is private and must never be called. * In fact, it should not even be implemented. */ HardScaleProfile & operator=(const HardScaleProfile &) = delete; }; } #endif /* Herwig_HardScaleProfile_H */ diff --git a/MatrixElement/Matchbox/Matching/MEMatching.cc b/MatrixElement/Matchbox/Matching/MEMatching.cc --- a/MatrixElement/Matchbox/Matching/MEMatching.cc +++ b/MatrixElement/Matchbox/Matching/MEMatching.cc @@ -1,152 +1,150 @@ // -*- C++ -*- // // MEMatching.cc is a part of Herwig - A multi-purpose Monte Carlo event generator // Copyright (C) 2002-2019 The Herwig Collaboration // // Herwig is licenced under version 3 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 MEMatching class. // #include "MEMatching.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/Handlers/StdXCombGroup.h" #include "ThePEG/PDT/EnumParticles.h" #include "ThePEG/Persistency/PersistentOStream.h" #include "ThePEG/Persistency/PersistentIStream.h" #include "Herwig/MatrixElement/Matchbox/Dipoles/SubtractionDipole.h" using namespace Herwig; MEMatching::MEMatching() : theTruncatedShower(false) {} -MEMatching::~MEMatching() {} - IBPtr MEMatching::clone() const { return new_ptr(*this); } IBPtr MEMatching::fullclone() const { return new_ptr(*this); } CrossSection MEMatching::dSigHatDR() const { // need to ensure the partner dipoles all got their xcombs set // for a safe evaluation of channelweight Ptr::tcptr grp = dynamic_ptr_cast::tcptr>(realCXComb()); assert(grp); for ( vector::const_iterator dep = grp->dependent().begin(); dep != grp->dependent().end(); ++dep ) { (**dep).matrixElement()->setXComb(*dep); } double xme2 = dipole()->realEmissionME()->me2(); xme2 *= channelWeight(); xme2 /= pow(dipole()->realEmissionME()->lastXComb().lastAlphaS(), (double)(dipole()->realEmissionME()->orderInAlphaS())); xme2 *= pow(dipole()->underlyingBornME()->lastXComb().lastAlphaS(), (double)(dipole()->underlyingBornME()->orderInAlphaS())); double bornPDF = bornPDFWeight(dipole()->underlyingBornME()->lastScale()); if ( bornPDF == 0.0 ) return ZERO; xme2 *= bornPDF; if ( profileScales() ) xme2 *= profileScales()->hardScaleProfile(dipole()->showerHardScale(),dipole()->lastPt()); return sqr(hbarc) * realXComb()->jacobian() * subtractionScaleWeight() * xme2 / (2. * realXComb()->lastSHat()); } double MEMatching::me2() const { double bme2 = bornXComb()->matrixElement()->me2(); bme2 /= pow(dipole()->underlyingBornME()->lastXComb().lastAlphaS(), (double)(dipole()->underlyingBornME()->orderInAlphaS())); double rme2 = dipole()->realEmissionME()->me2(); rme2 /= pow(dipole()->realEmissionME()->lastXComb().lastAlphaS(), (double)(dipole()->realEmissionME()->orderInAlphaS())); rme2 *= pow(bornXComb()->lastSHat()/realXComb()->lastSHat(), realCXComb()->mePartonData().size()-4.); if ( profileScales() ) rme2 *= profileScales()->hardScaleProfile(dipole()->showerHardScale(),dipole()->lastPt()); return channelWeight() * (rme2/bme2) * (bornXComb()->lastSHat()/realXComb()->lastSHat()) * splittingScaleWeight(); } // If needed, insert default implementations of virtual function defined // in the InterfacedBase class here (using ThePEG-interfaced-impl in Emacs). void MEMatching::persistentOutput(PersistentOStream & os) const { os << theTruncatedShower; } void MEMatching::persistentInput(PersistentIStream & is, int) { is >> theTruncatedShower; } // *** 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 describeHerwigMEMatching("Herwig::MEMatching", "Herwig.so"); void MEMatching::Init() { static ClassDocumentation documentation ("MEMatching implements NLO matching with matrix element correction (aka Powheg)."); static Switch interfaceTruncatedShower ("TruncatedShower", "Include a truncated qtilde shower", &MEMatching::theTruncatedShower, false, false, false); static SwitchOption interfaceTruncatedShowerYes (interfaceTruncatedShower, "Yes", "", true); static SwitchOption interfaceTruncatedShowerNo (interfaceTruncatedShower, "No", "", false); } diff --git a/MatrixElement/Matchbox/Matching/MEMatching.h b/MatrixElement/Matchbox/Matching/MEMatching.h --- a/MatrixElement/Matchbox/Matching/MEMatching.h +++ b/MatrixElement/Matchbox/Matching/MEMatching.h @@ -1,147 +1,139 @@ // -*- C++ -*- // // MEMatching.h is a part of Herwig - A multi-purpose Monte Carlo event generator // Copyright (C) 2002-2019 The Herwig Collaboration // // Herwig is licenced under version 3 of the GPL, see COPYING for details. // Please respect the MCnet academic guidelines, see GUIDELINES for details. // #ifndef Herwig_MEMatching_H #define Herwig_MEMatching_H // // This is the declaration of the MEMatching class. // #include "Herwig/MatrixElement/Matchbox/Matching/ShowerApproximation.h" namespace Herwig { using namespace ThePEG; /** * \ingroup Matchbox * \author Simon Platzer * * \brief MEMatching implements NLO matching with matrix element correction (aka Powheg). * */ class MEMatching: public Herwig::ShowerApproximation { public: - /** @name Standard constructors and destructors. */ - //@{ /** * The default constructor. */ MEMatching(); - /** - * The destructor. - */ - virtual ~MEMatching(); - //@} - public: /** * Return true, if this shower approximation will require a * splitting generator */ virtual bool needsSplittingGenerator() const { return true; } /** * Return true, if this shower approximation will require * H events */ virtual bool hasHEvents() const { return restrictPhasespace() || profileScales(); } /** * Return true, if this shower approximation will require * a truncated parton shower */ virtual bool needsTruncatedShower() const { return theTruncatedShower; } public: /** * Return the shower approximation to the real emission cross * section for the given pair of Born and real emission * configurations. */ virtual CrossSection dSigHatDR() const; /** * Return the shower approximation splitting kernel for the given * pair of Born and real emission configurations in units of the * Born center of mass energy squared, and including a weight to * project onto the splitting given by the dipole used. */ virtual double me2() 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. */ MEMatching & operator=(const MEMatching &) = delete; /** * True, if a truncated parton shower should be generated */ bool theTruncatedShower; }; } #endif /* Herwig_MEMatching_H */ diff --git a/MatrixElement/Matchbox/Matching/QTildeMatching.cc b/MatrixElement/Matchbox/Matching/QTildeMatching.cc --- a/MatrixElement/Matchbox/Matching/QTildeMatching.cc +++ b/MatrixElement/Matchbox/Matching/QTildeMatching.cc @@ -1,538 +1,536 @@ // -*- C++ -*- // // QTildeMatching.cc is a part of Herwig - A multi-purpose Monte Carlo event generator // Copyright (C) 2002-2019 The Herwig Collaboration // // Herwig is licenced under version 3 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 QTildeMatching class. // #include "QTildeMatching.h" #include "ThePEG/Interface/ClassDocumentation.h" #include "ThePEG/Interface/Switch.h" #include "ThePEG/Interface/Reference.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" #include "Herwig/MatrixElement/Matchbox/Phasespace/TildeKinematics.h" #include "Herwig/Shower/QTilde/Kinematics/KinematicHelpers.h" using namespace Herwig; QTildeMatching::QTildeMatching() : theCorrectForXZMismatch(true) {} -QTildeMatching::~QTildeMatching() {} - IBPtr QTildeMatching::clone() const { return new_ptr(*this); } IBPtr QTildeMatching::fullclone() const { return new_ptr(*this); } void QTildeMatching::checkCutoff() { if ( showerTildeKinematics() ) { showerTildeKinematics()-> prepare(realCXComb(),bornCXComb()); showerTildeKinematics()->dipole(dipole()); showerTildeKinematics()->getShowerVariables(); } } void QTildeMatching::getShowerVariables() { // already filled from checkCutoff in this case if ( showerTildeKinematics() ) return; // get the shower variables calculateShowerVariables(); // check for the cutoff dipole()->isAboveCutoff(isAboveCutoff()); // get the hard scale dipole()->showerHardScale(hardScale()); // check for phase space dipole()->isInShowerPhasespace(isInShowerPhasespace()); } bool QTildeMatching::isInShowerPhasespace() const { Energy qtildeHard = ZERO; Energy qtilde = dipole()->showerScale(); assert(!dipole()->showerParameters().empty()); double z = dipole()->showerParameters()[0]; // FF if ( dipole()->bornEmitter() > 1 && dipole()->bornSpectator() > 1 ) { qtildeHard = theQTildeFinder-> calculateFinalFinalScales(bornCXComb()->meMomenta()[dipole()->bornEmitter()], bornCXComb()->meMomenta()[dipole()->bornSpectator()]).first; } // FI if ( dipole()->bornEmitter() > 1 && dipole()->bornSpectator() < 2 ) { qtildeHard = theQTildeFinder-> calculateInitialFinalScales(bornCXComb()->meMomenta()[dipole()->bornSpectator()], bornCXComb()->meMomenta()[dipole()->bornEmitter()],false).second; } // IF if ( dipole()->bornEmitter() < 2 && dipole()->bornSpectator() > 1 ) { qtildeHard = theQTildeFinder-> calculateInitialFinalScales(bornCXComb()->meMomenta()[dipole()->bornEmitter()], bornCXComb()->meMomenta()[dipole()->bornSpectator()],false).first; if ( z < (dipole()->bornEmitter() == 0 ? bornCXComb()->lastX1() : bornCXComb()->lastX2()) ) return false; } // II if ( dipole()->bornEmitter() < 2 && dipole()->bornSpectator() < 2 ) { qtildeHard = theQTildeFinder-> calculateInitialInitialScales(bornCXComb()->meMomenta()[dipole()->bornEmitter()], bornCXComb()->meMomenta()[dipole()->bornSpectator()]).first; if ( z < (dipole()->bornEmitter() == 0 ? bornCXComb()->lastX1() : bornCXComb()->lastX2()) ) return false; } Energy2 pt2 = ZERO; const vector & masses = theQTildeSudakov->virtualMasses({{ bornCXComb()->mePartonData()[dipole()->bornEmitter() ], realCXComb()->mePartonData()[dipole()->realEmitter() ], realCXComb()->mePartonData()[dipole()->realEmission()] }}); const Energy2 m22 = sqr(masses[2]); if ( dipole()->bornEmitter() > 1 ) { const Energy2 m02 = sqr(masses[0]); const Energy2 m12 = sqr(masses[1]); pt2 = QTildeKinematics::pT2_FSR(sqr(qtilde),z,m02,m12,m22,m12,m22); } else { pt2 = QTildeKinematics::pT2_ISR(sqr(qtilde),z,m22); } if ( pt2 < max(theQTildeSudakov->pT2min(),sqr(safeCut()) )) return false; bool hardVeto = restrictPhasespace() && sqrt(pt2) >= dipole()->showerHardScale(); return qtilde <= qtildeHard && !hardVeto; } bool QTildeMatching::isAboveCutoff() const { Energy qtilde = dipole()->showerScale(); assert(!dipole()->showerParameters().empty()); double z = dipole()->showerParameters()[0]; const vector & masses = theQTildeSudakov->virtualMasses({{ bornCXComb()->mePartonData()[dipole()->bornEmitter() ], realCXComb()->mePartonData()[dipole()->realEmitter() ], realCXComb()->mePartonData()[dipole()->realEmission()] }}); const Energy2 m22 = sqr(masses[2]); if ( dipole()->bornEmitter() > 1 ) { const Energy2 m02 = sqr(masses[0]); const Energy2 m12 = sqr(masses[1]); const Energy2 pt2 = QTildeKinematics::pT2_FSR(sqr(qtilde),z,m02,m12,m22,m12,m22); return pt2 >= max(theQTildeSudakov->pT2min(),sqr(safeCut())); } else { const Energy2 pt2 = QTildeKinematics::pT2_ISR(sqr(qtilde),z,m22); return pt2 >= max(theQTildeSudakov->pT2min(),sqr(safeCut())); } return false; } CrossSection QTildeMatching::dSigHatDR() const { assert(!dipole()->showerParameters().empty()); pair vars = make_pair(sqr(dipole()->showerScale()), dipole()->showerParameters()[0]); pair ij(dipole()->bornEmitter(), dipole()->bornSpectator()); double ccme2 = dipole()->underlyingBornME()->largeNColourCorrelatedME2(ij,theLargeNBasis); if(ccme2==0.)return 0.*nanobarn; double lnme2=dipole()->underlyingBornME()->largeNME2(theLargeNBasis); if(lnme2==0){ generator()->log() <<"\nQTildeMatching: "; generator()->log() <<"\n largeNME2 is ZERO, while largeNColourCorrelatedME2 is not ZERO." ; generator()->log() <<"\n This is too seriuos.\n" ; generator()->log() << Exception::runerror; } ccme2 *= dipole()->underlyingBornME()->me2() /lnme2; Energy2 prop = ZERO; if ( dipole()->bornEmitter() > 1 ) { prop = (realCXComb()->meMomenta()[dipole()->realEmitter()] + realCXComb()->meMomenta()[dipole()->realEmission()]).m2() - bornCXComb()->meMomenta()[dipole()->bornEmitter()].m2(); } else { prop = 2.*vars.second*(realCXComb()->meMomenta()[dipole()->realEmitter()]* realCXComb()->meMomenta()[dipole()->realEmission()]); } // note alphas included downstream from subtractionScaleWeight() double xme2 = -8.*Constants::pi*ccme2*splitFn(vars)*realXComb()->lastSHat()/prop; xme2 *= pow(realCXComb()->lastSHat() / bornCXComb()->lastSHat(), bornCXComb()->mePartonData().size()-4.); double bornPDF = bornPDFWeight(dipole()->underlyingBornME()->lastScale()); if ( bornPDF == 0.0 ) return ZERO; xme2 *= bornPDF; xme2 *= dipole()->realEmissionME()->finalStateSymmetry() / dipole()->underlyingBornME()->finalStateSymmetry(); // take care of mismatch between z and x as we are approaching the // hard phase space boundary // TODO get rid of this useless scale option business and simplify PDF handling in here if ( dipole()->bornEmitter() < 2 && theCorrectForXZMismatch ) { Energy2 emissionScale = ZERO; if ( emissionScaleInSubtraction() == showerScale ) { emissionScale = showerFactorizationScale(); } else if ( emissionScaleInSubtraction() == realScale ) { emissionScale = dipole()->realEmissionME()->lastScale(); } else if ( emissionScaleInSubtraction() == bornScale ) { emissionScale = dipole()->underlyingBornME()->lastScale(); } double xzMismatch = dipole()->subtractionParameters()[0] / dipole()->showerParameters()[0]; double realCorrectedPDF = dipole()->bornEmitter() == 0 ? dipole()->realEmissionME()->pdf1(emissionScale,theExtrapolationX, xzMismatch) : dipole()->realEmissionME()->pdf2(emissionScale,theExtrapolationX, xzMismatch); double realPDF = dipole()->bornEmitter() == 0 ? dipole()->realEmissionME()->pdf1(emissionScale,theExtrapolationX,1.0) : dipole()->realEmissionME()->pdf2(emissionScale,theExtrapolationX,1.0); if ( realPDF == 0.0 || realCorrectedPDF == 0.0 ) return ZERO; xme2 *= realCorrectedPDF / realPDF; } Energy qtilde = sqrt(vars.first); double z = vars.second; Energy2 pt2 = ZERO; const vector & masses = theQTildeSudakov->virtualMasses({{ bornCXComb()->mePartonData()[dipole()->bornEmitter() ], realCXComb()->mePartonData()[dipole()->realEmitter() ], realCXComb()->mePartonData()[dipole()->realEmission()] }}); const Energy2 m22 = sqr(masses[2]); if ( dipole()->bornEmitter() > 1 ) { const Energy2 m02 = sqr(masses[0]); const Energy2 m12 = sqr(masses[1]); pt2 = QTildeKinematics::pT2_FSR(sqr(qtilde),z,m02,m12,m22,m12,m22); } else { pt2 = QTildeKinematics::pT2_ISR(sqr(qtilde),z,m22); } assert(pt2 >= ZERO); if ( profileScales() ) xme2 *= profileScales()->hardScaleProfile(dipole()->showerHardScale(),sqrt(pt2)); CrossSection res = sqr(hbarc) * realXComb()->jacobian() * subtractionScaleWeight() * xme2 / (2. * realXComb()->lastSHat()); return res; } double QTildeMatching::me2() const { throw Exception() << "QTildeMatching::me2(): Not intented to use. Disable the ShowerApproximationGenerator." << Exception::runerror; return 0.; } void QTildeMatching::calculateShowerVariables() const { Lorentz5Momentum n; Energy2 Q2 = ZERO; const Lorentz5Momentum& pb = bornCXComb()->meMomenta()[dipole()->bornEmitter()]; const Lorentz5Momentum& pc = bornCXComb()->meMomenta()[dipole()->bornSpectator()]; if ( dipole()->bornEmitter() > 1 ) { Q2 = (pb+pc).m2(); } else { Q2 = -(pb-pc).m2(); } if ( dipole()->bornEmitter() > 1 && dipole()->bornSpectator() > 1 ) { double b = sqr(bornCXComb()->meMomenta()[dipole()->bornEmitter()].m())/Q2; double c = sqr(bornCXComb()->meMomenta()[dipole()->bornSpectator()].m())/Q2; double lambda = sqrt(1.+sqr(b)+sqr(c)-2.*b-2.*c-2.*b*c); n = (1.-0.5*(1.-b+c-lambda))*pc - 0.5*(1.-b+c-lambda)*pb; } if ( dipole()->bornEmitter() > 1 && dipole()->bornSpectator() < 2 ) { n = bornCXComb()->meMomenta()[dipole()->bornSpectator()]; } if ( dipole()->bornEmitter() < 2 && dipole()->bornSpectator() > 1 ) { double c = sqr(bornCXComb()->meMomenta()[dipole()->bornSpectator()].m())/Q2; n = (1.+c)*pc - c*pb; } if ( dipole()->bornEmitter() < 2 && dipole()->bornSpectator() < 2 ) { n = bornCXComb()->meMomenta()[dipole()->bornSpectator()]; } // the light-cone condition is numerically not very stable, so we // explicitly push it on the light-cone here n.setMass(ZERO); n.rescaleEnergy(); double z = 0.0; if ( dipole()->bornEmitter() > 1 ) { z = 1. - (n*realCXComb()->meMomenta()[dipole()->realEmission()])/ (n*bornCXComb()->meMomenta()[dipole()->bornEmitter()]); } else { z = 1. - (n*realCXComb()->meMomenta()[dipole()->realEmission()])/ (n*realCXComb()->meMomenta()[dipole()->realEmitter()]); } // allow small violations (numerical inaccuracies) if ( z <= 0 && z >= -1e-6 ) { z = std::numeric_limits::epsilon(); } else if ( z >= 1 && z <= 1+1e-6 ) { z = 1-std::numeric_limits::epsilon(); } Energy2 qtilde2 = ZERO; Energy2 q2 = ZERO; if ( dipole()->bornEmitter() > 1 ) { q2 = (realCXComb()->meMomenta()[dipole()->realEmitter()] + realCXComb()->meMomenta()[dipole()->realEmission()]).m2(); qtilde2 = (q2 - bornCXComb()->meMomenta()[dipole()->bornEmitter()].m2())/(z*(1.-z)); } else { q2 = -(realCXComb()->meMomenta()[dipole()->realEmitter()] - realCXComb()->meMomenta()[dipole()->realEmission()]).m2(); qtilde2 = (q2 + bornCXComb()->meMomenta()[dipole()->bornEmitter()].m2())/(1.-z); } if ( qtilde2 < ZERO ) { qtilde2 = ZERO; } assert(qtilde2 >= ZERO && z > 0.0 && z < 1.0); dipole()->showerScale(sqrt(qtilde2)); dipole()->showerParameters().resize(1); dipole()->showerParameters()[0] = z; } double QTildeMatching::splitFn(const pair& vars) const { const Energy2& qtilde2 = vars.first; const double z = vars.second; double Nc = SM().Nc(); // final state branching if ( dipole()->bornEmitter() > 1 ) { // final state quark quark branching if ( abs(bornCXComb()->mePartonData()[dipole()->bornEmitter()]->id()) < 7 ) { Energy m = bornCXComb()->mePartonData()[dipole()->bornEmitter()]->hardProcessMass(); return ((sqr(Nc)-1.)/(2.*Nc))*(1+sqr(z)-2.*sqr(m)/(z*qtilde2))/(1.-z); } // final state gluon branching if ( bornCXComb()->mePartonData()[dipole()->bornEmitter()]->id() == ParticleID::g ) { if ( realCXComb()->mePartonData()[dipole()->realEmission()]->id() == ParticleID::g ) { // ATTENTION the factor 2 here is intentional as it cancels to the 1/2 // stemming from the large-N colour correlator return 2.*Nc*(z/(1.-z)+(1.-z)/z+z*(1.-z)); } if ( abs(realCXComb()->mePartonData()[dipole()->realEmission()]->id()) < 7 ) { Energy m = realCXComb()->mePartonData()[dipole()->realEmission()]->hardProcessMass(); return (1./2.)*(1.-2.*z*(1.-z)+2.*sqr(m)/(z*(1.-z)*qtilde2)); } } // final state squark branching if ((abs(bornCXComb()->mePartonData()[dipole()->bornEmitter()]->id()) > 1000000 && abs(bornCXComb()->mePartonData()[dipole()->bornEmitter()]->id()) < 1000007) || (abs(bornCXComb()->mePartonData()[dipole()->bornEmitter()]->id()) > 2000000 && abs(bornCXComb()->mePartonData()[dipole()->bornEmitter()]->id()) < 2000007)){ Energy m = bornCXComb()->mePartonData()[dipole()->bornEmitter()]->hardProcessMass(); return ((sqr(Nc)-1.)/Nc)*(z-sqr(m)/(z*qtilde2))/(1.-z); } // final state gluino branching if (bornCXComb()->mePartonData()[dipole()->bornEmitter()]->id() == 1000021){ Energy m = bornCXComb()->mePartonData()[dipole()->bornEmitter()]->hardProcessMass(); return Nc*(1.+sqr(z)-2.*sqr(m)/(z*qtilde2))/(1.-z); } } // initial state branching if ( dipole()->bornEmitter() < 2 ) { // g/g if ( realCXComb()->mePartonData()[dipole()->realEmitter()]->id() == ParticleID::g && realCXComb()->mePartonData()[dipole()->realEmission()]->id() == ParticleID::g ) { // see above for factor of 2 return 2.*Nc*(z/(1.-z)+(1.-z)/z+z*(1.-z)); } // q/q if ( abs(realCXComb()->mePartonData()[dipole()->realEmitter()]->id()) < 7 && realCXComb()->mePartonData()[dipole()->realEmission()]->id() == ParticleID::g ) { return ((sqr(Nc)-1.)/(2.*Nc))*(1+sqr(z))/(1.-z); } // g/q if ( realCXComb()->mePartonData()[dipole()->realEmitter()]->id() == ParticleID::g && abs(realCXComb()->mePartonData()[dipole()->realEmission()]->id()) < 7 ) { return (1./2.)*(1.-2.*z*(1.-z)); } // q/g if ( abs(realCXComb()->mePartonData()[dipole()->realEmitter()]->id()) < 7 && abs(realCXComb()->mePartonData()[dipole()->realEmission()]->id()) < 7 ) { return ((sqr(Nc)-1.)/(2.*Nc))*(1+sqr(1.-z))/z; } } return 0.0; } // If needed, insert default implementations of virtual function defined // in the InterfacedBase class here (using ThePEG-interfaced-impl in Emacs). void QTildeMatching::doinit() { assert(theShowerHandler && theQTildeFinder && theQTildeSudakov); theShowerHandler->init(); theQTildeFinder->init(); theQTildeSudakov->init(); hardScaleFactor(theShowerHandler->hardScaleFactor()); factorizationScaleFactor(theShowerHandler->factorizationScaleFactor()); renormalizationScaleFactor(theShowerHandler->renormalizationScaleFactor()); profileScales(theShowerHandler->profileScales()); restrictPhasespace(theShowerHandler->restrictPhasespace()); hardScaleIsMuF(theShowerHandler->hardScaleIsMuF()); ShowerApproximation::doinit(); } void QTildeMatching::doinitrun() { assert(theShowerHandler && theQTildeFinder && theQTildeSudakov); theShowerHandler->initrun(); theQTildeFinder->initrun(); theQTildeSudakov->initrun(); ShowerApproximation::doinitrun(); } void QTildeMatching::persistentOutput(PersistentOStream & os) const { os << theQTildeFinder << theQTildeSudakov << theShowerHandler << theCorrectForXZMismatch; } void QTildeMatching::persistentInput(PersistentIStream & is, int) { is >> theQTildeFinder >> theQTildeSudakov >> theShowerHandler >> theCorrectForXZMismatch; } // *** 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 describeHerwigQTildeMatching("Herwig::QTildeMatching", "HwShower.so HwQTildeMatching.so"); void QTildeMatching::Init() { static ClassDocumentation documentation ("QTildeMatching implements NLO matching with the default shower."); static Reference interfaceQTildeFinder ("QTildeFinder", "Set the partner finder to calculate hard scales.", &QTildeMatching::theQTildeFinder, false, false, true, false, false); interfaceQTildeFinder.rank(-1); static Reference interfaceQTildeSudakov ("QTildeSudakov", "Set the partner finder to calculate hard scales.", &QTildeMatching::theQTildeSudakov, false, false, true, false, false); interfaceQTildeSudakov.rank(-1); static Reference interfaceShowerHandler ("ShowerHandler", "The QTilde shower handler to use.", &QTildeMatching::theShowerHandler, false, false, true, true, false); interfaceShowerHandler.rank(-1); static Switch interfaceCorrectForXZMismatch ("CorrectForXZMismatch", "Correct for x/z mismatch near hard phase space boundary.", &QTildeMatching::theCorrectForXZMismatch, true, false, false); static SwitchOption interfaceCorrectForXZMismatchYes (interfaceCorrectForXZMismatch, "Yes", "Include the correction factor.", true); static SwitchOption interfaceCorrectForXZMismatchNo (interfaceCorrectForXZMismatch, "No", "Do not include the correction factor.", false); interfaceCorrectForXZMismatch.rank(-1); } diff --git a/MatrixElement/Matchbox/Matching/QTildeMatching.h b/MatrixElement/Matchbox/Matching/QTildeMatching.h --- a/MatrixElement/Matchbox/Matching/QTildeMatching.h +++ b/MatrixElement/Matchbox/Matching/QTildeMatching.h @@ -1,201 +1,193 @@ // -*- C++ -*- // // QTildeMatching.h is a part of Herwig - A multi-purpose Monte Carlo event generator // Copyright (C) 2002-2019 The Herwig Collaboration // // Herwig is licenced under version 3 of the GPL, see COPYING for details. // Please respect the MCnet academic guidelines, see GUIDELINES for details. // #ifndef Herwig_QTildeMatching_H #define Herwig_QTildeMatching_H // // This is the declaration of the QTildeMatching class. // #include "Herwig/MatrixElement/Matchbox/Matching/ShowerApproximation.h" #include "Herwig/Shower/ShowerHandler.h" #include "Herwig/Shower/QTilde/Base/PartnerFinder.h" #include "Herwig/Shower/QTilde/SplittingFunctions/SudakovFormFactor.h" namespace Herwig { using namespace ThePEG; /** * \ingroup Matchbox * \author Simon Platzer * * \brief QTildeMatching implements NLO matching with the default shower. * */ class QTildeMatching: public Herwig::ShowerApproximation { public: - /** @name Standard constructors and destructors. */ - //@{ /** * The default constructor. */ QTildeMatching(); - /** - * The destructor. - */ - virtual ~QTildeMatching(); - //@} - public: /** * Return the shower approximation to the real emission cross * section for the given pair of Born and real emission * configurations. */ virtual CrossSection dSigHatDR() const; /** * Return the shower approximation splitting kernel for the given * pair of Born and real emission configurations in units of the * Born center of mass energy squared, and including a weight to * project onto the splitting given by the dipole used. */ virtual double me2() const; /** * Determine if the configuration is below or above the cutoff. */ virtual void checkCutoff(); /** * Determine all kinematic variables which are not provided by the * dipole kinematics; store all shower variables in the respective * dipole object for later use. */ virtual void getShowerVariables(); protected: /** * Return true, if the shower was able to generate an emission * leading from the given Born to the given real emission process. */ virtual bool isInShowerPhasespace() const; /** * Return true, if the shower emission leading from the given Born * to the given real emission process would have been generated * above the shower's infrared cutoff. */ virtual bool isAboveCutoff() const; /** * Calculate qtilde^2 and z for the splitting considered */ void calculateShowerVariables() const; /** * Return the splitting function as a function of the kinematic * variables */ double splitFn(const pair&) 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). protected: /** @name Standard Interfaced functions. */ //@{ /** * Initialize this object after the setup phase before saving an * EventGenerator to disk. * @throws InitException if object could not be initialized properly. */ virtual void doinit(); /** * Initialize this object. Called in the run phase just before * a run begins. */ virtual void doinitrun(); //@} private: /** * The assignment operator is private and must never be called. * In fact, it should not even be implemented. */ QTildeMatching & operator=(const QTildeMatching &) = delete; /** * The shower handler to be used */ Ptr::ptr theShowerHandler; /** * The qtilde partner finder for calculating the hard scales */ Ptr::ptr theQTildeFinder; /** * The qtilde Sudakov to access the cutoff */ Ptr::ptr theQTildeSudakov; /** * True, if PDF weight should be corrected for z/x mismatch at the * hard phase space boundary */ bool theCorrectForXZMismatch; }; } #endif /* Herwig_QTildeMatching_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,718 +1,716 @@ // -*- C++ -*- // // ShowerApproximation.cc is a part of Herwig - A multi-purpose Monte Carlo event generator // Copyright (C) 2002-2019 The Herwig Collaboration // // Herwig is licenced under version 3 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/Reference.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" #include "Herwig/MatrixElement/Matchbox/Phasespace/TildeKinematics.h" #include "Herwig/MatrixElement/Matchbox/Phasespace/InvertedTildeKinematics.h" using namespace Herwig; ShowerApproximation::ShowerApproximation() : HandlerBase(), theExtrapolationX(1.0), theBelowCutoff(false), theFFPtCut(1.0*GeV), theFFScreeningScale(ZERO), theFIPtCut(1.0*GeV), theFIScreeningScale(ZERO), theIIPtCut(1.0*GeV), theIIScreeningScale(ZERO), theSafeCut(0.0*GeV), theRestrictPhasespace(true), theHardScaleFactor(1.0), theRenormalizationScaleFactor(1.0), theFactorizationScaleFactor(1.0), theRealEmissionScaleInSubtraction(showerScale), theBornScaleInSubtraction(showerScale), theEmissionScaleInSubtraction(showerScale), theRealEmissionScaleInSplitting(showerScale), theBornScaleInSplitting(showerScale), theEmissionScaleInSplitting(showerScale), theRenormalizationScaleFreeze(1.*GeV), theFactorizationScaleFreeze(1.*GeV), maxPtIsMuF(false), theOpenZ(true) {} -ShowerApproximation::~ShowerApproximation() {} - void ShowerApproximation::setLargeNBasis() { assert(dipole()->realEmissionME()->matchboxAmplitude()); if ( !dipole()->realEmissionME()->matchboxAmplitude()->treeAmplitudes() ) return; if ( !theLargeNBasis ) { if ( !dipole()->realEmissionME()->matchboxAmplitude()->colourBasis() ) throw Exception() << "ShowerApproximation::setLargeNBasis(): Expecting a colour basis object." << Exception::runerror; theLargeNBasis = dipole()->realEmissionME()->matchboxAmplitude()->colourBasis()->cloneMe(); theLargeNBasis->clear(); theLargeNBasis->doLargeN(); } } void ShowerApproximation::setDipole(Ptr::tptr dip) { theDipole = dip; setLargeNBasis(); } Ptr::tptr ShowerApproximation::dipole() const { return theDipole; } Ptr::tptr ShowerApproximation::showerTildeKinematics() const { return Ptr::tptr(); } Ptr::tptr ShowerApproximation::showerInvertedTildeKinematics() const { return Ptr::tptr(); } void ShowerApproximation::checkCutoff() { assert(!showerTildeKinematics()); } void ShowerApproximation::getShowerVariables() { // check for the cutoff dipole()->isAboveCutoff(isAboveCutoff()); // get the hard scale dipole()->showerHardScale(hardScale()); // set the shower scale and variables for completeness dipole()->showerScale(dipole()->lastPt()); dipole()->showerParameters().resize(1); dipole()->showerParameters()[0] = dipole()->lastZ(); // check for phase space dipole()->isInShowerPhasespace(isInShowerPhasespace()); } bool ShowerApproximation::isAboveCutoff() const { if ( dipole()->bornEmitter() > 1 && dipole()->bornSpectator() > 1 ) { return dipole()->lastPt() >= max(ffPtCut(),safeCut()); } else if ( ( dipole()->bornEmitter() > 1 && dipole()->bornSpectator() < 2 ) || ( dipole()->bornEmitter() < 2 && dipole()->bornSpectator() > 1 ) ) { return dipole()->lastPt() >= max(fiPtCut(),safeCut()); } else { assert(dipole()->bornEmitter() < 2 && dipole()->bornSpectator() < 2); return dipole()->lastPt() >= max(iiPtCut(),safeCut()); } return true; } Energy ShowerApproximation::hardScale() const { if ( !maxPtIsMuF ) { 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::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->mt()); if ( maxPt == generator()->maximumCMEnergy() ) maxPt = (bornCXComb()->meMomenta()[0] + bornCXComb()->meMomenta()[1]).m(); maxPt *= hardScaleFactor(); return maxPt; } else { return hardScaleFactor()*sqrt(bornCXComb()->lastShowerScale()); } } bool ShowerApproximation::isInShowerPhasespace() const { if ( !dipole()->isAboveCutoff() ) return false; if ( !restrictPhasespace() ) return true; InvertedTildeKinematics& kinematics = const_cast(*dipole()->invertedTildeKinematics()); tcStdXCombPtr tmpreal = kinematics.realXComb(); tcStdXCombPtr tmpborn = kinematics.bornXComb(); Ptr::tptr tmpdip = kinematics.dipole(); Energy hard = dipole()->showerHardScale(); Energy pt = dipole()->lastPt(); double z = dipole()->lastZ(); pair zbounds(0.,1.); kinematics.dipole(const_ptr_cast::tptr>(theDipole)); kinematics.prepare(realCXComb(),bornCXComb()); if ( pt > hard ) { kinematics.dipole(tmpdip); kinematics.prepare(tmpreal,tmpborn); return false; } try { zbounds = kinematics.zBounds(pt,openZ() ? kinematics.ptMax() : hard); } catch(...) { kinematics.dipole(tmpdip); kinematics.prepare(tmpreal,tmpborn); throw; } kinematics.dipole(tmpdip); kinematics.prepare(tmpreal,tmpborn); return z > zbounds.first && z < zbounds.second; } 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 ( abs(bornPDF) < 1e-8 ) bornPDF = 0.0; if ( abs(emissionPDF) < 1e-8 ) emissionPDF = 0.0; if ( emissionPDF == 0.0 || bornPDF == 0.0 ) return 0.0; double pdfRatio = emissionPDF/bornPDF; pdfRatio = min(abs(pdfRatio),100000.); return emissionAlpha * pdfRatio * couplingFactor; } double ShowerApproximation::channelWeight(int emitter, int emission, int spectator, int) const { double cfac = 1.; double Nc = generator()->standardModel()->Nc(); if (realCXComb()->mePartonData()[emitter]->iColour() == PDT::Colour8){ if (realCXComb()->mePartonData()[emission]->iColour() == PDT::Colour8) cfac = Nc; else if ( realCXComb()->mePartonData()[emission]->iColour() == PDT::Colour3 || realCXComb()->mePartonData()[emission]->iColour() == PDT::Colour3bar) cfac = 0.5; else assert(false); } else if ((realCXComb()->mePartonData()[emitter] ->iColour() == PDT::Colour3 || realCXComb()->mePartonData()[emitter] ->iColour() == PDT::Colour3bar)) cfac = (sqr(Nc)-1.)/(2.*Nc); else assert(false); // do the most simple thing for the time being; needs fixing later if ( realCXComb()->mePartonData()[emission]->id() == ParticleID::g ) { Energy2 pipk = realCXComb()->meMomenta()[emitter] * realCXComb()->meMomenta()[spectator]; Energy2 pipj = realCXComb()->meMomenta()[emitter] * realCXComb()->meMomenta()[emission]; Energy2 pjpk = realCXComb()->meMomenta()[emission] * realCXComb()->meMomenta()[spectator]; return cfac *GeV2 * pipk / ( pipj * ( pipj + pjpk ) ); } return cfac * GeV2 / (realCXComb()->meMomenta()[emitter] * realCXComb()->meMomenta()[emission]); } double ShowerApproximation::channelWeight() const { double currentChannel = channelWeight(dipole()->realEmitter(), dipole()->realEmission(), dipole()->realSpectator(), dipole()->bornEmitter()); if ( currentChannel == 0. ) return 0.; double sum = 0.; for ( vector::tptr>::const_iterator dip = dipole()->partnerDipoles().begin(); dip != dipole()->partnerDipoles().end(); ++dip ) sum += channelWeight((**dip).realEmitter(), (**dip).realEmission(), (**dip).realSpectator(), (**dip).bornEmitter()); assert(sum > 0.0); return currentChannel / sum; } // If needed, insert default implementations of virtual function defined // in the InterfacedBase class here (using ThePEG-interfaced-impl in Emacs). void ShowerApproximation::doinit() { if ( profileScales() ) { if ( profileScales()->unrestrictedPhasespace() && restrictPhasespace() ) { generator()->log() << "ShowerApproximation warning: The scale profile chosen requires an unrestricted phase space,\n" << "however, the phase space was set to be restricted. Will switch to unrestricted phase space.\n" << flush; restrictPhasespace(false); } } HandlerBase::doinit(); } void ShowerApproximation::persistentOutput(PersistentOStream & os) const { os << theLargeNBasis << theBornXComb << theRealXComb << theTildeXCombs << theDipole << theBelowCutoff << ounit(theFFPtCut,GeV) << ounit(theFFScreeningScale,GeV) << ounit(theFIPtCut,GeV) << ounit(theFIScreeningScale,GeV) << ounit(theIIPtCut,GeV) << ounit(theIIScreeningScale,GeV) << ounit(theSafeCut,GeV) << theRestrictPhasespace << theHardScaleFactor << theRenormalizationScaleFactor << theFactorizationScaleFactor << theExtrapolationX << theRealEmissionScaleInSubtraction << theBornScaleInSubtraction << theEmissionScaleInSubtraction << theRealEmissionScaleInSplitting << theBornScaleInSplitting << theEmissionScaleInSplitting << ounit(theRenormalizationScaleFreeze,GeV) << ounit(theFactorizationScaleFreeze,GeV) << maxPtIsMuF << theHardScaleProfile << theOpenZ; } void ShowerApproximation::persistentInput(PersistentIStream & is, int) { is >> theLargeNBasis >> theBornXComb >> theRealXComb >> theTildeXCombs >> theDipole >> theBelowCutoff >> iunit(theFFPtCut,GeV) >> iunit(theFFScreeningScale,GeV) >> iunit(theFIPtCut,GeV) >> iunit(theFIScreeningScale,GeV) >> iunit(theIIPtCut,GeV) >> iunit(theIIScreeningScale,GeV) >> iunit(theSafeCut,GeV) >> theRestrictPhasespace >> theHardScaleFactor >> theRenormalizationScaleFactor >> theFactorizationScaleFactor >> theExtrapolationX >> theRealEmissionScaleInSubtraction >> theBornScaleInSubtraction >> theEmissionScaleInSubtraction >> theRealEmissionScaleInSplitting >> theBornScaleInSplitting >> theEmissionScaleInSplitting >> iunit(theRenormalizationScaleFreeze,GeV) >> iunit(theFactorizationScaleFreeze,GeV) >> maxPtIsMuF >> theHardScaleProfile >> theOpenZ; } // *** 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 describeHerwigShowerApproximation("Herwig::ShowerApproximation", "Herwig.so"); void ShowerApproximation::Init() { static ClassDocumentation documentation ("ShowerApproximation describes the shower emission to be used " "in NLO matching."); static Parameter interfaceFFPtCut ("FFPtCut", "Set the pt infrared cutoff", &ShowerApproximation::theFFPtCut, GeV, 1.0*GeV, 0.0*GeV, 0*GeV, false, false, Interface::lowerlim); static Parameter interfaceFIPtCut ("FIPtCut", "Set the pt infrared cutoff", &ShowerApproximation::theFIPtCut, GeV, 1.0*GeV, 0.0*GeV, 0*GeV, false, false, Interface::lowerlim); static Parameter interfaceIIPtCut ("IIPtCut", "Set the pt infrared cutoff", &ShowerApproximation::theIIPtCut, GeV, 1.0*GeV, 0.0*GeV, 0*GeV, false, false, Interface::lowerlim); static Parameter interfaceSafeCut ("SafeCut", "Set the enhanced infrared cutoff for the Matching.", &ShowerApproximation::theSafeCut, GeV, 0.0*GeV, 0.0*GeV, 0*GeV, false, false, Interface::lowerlim); static Parameter interfaceFFScreeningScale ("FFScreeningScale", "Set the screening scale", &ShowerApproximation::theFFScreeningScale, GeV, 0.0*GeV, 0.0*GeV, 0*GeV, false, false, Interface::lowerlim); static Parameter interfaceFIScreeningScale ("FIScreeningScale", "Set the screening scale", &ShowerApproximation::theFIScreeningScale, GeV, 0.0*GeV, 0.0*GeV, 0*GeV, false, false, Interface::lowerlim); static Parameter interfaceIIScreeningScale ("IIScreeningScale", "Set the screening scale", &ShowerApproximation::theIIScreeningScale, GeV, 0.0*GeV, 0.0*GeV, 0*GeV, false, false, Interface::lowerlim); static Switch interfaceRestrictPhasespace ("RestrictPhasespace", "Switch on or off phasespace restrictions", &ShowerApproximation::theRestrictPhasespace, true, false, false); static SwitchOption interfaceRestrictPhasespaceYes (interfaceRestrictPhasespace, "Yes", "Perform phasespace restrictions", true); static SwitchOption interfaceRestrictPhasespaceNo (interfaceRestrictPhasespace, "No", "Do not perform phasespace restrictions", false); static Parameter interfaceHardScaleFactor ("HardScaleFactor", "The hard scale factor.", &ShowerApproximation::theHardScaleFactor, 1.0, 0.0, 0, false, false, Interface::lowerlim); static Parameter interfaceRenormalizationScaleFactor ("RenormalizationScaleFactor", "The hard scale factor.", &ShowerApproximation::theRenormalizationScaleFactor, 1.0, 0.0, 0, false, false, Interface::lowerlim); static Parameter interfaceFactorizationScaleFactor ("FactorizationScaleFactor", "The hard scale factor.", &ShowerApproximation::theFactorizationScaleFactor, 1.0, 0.0, 0, false, false, Interface::lowerlim); static Parameter interfaceExtrapolationX ("ExtrapolationX", "The x from which on extrapolation should be performed.", &ShowerApproximation::theExtrapolationX, 1.0, 0.0, 1.0, false, false, Interface::limited); static Switch 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); interfaceRealEmissionScaleInSubtraction.rank(-1); static Switch 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); interfaceBornScaleInSubtraction.rank(-1); static Switch 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); interfaceEmissionScaleInSubtraction.rank(-1); static Switch 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); interfaceRealEmissionScaleInSplitting.rank(-1); static Switch 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); interfaceBornScaleInSplitting.rank(-1); static Switch 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); interfaceEmissionScaleInSplitting.rank(-1); static Parameter interfaceRenormalizationScaleFreeze ("RenormalizationScaleFreeze", "The freezing scale for the renormalization scale.", &ShowerApproximation::theRenormalizationScaleFreeze, GeV, 1.0*GeV, 0.0*GeV, 0*GeV, false, false, Interface::lowerlim); interfaceRenormalizationScaleFreeze.rank(-1); static Parameter interfaceFactorizationScaleFreeze ("FactorizationScaleFreeze", "The freezing scale for the factorization scale.", &ShowerApproximation::theFactorizationScaleFreeze, GeV, 1.0*GeV, 0.0*GeV, 0*GeV, false, false, Interface::lowerlim); interfaceFactorizationScaleFreeze.rank(-1); static Reference interfaceHardScaleProfile ("HardScaleProfile", "The hard scale profile to use.", &ShowerApproximation::theHardScaleProfile, false, false, true, true, false); static Reference interfaceLargeNBasis ("LargeNBasis", "Set the large-N colour basis implementation.", &ShowerApproximation::theLargeNBasis, false, false, true, true, false); interfaceLargeNBasis.rank(-1); static Switch interfaceMaxPtIsMuF ("MaxPtIsMuF", "", &ShowerApproximation::maxPtIsMuF, false, false, false); static SwitchOption interfaceMaxPtIsMuFYes (interfaceMaxPtIsMuF, "Yes", "", true); static SwitchOption interfaceMaxPtIsMuFNo (interfaceMaxPtIsMuF, "No", "", false); } diff --git a/MatrixElement/Matchbox/Matching/ShowerApproximation.h b/MatrixElement/Matchbox/Matching/ShowerApproximation.h --- a/MatrixElement/Matchbox/Matching/ShowerApproximation.h +++ b/MatrixElement/Matchbox/Matching/ShowerApproximation.h @@ -1,691 +1,683 @@ // -*- C++ -*- // // ShowerApproximation.h is a part of Herwig - A multi-purpose Monte Carlo event generator // Copyright (C) 2002-2019 The Herwig Collaboration // // Herwig is licenced under version 3 of the GPL, see COPYING for details. // Please respect the MCnet academic guidelines, see GUIDELINES for details. // #ifndef Herwig_ShowerApproximation_H #define Herwig_ShowerApproximation_H // // This is the declaration of the ShowerApproximation class. // #include "ThePEG/Handlers/HandlerBase.h" #include "ThePEG/Handlers/StandardXComb.h" #include "Herwig/MatrixElement/Matchbox/Dipoles/SubtractionDipole.fh" #include "Herwig/MatrixElement/Matchbox/Utility/ColourBasis.h" #include "Herwig/MatrixElement/Matchbox/Phasespace/TildeKinematics.fh" #include "Herwig/MatrixElement/Matchbox/Phasespace/InvertedTildeKinematics.fh" #include "HardScaleProfile.h" namespace Herwig { using namespace ThePEG; /** * \ingroup Matchbox * \author Simon Platzer * * \brief ShowerApproximation describes the shower emission to be used * in NLO matching. * */ class ShowerApproximation: public HandlerBase { public: - /** @name Standard constructors and destructors. */ - //@{ /** * The default constructor. */ ShowerApproximation(); - /** - * The destructor. - */ - virtual ~ShowerApproximation(); - //@} - public: /** * Return true, if this shower approximation will require a * splitting generator */ virtual bool needsSplittingGenerator() const { return false; } /** * Return true, if this shower approximation will require * H events */ virtual bool hasHEvents() const { return true; } /** * Return true, if this shower approximation will require tilde * XCombs for the real phase space point generated */ virtual bool needsTildeXCombs() const { return false; } /** * Return true, if this shower approximation will require * a truncated parton shower */ virtual bool needsTruncatedShower() const { return false; } /** * Return the tilde kinematics object returning the shower * kinematics parametrization if different from the nominal dipole * mappings. */ virtual Ptr::tptr showerTildeKinematics() const; /** * Return the tilde kinematics object returning the shower * kinematics parametrization if different from the nominal dipole * mappings. */ virtual Ptr::tptr showerInvertedTildeKinematics() const; public: /** * Set the XComb object describing the Born process */ void setBornXComb(tStdXCombPtr xc) { theBornXComb = xc; } /** * Return the XComb object describing the Born process */ tStdXCombPtr bornXComb() const { return theBornXComb; } /** * Return the XComb object describing the Born process */ tcStdXCombPtr bornCXComb() const { return theBornXComb; } /** * Set the XComb object describing the real emission process */ void setRealXComb(tStdXCombPtr xc) { theRealXComb = xc; } /** * Return the XComb object describing the real emission process */ tStdXCombPtr realXComb() const { return theRealXComb; } /** * Return the XComb object describing the real emission process */ tcStdXCombPtr realCXComb() const { return theRealXComb; } /** * Set the tilde xcomb objects associated to the real xcomb */ void setTildeXCombs(const vector& xc) { theTildeXCombs = xc; } /** * Return the tilde xcomb objects associated to the real xcomb */ const vector& tildeXCombs() const { return theTildeXCombs; } /** * Set the dipole in charge for the emission */ void setDipole(Ptr::tptr); /** * Return the dipole in charge for the emission */ Ptr::tptr dipole() const; /** * Return true, if this matching is capable of spin correlations. */ virtual bool hasSpinCorrelations() const { return false; } public: /** * Return true if one of the recently encountered configutations was * below the infrared cutoff. */ bool belowCutoff() const { return theBelowCutoff; } /** * Indicate that one of the recently encountered configutations was * below the infrared cutoff. */ void wasBelowCutoff() { theBelowCutoff = true; } /** * Reset the below cutoff flag. */ void resetBelowCutoff() { theBelowCutoff = false; } /** * Return the pt cut to be applied for final-final dipoles. */ Energy ffPtCut() const { return theFFPtCut; } /** * Return the pt cut to be applied for final-initial dipoles. */ Energy fiPtCut() const { return theFIPtCut; } /** * Return the pt cut to be applied for initial-initial dipoles. */ Energy iiPtCut() const { return theIIPtCut; } /** * Return the pt cut to be applied for initial-initial dipoles. */ Energy safeCut() const { return theSafeCut;} /** * Return the screening scale to be applied for final-final dipoles. */ Energy ffScreeningScale() const { return theFFScreeningScale; } /** * Return the screening scale to be applied for final-initial dipoles. */ Energy fiScreeningScale() const { return theFIScreeningScale; } /** * Return the screening scale to be applied for initial-initial dipoles. */ Energy iiScreeningScale() const { return theIIScreeningScale; } /** * Return the shower renormalization scale */ virtual Energy2 showerEmissionScale() const; /** * Return the shower renormalization scale */ Energy2 showerRenormalizationScale() const { return sqr(renormalizationScaleFactor())*showerEmissionScale(); } /** * Return the shower factorization scale */ Energy2 showerFactorizationScale() const { return sqr(factorizationScaleFactor())*showerEmissionScale(); } /** * Return the Born renormalization scale */ Energy2 bornRenormalizationScale() const; /** * Return the Born factorization scale */ Energy2 bornFactorizationScale() const; /** * Return the real emission renormalization scale */ Energy2 realRenormalizationScale() const; /** * Return the real emission factorization scale */ Energy2 realFactorizationScale() const; /** * Enumerate possible scale choices */ enum ScaleChoices { bornScale = 0, /** Use the born scales */ realScale = 1, /** Use the real scales */ showerScale = 2 /** Use the shower scales */ }; /** * Return the scale choice in the real emission cross section to be * used in the matching subtraction. */ int realEmissionScaleInSubtraction() const { return theRealEmissionScaleInSubtraction; } /** * Return the scale choice in the born cross section to be * used in the matching subtraction. */ int bornScaleInSubtraction() const { return theBornScaleInSubtraction; } /** * Return the scale choice in the emission contribution to be * used in the matching subtraction. */ int emissionScaleInSubtraction() const { return theEmissionScaleInSubtraction; } /** * Return the scale choice in the real emission cross section to be * used in the splitting. */ int realEmissionScaleInSplitting() const { return theRealEmissionScaleInSplitting; } /** * Return the scale choice in the born cross section to be * used in the splitting. */ int bornScaleInSplitting() const { return theBornScaleInSplitting; } /** * Return the scale choice in the emission contribution to be * used in the splitting. */ int emissionScaleInSplitting() const { return theEmissionScaleInSplitting; } /** * Return the scale weight */ double scaleWeight(int rScale, int bScale, int eScale) const; /** * Return the scale weight for the matching subtraction */ double subtractionScaleWeight() const { return scaleWeight(realEmissionScaleInSubtraction(), bornScaleInSubtraction(), emissionScaleInSubtraction()); } /** * Return the scale weight for the splitting */ double splittingScaleWeight() const { return scaleWeight(realEmissionScaleInSplitting(), bornScaleInSplitting(), emissionScaleInSplitting()); } public: /** * Return true, if the phase space restrictions of the dipole shower should * be applied. */ bool restrictPhasespace() const { return theRestrictPhasespace; } /** * Indicate that the phase space restrictions of the dipole shower should * be applied. */ void restrictPhasespace(bool yes) { theRestrictPhasespace = yes; } /** * Return profile scales */ Ptr::tptr profileScales() const { return theHardScaleProfile; } /** * Set profile scales */ void profileScales(Ptr::ptr prof) { theHardScaleProfile = prof; } /** * Return true if maximum pt should be deduced from the factorization scale */ bool hardScaleIsMuF() const { return maxPtIsMuF; } /** * Indicate that maximum pt should be deduced from the factorization scale */ void hardScaleIsMuF(bool yes) { maxPtIsMuF = yes; } /** * Return the scale factor for the hard scale */ double hardScaleFactor() const { return theHardScaleFactor; } /** * Set the scale factor for the hard scale */ void hardScaleFactor(double f) { theHardScaleFactor = f; } /** * Get the factorization scale factor */ double factorizationScaleFactor() const { return theFactorizationScaleFactor; } /** * Get the renormalization scale factor */ double renormalizationScaleFactor() const { return theRenormalizationScaleFactor; } /** * Set the factorization scale factor */ void factorizationScaleFactor(double f) { theFactorizationScaleFactor = f; } /** * Set the renormalization scale factor */ void renormalizationScaleFactor(double f) { theRenormalizationScaleFactor = f; } /** * Determine if the configuration is below or above the cutoff. */ virtual void checkCutoff(); /** * Determine all kinematic variables which are not provided by the * dipole kinematics; store all shower variables in the respective * dipole object for later use. */ virtual void getShowerVariables(); /** * Return the shower approximation to the real emission cross * section for the given pair of Born and real emission * configurations. */ virtual CrossSection dSigHatDR() const = 0; /** * Return the shower approximation splitting kernel for the given * pair of Born and real emission configurations in units of the * Born center of mass energy squared, and including a weight to * project onto the splitting given by the dipole used. */ virtual double me2() const = 0; /** * Return the Born PDF weight */ double bornPDFWeight(Energy2 muF) const; /** * Return the real emission PDF weight */ double realPDFWeight(Energy2 muF) const; protected: /** * Return true, if the shower was able to generate an emission * leading from the given Born to the given real emission process. */ virtual bool isInShowerPhasespace() const; /** * Return true, if the shower emission leading from the given Born * to the given real emission process would have been generated * above the shower's infrared cutoff. */ virtual bool isAboveCutoff() const; /** * Return the relevant hard scale */ virtual Energy hardScale() const; /** * Use the maximum available phase space for the momentum fraction */ void useOpenZ(bool yes) { theOpenZ = yes; } /** * Return true if the maximum available phase space should be used * for the momentum fraction */ bool openZ() const { return theOpenZ; } public: /** * Generate a weight for the given dipole channel */ virtual double channelWeight(int emitter, int emission, int spectator, int bemitter) const; /** * Generate a normalized weight taking into account all channels */ virtual double channelWeight() 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 Standard Interfaced functions. */ //@{ /** * Initialize this object after the setup phase before saving an * EventGenerator to disk. * @throws InitException if object could not be initialized properly. */ virtual void doinit(); //@} // If needed, insert declarations of virtual function defined in the // InterfacedBase class here (using ThePEG-interfaced-decl in Emacs). public: /** * A large-N colour basis to be used when reproducing the shower * kernels. */ Ptr::tptr largeNBasis() const { return theLargeNBasis; } protected: /** * A large-N colour basis to be used when reproducing the shower * kernels. */ Ptr::ptr theLargeNBasis; /** * Set the large-N basis */ void setLargeNBasis(); /** * The x value from which on we extrapolate PDFs for numerically stable ratios. */ double theExtrapolationX; private: /** * The XComb object describing the Born process */ tStdXCombPtr theBornXComb; /** * The XComb object describing the real emission process */ tStdXCombPtr theRealXComb; /** * The tilde xcomb objects associated to the real xcomb */ vector theTildeXCombs; /** * The dipole in charge for the emission */ Ptr::tptr theDipole; /** * True if one of the recently encountered configutations was below * the infrared cutoff. */ bool theBelowCutoff; /** * The pt cut to be applied for final-final dipoles. */ Energy theFFPtCut; /** * An optional screening scale for final-final dipoles; see * DipoleSplittingKernel */ Energy theFFScreeningScale; /** * The pt cut to be applied for final-initial dipoles. */ Energy theFIPtCut; /** * An optional screening scale for final-initial dipoles; see * DipoleSplittingKernel */ Energy theFIScreeningScale; /** * The pt cut to be applied for initial-initial dipoles. */ Energy theIIPtCut; /** * An optional screening scale for initial-initial dipoles; see * DipoleSplittingKernel */ Energy theIIScreeningScale; /** * The cut to be applied as an enhanced shower cutoff. */ Energy theSafeCut; /** * True, if the phase space restrictions of the dipole shower should * be applied. */ bool theRestrictPhasespace; /** * The scale factor for the hard scale */ double theHardScaleFactor; /** * The scale factor for the renormalization scale */ double theRenormalizationScaleFactor; /** * The scale factor for the factorization scale */ double theFactorizationScaleFactor; /** * The scale choice in the real emission cross section to be * used in the matching subtraction. */ int theRealEmissionScaleInSubtraction; /** * The scale choice in the born cross section to be * used in the matching subtraction. */ int theBornScaleInSubtraction; /** * The scale choice in the emission contribution to be * used in the matching subtraction. */ int theEmissionScaleInSubtraction; /** * The scale choice in the real emission cross section to be * used in the splitting. */ int theRealEmissionScaleInSplitting; /** * The scale choice in the born cross section to be * used in the splitting. */ int theBornScaleInSplitting; /** * The scale choice in the emission contribution to be * used in the splitting. */ int theEmissionScaleInSplitting; /** * A freezing value for the renormalization scale */ Energy theRenormalizationScaleFreeze; /** * A freezing value for the factorization scale */ Energy theFactorizationScaleFreeze; /** * True if maximum pt should be deduced from the factorization scale */ bool maxPtIsMuF; /** * The profile scales */ Ptr::ptr theHardScaleProfile; /** * Use the maximum available phase space for the momentum fraction */ bool theOpenZ; private: /** * The assignment operator is private and must never be called. * In fact, it should not even be implemented. */ ShowerApproximation & operator=(const ShowerApproximation &) = delete; }; } #endif /* Herwig_ShowerApproximation_H */ diff --git a/MatrixElement/Matchbox/Matching/ShowerApproximationGenerator.cc b/MatrixElement/Matchbox/Matching/ShowerApproximationGenerator.cc --- a/MatrixElement/Matchbox/Matching/ShowerApproximationGenerator.cc +++ b/MatrixElement/Matchbox/Matching/ShowerApproximationGenerator.cc @@ -1,527 +1,525 @@ // -*- C++ -*- // // ShowerApproximationGenerator.cc is a part of Herwig - A multi-purpose Monte Carlo event generator // Copyright (C) 2002-2019 The Herwig Collaboration // // Herwig is licenced under version 3 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 ShowerApproximationGenerator class. // #include #include "ShowerApproximationGenerator.h" #include "ThePEG/Interface/ClassDocumentation.h" #include "ThePEG/Interface/Reference.h" #include "ThePEG/Interface/Parameter.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 "ThePEG/PDT/EnumParticles.h" #include "ThePEG/PDF/PartonExtractor.h" #include "ThePEG/Cuts/Cuts.h" #include "ThePEG/Persistency/PersistentOStream.h" #include "ThePEG/Persistency/PersistentIStream.h" using namespace Herwig; ShowerApproximationGenerator::ShowerApproximationGenerator() : thePresamplingPoints(2000), theMaxTry(100000), theFreezeGrid(500000), theDoCompensate(false) {} -ShowerApproximationGenerator::~ShowerApproximationGenerator() {} - double ShowerApproximationGenerator::generateFraction(tcPDPtr pd, double r, double xmin) const { if ( pd->coloured() || pd->id() == ParticleID::gamma ) { return pow(xmin,r); } double x0 = 1.e-5; return 1. + x0 - x0*pow((1.+x0)/x0,r); } double ShowerApproximationGenerator::invertFraction(tcPDPtr pd, double x, double xmin) const { if ( pd->coloured() || pd->id() == ParticleID::gamma ) { return log(x)/log(xmin); } double x0 = 1.e-5; return log((1.-x+x0)/x0)/log((1.+x0)/x0); } bool ShowerApproximationGenerator::prepare(bool didproject) { tSubProPtr oldSub = lastIncomingXComb->subProcess(); tcStdXCombPtr cIncomingXC = lastIncomingXComb; bool hasFractions = thePhasespace->haveX1X2() || cIncomingXC->mePartonData().size() == 3; theLastMomenta.resize(cIncomingXC->mePartonData().size()); if ( !hasFractions ) theLastRandomNumbers.resize(thePhasespace->nDim(cIncomingXC->mePartonData()) + 2); else theLastRandomNumbers.resize(thePhasespace->nDim(cIncomingXC->mePartonData())); if ( !hasFractions ) { double x1 = oldSub->incoming().first->momentum().plus() / lastIncomingXComb->lastParticles().first->momentum().plus(); theLastRandomNumbers[0] = invertFraction(oldSub->incoming().first->dataPtr(),x1, lastIncomingXComb->cuts()->x1Min()); double x2 = oldSub->incoming().second->momentum().minus() / lastIncomingXComb->lastParticles().second->momentum().minus(); theLastRandomNumbers[1] = invertFraction(oldSub->incoming().second->dataPtr(),x2, lastIncomingXComb->cuts()->x2Min()); } theLastMomenta = cIncomingXC->meMomenta(); theLastPartons.first = oldSub->incoming().first->data().produceParticle(oldSub->incoming().first->momentum()); theLastPartons.second = oldSub->incoming().second->data().produceParticle(oldSub->incoming().second->momentum()); thePhasespace->setXComb(lastIncomingXComb); // this is a brute force fix for private ticket #241 ; only done to get fixed // for the release but will need to be looked at in more detail later on by // cleaning up the XCombs for these cases if ( theLastMomenta.size() == 3 && didproject ) { // boost them where they belong so invertKinematics is doing something sensible Boost toLab = (lastIncomingXComb->lastPartons().first->momentum() + lastIncomingXComb->lastPartons().second->momentum()).boostVector(); for ( int i = 0; i < 3; ++i ) theLastMomenta[i].boost(toLab); } thePhasespace->invertKinematics(theLastMomenta, !hasFractions ? &theLastRandomNumbers[2] : &theLastRandomNumbers[0]); theLastBornXComb->clean(); theLastBornXComb->fill(lastIncomingXComb->lastParticles(),theLastPartons, theLastMomenta,theLastRandomNumbers); if ( !theLastBornXComb->cuts()->initSubProcess(theLastBornXComb->lastSHat(), theLastBornXComb->lastY(), theLastBornXComb->mirror()) ) return false; theLastBornME->setXComb(theLastBornXComb); if ( !theLastBornME->generateKinematics(!hasFractions ? &theLastRandomNumbers[2] : &theLastRandomNumbers[0]) ) return false; CrossSection bornXS = theLastBornME->dSigHatDR(); if ( bornXS == ZERO ) return false; return true; } bool ShowerApproximationGenerator::generate(const vector& r) { theLastBornXComb->clean(); bool hasFractions = thePhasespace->haveX1X2() || theLastBornXComb->mePartonData().size() == 3; if ( !hasFractions ) { double x = generateFraction(theLastPartons.first->dataPtr(),r[0], lastIncomingXComb->cuts()->x1Min()); Energy Q = lastIncomingXComb->lastParticles().first->momentum().plus(); Energy mass = theLastPartons.first->dataPtr()->mass(); double xi = (sqr(x*Q) - sqr(mass))/(sqr(Q)*x); Lorentz5Momentum p1(ZERO,ZERO,xi*Q/2.); p1.setMass(mass); p1.rescaleEnergy(); theLastPartons.first->set5Momentum(p1); x = generateFraction(theLastPartons.second->dataPtr(),r[1], lastIncomingXComb->cuts()->x2Min()); Q = lastIncomingXComb->lastParticles().second->momentum().minus(); mass = theLastPartons.second->dataPtr()->mass(); xi = (sqr(x*Q) - sqr(mass))/(sqr(Q)*x); Lorentz5Momentum p2(ZERO,ZERO,-xi*Q/2.); p2.setMass(mass); p2.rescaleEnergy(); theLastPartons.second->set5Momentum(p2); } else { theLastBornME->setXComb(theLastBornXComb); theLastBornXComb->lastParticles(lastIncomingXComb->lastParticles()); theLastBornXComb->lastP1P2(make_pair(0.0, 0.0)); theLastBornXComb->lastS(lastIncomingXComb->lastS()); if ( !theLastBornME->generateKinematics(&r[0]) ) return false; theLastPartons.first->set5Momentum(theLastBornME->lastMEMomenta()[0]); theLastPartons.second->set5Momentum(theLastBornME->lastMEMomenta()[1]); } theLastPresamplingMomenta.resize(theLastMomenta.size()); Boost toCMS = (theLastPartons.first->momentum() + theLastPartons.second->momentum()).findBoostToCM(); theLastPresamplingMomenta[0] = theLastPartons.first->momentum(); if ( !hasFractions ) theLastPresamplingMomenta[0].boost(toCMS); theLastPresamplingMomenta[1] = theLastPartons.second->momentum(); if ( !hasFractions ) theLastPresamplingMomenta[1].boost(toCMS); if ( hasFractions ) { for ( size_t k = 2; k < theLastBornME->lastMEMomenta().size(); ++k ) theLastPresamplingMomenta[k] = theLastBornME->lastMEMomenta()[k]; } theLastBornXComb->fill(lastIncomingXComb->lastParticles(),theLastPartons, theLastPresamplingMomenta,r); if ( !theLastBornXComb->cuts()->initSubProcess(theLastBornXComb->lastSHat(), theLastBornXComb->lastY(), theLastBornXComb->mirror()) ) return false; if ( !hasFractions ) { theLastBornME->setXComb(theLastBornXComb); if ( !theLastBornME->generateKinematics(&r[2]) ) return false; } CrossSection bornXS = theLastBornME->dSigHatDR(); if ( bornXS == ZERO ) return false; return true; } void ShowerApproximationGenerator::restore() { theLastBornXComb->clean(); bool hasFractions = thePhasespace->haveX1X2() || theLastBornXComb->mePartonData().size() == 3; if ( !hasFractions ) { tSubProPtr oldSub = lastIncomingXComb->subProcess(); theLastPartons.first->set5Momentum(oldSub->incoming().first->momentum()); theLastPartons.second->set5Momentum(oldSub->incoming().second->momentum()); } else { theLastBornME->setXComb(theLastBornXComb); theLastBornXComb->lastParticles(lastIncomingXComb->lastParticles()); theLastBornXComb->lastP1P2(make_pair(0.0, 0.0)); theLastBornXComb->lastS(lastIncomingXComb->lastS()); theLastBornME->generateKinematics(&theLastRandomNumbers[0]); theLastPartons.first->set5Momentum(theLastBornME->lastMEMomenta()[0]); theLastPartons.second->set5Momentum(theLastBornME->lastMEMomenta()[1]); } theLastBornXComb->fill(lastIncomingXComb->lastParticles(),theLastPartons, theLastMomenta,theLastRandomNumbers); if ( !hasFractions ) { theLastBornME->setXComb(theLastBornXComb); theLastBornME->generateKinematics(&theLastRandomNumbers[2]); } theLastBornME->dSigHatDR(); } void ShowerApproximationGenerator:: handle(EventHandler & eh, const tPVector &, const Hint &) { MatchboxFactory::currentFactory()->setHardTreeEmitter(-1); MatchboxFactory::currentFactory()->setHardTreeSpectator(-1); MatchboxFactory::currentFactory()->setHardTreeSubprocess(SubProPtr()); lastIncomingXComb = dynamic_ptr_cast(eh.lastXCombPtr()); if ( !lastIncomingXComb ) throw Exception() << "ShowerApproximationGenerator::handle(): Expecting a standard event handler." << Exception::runerror; bool didproject = false; if ( lastIncomingXComb->lastProjector() ) { lastIncomingXComb = lastIncomingXComb->lastProjector(); didproject = true; } const StandardXComb& xc = *lastIncomingXComb; map::ptr> >::const_iterator kernelit = theKernelMap.find(xc.mePartonData()); if ( kernelit == theKernelMap.end() ) { list channels = MatchboxFactory::currentFactory()->getSplittingChannels(lastIncomingXComb); set::ptr> newKernels; for ( list::const_iterator c = channels.begin(); c != channels.end(); ++c ) { Ptr::ptr kernel = new_ptr(ShowerApproximationKernel()); kernel->setBornXComb(c->bornXComb); kernel->setRealXComb(c->realXComb); kernel->setTildeXCombs(c->tildeXCombs); kernel->setDipole(c->dipole); kernel->showerApproximation(theShowerApproximation); kernel->presamplingPoints(thePresamplingPoints); kernel->maxtry(theMaxTry); kernel->freezeGrid(theFreezeGrid); kernel->showerApproximationGenerator(this); kernel->doCompensate(theDoCompensate); if ( kernel->dipole()->bornEmitter() > 1 && kernel->dipole()->bornSpectator() > 1 ) { kernel->ptCut(ffPtCut()); } else if ( ( kernel->dipole()->bornEmitter() > 1 && kernel->dipole()->bornSpectator() < 2 ) || ( kernel->dipole()->bornEmitter() < 2 && kernel->dipole()->bornSpectator() > 1 ) ) { kernel->ptCut(fiPtCut()); } else { assert(kernel->dipole()->bornEmitter() < 2 && kernel->dipole()->bornSpectator() < 2); kernel->ptCut(iiPtCut()); } newKernels.insert(kernel); } theKernelMap[xc.mePartonData()] = newKernels; kernelit = theKernelMap.find(xc.mePartonData()); } if ( kernelit->second.empty() ) return; const set::ptr>& kernels = kernelit->second; theLastBornME = (**kernels.begin()).dipole()->underlyingBornME(); if ( theLastBornME->phasespace()->wantCMS() != thePhasespace->wantCMS() ) { throw Exception() << "Mismatch in centre-of-mass-system requirements of hard matrix element phasespace (" << (theLastBornME->phasespace()->wantCMS()?"Yes":"No") << ") and shower approximation phasespace (" << (thePhasespace->wantCMS()?"Yes":"No") << ")" << Exception::abortnow; } theLastBornME->phasespace(thePhasespace); theLastBornXComb = (**kernels.begin()).bornXComb(); if ( !prepare(didproject) ) return; Energy winnerPt = ZERO; Ptr::ptr winnerKernel; try { for ( set::ptr>::const_iterator k = kernels.begin(); k != kernels.end(); ++k ) { if ( (**k).generate() != 0. && (*k)->dipole()->lastPt() > winnerPt){ winnerKernel = *k; winnerPt = winnerKernel->dipole()->lastPt(); } } } catch(ShowerApproximationKernel::MaxTryException&) { throw Exception() << "Too many tries needed to generate the matrix element correction in '" << name() << "'" << Exception::eventerror; } if ( !winnerKernel || winnerPt == ZERO ) return; //Hardest emission should be this one. winnerKernel->realXComb()->lastShowerScale(sqr(winnerPt)); winnerKernel->bornXComb()->lastShowerScale(sqr(winnerPt)); lastIncomingXComb->lastShowerScale(sqr(winnerPt)); SubProPtr oldSub = lastIncomingXComb->subProcess(); SubProPtr newSub; try { tcDiagPtr bornDiag = lastIncomingXComb->lastDiagram(); tcDiagPtr realDiag = winnerKernel->dipole()->realEmissionDiagram(bornDiag); winnerKernel->realXComb()->externalDiagram(realDiag); newSub = winnerKernel->realXComb()->construct(); } catch(Veto&) { return; } if ( !theShowerApproximation->needsTruncatedShower() ){ tParticleSet firstS = oldSub->incoming().first->siblings(); assert(firstS.empty() || firstS.size() == 1); if ( !firstS.empty() ) { eh.currentStep()->removeParticle(*firstS.begin()); } tParticleSet secondS = oldSub->incoming().second->siblings(); assert(secondS.empty() || secondS.size() == 1); if ( !secondS.empty() ) { eh.currentStep()->removeParticle(*secondS.begin()); } // prevent the colliding particles from disappearing // in the initial state and appearing // in the final state when we've cut off all their // (physical) children; only applies to the case // where we have a parton extractor not build from // noPDF, so check wether the incoming particle // doesnt equal the incoming parton -- this needs fixing in ThePEG PPtr dummy = new_ptr(Particle(getParticleData(ParticleID::gamma))); bool usedDummy = false; if ( eh.currentStep()->incoming().first != oldSub->incoming().first ) { eh.currentStep()->addDecayProduct(eh.currentStep()->incoming().first,dummy); usedDummy = true; } if ( eh.currentStep()->incoming().second != oldSub->incoming().second ) { eh.currentStep()->addDecayProduct(eh.currentStep()->incoming().second,dummy); usedDummy = true; } eh.currentStep()->removeSubProcess(oldSub); eh.currentStep()->addSubProcess(newSub); // get rid of the dummy if ( usedDummy ) { eh.currentStep()->removeParticle(dummy); } eh.select(winnerKernel->realXComb()); winnerKernel->realXComb()->recreatePartonBinInstances(winnerKernel->realXComb()->lastScale()); winnerKernel->realXComb()->refillPartonBinInstances(&(xc.lastRandomNumbers()[0])); winnerKernel->realXComb()->pExtractor()->constructRemnants(winnerKernel->realXComb()->partonBinInstances(), newSub, eh.currentStep()); } else{ MatchboxFactory::currentFactory()->setHardTreeSubprocess(newSub); MatchboxFactory::currentFactory()->setHardTreeEmitter(winnerKernel->dipole()->bornEmitter()); MatchboxFactory::currentFactory()->setHardTreeSpectator(winnerKernel->dipole()->bornSpectator()); } } IBPtr ShowerApproximationGenerator::clone() const { return new_ptr(*this); } IBPtr ShowerApproximationGenerator::fullclone() const { return new_ptr(*this); } // If needed, insert default implementations of virtual function defined // in the InterfacedBase class here (using ThePEG-interfaced-impl in Emacs). void ShowerApproximationGenerator::persistentOutput(PersistentOStream & os) const { os << theShowerApproximation << thePhasespace << theKernelMap << thePresamplingPoints << theMaxTry << theFreezeGrid << lastIncomingXComb << theLastBornME << ounit(theLastMomenta,GeV) << ounit(theLastPresamplingMomenta,GeV) << theLastRandomNumbers << theLastBornXComb << theLastPartons << theDoCompensate; } void ShowerApproximationGenerator::persistentInput(PersistentIStream & is, int) { is >> theShowerApproximation >> thePhasespace >> theKernelMap >> thePresamplingPoints >> theMaxTry >> theFreezeGrid >> lastIncomingXComb >> theLastBornME >> iunit(theLastMomenta,GeV) >> iunit(theLastPresamplingMomenta,GeV) >> theLastRandomNumbers >> theLastBornXComb >> theLastPartons >> theDoCompensate; } // *** 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 describeHerwigShowerApproximationGenerator("Herwig::ShowerApproximationGenerator", "Herwig.so"); void ShowerApproximationGenerator::Init() { static ClassDocumentation documentation ("ShowerApproximationGenerator generates emissions according to a " "shower approximation entering a NLO matching."); static Reference interfaceShowerApproximation ("ShowerApproximation", "Set the shower approximation to sample.", &ShowerApproximationGenerator::theShowerApproximation, false, false, true, false, false); interfaceShowerApproximation.rank(-1); static Reference interfacePhasespace ("Phasespace", "The phase space generator to use.", &ShowerApproximationGenerator::thePhasespace, false, false, true, false, false); interfacePhasespace.rank(-1); static Parameter interfacePresamplingPoints ("PresamplingPoints", "Set the number of presampling points.", &ShowerApproximationGenerator::thePresamplingPoints, 2000, 1, 0, false, false, Interface::lowerlim); static Parameter interfaceMaxTry ("MaxTry", "Set the number of maximum attempts.", &ShowerApproximationGenerator::theMaxTry, 100000, 1, 0, false, false, Interface::lowerlim); static Parameter interfaceFreezeGrid ("FreezeGrid", "", &ShowerApproximationGenerator::theFreezeGrid, 500000, 1, 0, false, false, Interface::lowerlim); static Switch interfaceDoCompensate ("DoCompensate", "", &ShowerApproximationGenerator::theDoCompensate, false, false, false); static SwitchOption interfaceDoCompensateYes (interfaceDoCompensate, "Yes", "", true); static SwitchOption interfaceDoCompensateNo (interfaceDoCompensate, "No", "", false); } diff --git a/MatrixElement/Matchbox/Matching/ShowerApproximationGenerator.h b/MatrixElement/Matchbox/Matching/ShowerApproximationGenerator.h --- a/MatrixElement/Matchbox/Matching/ShowerApproximationGenerator.h +++ b/MatrixElement/Matchbox/Matching/ShowerApproximationGenerator.h @@ -1,251 +1,243 @@ // -*- C++ -*- // // ShowerApproximationGenerator.h is a part of Herwig - A multi-purpose Monte Carlo event generator // Copyright (C) 2002-2019 The Herwig Collaboration // // Herwig is licenced under version 3 of the GPL, see COPYING for details. // Please respect the MCnet academic guidelines, see GUIDELINES for details. // #ifndef Herwig_ShowerApproximationGenerator_H #define Herwig_ShowerApproximationGenerator_H // // This is the declaration of the ShowerApproximationGenerator class. // #include "ThePEG/Handlers/StepHandler.h" #include "Herwig/MatrixElement/Matchbox/Matching/ShowerApproximationKernel.h" #include "Herwig/MatrixElement/Matchbox/Phasespace/MatchboxPhasespace.h" #include "Herwig/MatrixElement/Matchbox/MatchboxFactory.h" namespace Herwig { using namespace ThePEG; /** * \ingroup Matchbox * \author Simon Platzer * * \brief ShowerApproximationGenerator generates emissions according to a * shower approximation entering a NLO matching. * */ class ShowerApproximationGenerator: public StepHandler { public: - /** @name Standard constructors and destructors. */ - //@{ /** * The default constructor. */ ShowerApproximationGenerator(); - /** - * The destructor. - */ - virtual ~ShowerApproximationGenerator(); - //@} - public: /** @name Virtual functions required by the StepHandler class. */ //@{ /** * The main function called by the EventHandler class to * perform a step. Given the current state of an Event, this function * performs the event generation step and includes the result in a new * Step object int the Event record. * @param eh the EventHandler in charge of the Event generation. * @param tagged if not empty these are the only particles which should * be considered by the StepHandler. * @param hint a Hint object with possible information from previously * performed steps. * @throws Veto if the StepHandler requires the current step to be discarded. * @throws Stop if the generation of the current Event should be stopped * after this call. * @throws Exception if something goes wrong. */ virtual void handle(EventHandler & eh, const tPVector & tagged, const Hint & hint); //@} public: /** * Fill information on the Born process */ bool prepare(bool didproject); /** * Generate a Born phase space point while kernels are being * presampled */ bool generate(const vector&); /** * Restore information on the Born process */ void restore(); protected: /** * Generate a momentum fraction for the given parton species */ double generateFraction(tcPDPtr, double, double) const; /** * Invert the momentum fraction for the given parton species */ double invertFraction(tcPDPtr, double, double) const; /** * Return the pt cut to be applied for final-final dipoles. */ Energy ffPtCut() const { return theShowerApproximation->ffPtCut(); } /** * Return the pt cut to be applied for final-initial dipoles. */ Energy fiPtCut() const { return theShowerApproximation->fiPtCut(); } /** * Return the pt cut to be applied for initial-initial dipoles. */ Energy iiPtCut() const { return theShowerApproximation->iiPtCut(); } 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 shower approximation to consider */ Ptr::ptr theShowerApproximation; /** * The (invertible) phase space generator to use */ Ptr::ptr thePhasespace; /** * Map hard processes to the respective kernels. */ map::ptr> > theKernelMap; /** * The number of points to presample this splitting generator. */ unsigned long thePresamplingPoints; /** * The maximum number of trials to generate a splitting. */ unsigned long theMaxTry; /** * Return the number of accepted points after which the grid should * be frozen */ unsigned long theFreezeGrid; /** * The last external Born XComb dealt with */ tStdXCombPtr lastIncomingXComb; // the next three are filled from the incoming xcomb in the prepare method /** * The last internal Born matrix element dealt with */ Ptr::ptr theLastBornME; /** * The last Born phase space point */ vector theLastMomenta; /** * The last Born phase space point used while presampling */ vector theLastPresamplingMomenta; /** * The random numbers which have produced the last Born phase space * point. */ vector theLastRandomNumbers; /** * The last internal Born XComb dealt with */ tStdXCombPtr theLastBornXComb; /** * The last internal incoming partons dealt with */ PPair theLastPartons; /** * True, if sampler should apply compensation */ bool theDoCompensate; /** * The assignment operator is private and must never be called. * In fact, it should not even be implemented. */ ShowerApproximationGenerator & operator=(const ShowerApproximationGenerator &) = delete; }; } #endif /* Herwig_ShowerApproximationGenerator_H */ diff --git a/MatrixElement/Matchbox/Matching/ShowerApproximationKernel.cc b/MatrixElement/Matchbox/Matching/ShowerApproximationKernel.cc --- a/MatrixElement/Matchbox/Matching/ShowerApproximationKernel.cc +++ b/MatrixElement/Matchbox/Matching/ShowerApproximationKernel.cc @@ -1,210 +1,208 @@ // -*- C++ -*- // // ShowerApproximationKernel.cc is a part of Herwig - A multi-purpose Monte Carlo event generator // Copyright (C) 2002-2019 The Herwig Collaboration // // Herwig is licenced under version 3 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 ShowerApproximationKernel class. // #include #include "ShowerApproximationKernel.h" #include "ThePEG/Interface/ClassDocumentation.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 "ShowerApproximationGenerator.h" using namespace Herwig; ShowerApproximationKernel::ShowerApproximationKernel() : thePresampling(false), thePresamplingPoints(10000), theMaxTry(100000), theFreezeGrid(500000), sampler(0), theDoCompensate(false) {} -ShowerApproximationKernel::~ShowerApproximationKernel() {} - IBPtr ShowerApproximationKernel::clone() const { return new_ptr(*this); } IBPtr ShowerApproximationKernel::fullclone() const { return new_ptr(*this); } void ShowerApproximationKernel::showerApproximationGenerator(Ptr::tptr gen) { theShowerApproximationGenerator = gen; } Ptr::tptr ShowerApproximationKernel::showerApproximationGenerator() const { return theShowerApproximationGenerator; } const vector& ShowerApproximationKernel::sampleFlags() { if ( !theFlags.empty() ) return theFlags; theFlags.resize(nDim(),false); for ( int k = nDimBorn(); k < nDimBorn() + dipole()->nDimRadiation(); ++k ) theFlags[k] = true; return theFlags; } const pair,vector >& ShowerApproximationKernel::support() { if ( !theSupport.first.empty() ) return theSupport; vector l(nDim(),0.0); vector u(nDim(),1.0); theSupport.first = l; theSupport.second = u; return theSupport; } const vector& ShowerApproximationKernel::parameterPoint() { theLastParameterPoint.resize(nDim()); copy(bornCXComb()->lastRandomNumbers().begin(), bornCXComb()->lastRandomNumbers().end(), theLastParameterPoint.begin()); theLastParameterPoint[evolutionVariable()] = 1.; return theLastParameterPoint; } void ShowerApproximationKernel::startPresampling() { thePresampling = true; } void ShowerApproximationKernel::stopPresampling() { showerApproximationGenerator()->restore(); thePresampling = false; } double ShowerApproximationKernel::evaluate(const vector& r) { if ( presampling() ) { theLastBornPoint.resize(nDimBorn()); copy(r.begin(),r.begin()+nDimBorn(),theLastBornPoint.begin()); if ( !showerApproximationGenerator()->generate(theLastBornPoint) ) return 0.; } assert(dipole()->splitting()); realXComb()->clean(); dipole()->setXComb(realXComb()); for ( vector::const_iterator t = tildeXCombs().begin(); t != tildeXCombs().end(); ++t ) { (**t).clean(); (**t).matrixElement()->setXComb(*t); } if ( !dipole()->generateKinematics(&r[nDimBorn()]) ) return 0.; double jac = showerApproximation()->showerInvertedTildeKinematics() ? showerApproximation()->showerInvertedTildeKinematics()->jacobian() : dipole()->invertedTildeKinematics()->jacobian(); showerApproximation()->setBornXComb(bornXComb()); showerApproximation()->setRealXComb(realXComb()); showerApproximation()->setTildeXCombs(tildeXCombs()); showerApproximation()->setDipole(dipole()); showerApproximation()->checkCutoff(); showerApproximation()->getShowerVariables(); if ( !dipole()->isInShowerPhasespace() ) return 0.; return showerApproximation()->me2() * jac; } double ShowerApproximationKernel::generate() { if ( !sampler ) { sampler = new ExponentialGenerator(); sampler->sampling_parameters().maxtry = maxtry(); sampler->sampling_parameters().presampling_points = presamplingPoints(); sampler->sampling_parameters().freeze_grid = freezeGrid(); sampler->docompensate(theDoCompensate); sampler->function(this); sampler->initialize(); } double res = 0.; while (true) { try { res = sampler->generate(); } catch (exsample::exponential_regenerate&) { continue; } catch (exsample::hit_and_miss_maxtry&) { throw MaxTryException(); } catch (exsample::selection_maxtry&) { throw MaxTryException(); } break; } return res; } // If needed, insert default implementations of virtual function defined // in the InterfacedBase class here (using ThePEG-interfaced-impl in Emacs). void ShowerApproximationKernel::persistentOutput(PersistentOStream & os) const { os << theDipole << theShowerApproximation << theBornXComb << theRealXComb << theTildeXCombs << thePresampling << thePresamplingPoints << theMaxTry << theFreezeGrid << theFlags << theSupport << theShowerApproximationGenerator << theLastParameterPoint << theLastBornPoint << (sampler ? true : false) << theDoCompensate; if ( sampler ) sampler->put(os); } void ShowerApproximationKernel::persistentInput(PersistentIStream & is, int) { bool haveSampler; is >> theDipole >> theShowerApproximation >> theBornXComb >> theRealXComb >> theTildeXCombs >> thePresampling >> thePresamplingPoints >> theMaxTry >> theFreezeGrid >> theFlags >> theSupport >> theShowerApproximationGenerator >> theLastParameterPoint >> theLastBornPoint >> haveSampler >> theDoCompensate; if ( haveSampler ) { sampler = new ExponentialGenerator(); sampler->get(is); sampler->function(this); sampler->initialize(); } } // *** 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 describeHerwigShowerApproximationKernel("Herwig::ShowerApproximationKernel", "Herwig.so"); void ShowerApproximationKernel::Init() { static ClassDocumentation documentation ("ShowerApproximationKernel generates emissions according to a " "shower approximation entering a NLO matching."); } diff --git a/MatrixElement/Matchbox/Matching/ShowerApproximationKernel.h b/MatrixElement/Matchbox/Matching/ShowerApproximationKernel.h --- a/MatrixElement/Matchbox/Matching/ShowerApproximationKernel.h +++ b/MatrixElement/Matchbox/Matching/ShowerApproximationKernel.h @@ -1,478 +1,470 @@ // -*- C++ -*- // // ShowerApproximationKernel.h is a part of Herwig - A multi-purpose Monte Carlo event generator // Copyright (C) 2002-2019 The Herwig Collaboration // // Herwig is licenced under version 3 of the GPL, see COPYING for details. // Please respect the MCnet academic guidelines, see GUIDELINES for details. // #ifndef Herwig_ShowerApproximationKernel_H #define Herwig_ShowerApproximationKernel_H // // This is the declaration of the ShowerApproximationKernel class. // #include "ThePEG/Handlers/HandlerBase.h" #include "ThePEG/Handlers/StandardXComb.h" #include "Herwig/MatrixElement/Matchbox/Matching/ShowerApproximation.h" #include "Herwig/MatrixElement/Matchbox/Phasespace/InvertedTildeKinematics.h" #include "Herwig/MatrixElement/Matchbox/Dipoles/SubtractionDipole.h" #include "Herwig/Sampling/exsample/exponential_generator.h" namespace Herwig { using namespace ThePEG; class ShowerApproximationGenerator; /** * \ingroup Matchbox * \author Simon Platzer * * \brief ShowerApproximationKernel generates emissions according to a * shower approximation entering a NLO matching. * */ class ShowerApproximationKernel: public HandlerBase { public: /** * Exception to communicate sampler maxtry events. */ struct MaxTryException {}; public: - /** @name Standard constructors and destructors. */ - //@{ /** * The default constructor. */ ShowerApproximationKernel(); - /** - * The destructor. - */ - virtual ~ShowerApproximationKernel(); - //@} - public: /** * Set the XComb object describing the Born process */ void setBornXComb(tStdXCombPtr xc) { theBornXComb = xc; } /** * Return the XComb object describing the Born process */ tcStdXCombPtr bornCXComb() const { return theBornXComb; } /** * Return the XComb object describing the Born process */ tStdXCombPtr bornXComb() const { return theBornXComb; } /** * Set the XComb object describing the real emission process */ void setRealXComb(tStdXCombPtr xc) { theRealXComb = xc; } /** * Return the XComb object describing the real emission process */ tcStdXCombPtr realCXComb() const { return theRealXComb; } /** * Return the XComb object describing the real emission process */ tStdXCombPtr realXComb() const { return theRealXComb; } /** * Set the tilde xcomb objects associated to the real xcomb */ void setTildeXCombs(const vector& xc) { theTildeXCombs = xc; } /** * Return the tilde xcomb objects associated to the real xcomb */ const vector& tildeXCombs() const { return theTildeXCombs; } /** * Set the dipole in charge for the emission */ void setDipole(Ptr::tptr dip) { theDipole = dip; } /** * Return the dipole in charge for the emission */ Ptr::tptr dipole() const { return theDipole; } /** * Set the shower approximation. */ void showerApproximation(Ptr::tptr app) { theShowerApproximation = app; } /** * Return the shower approximation. */ Ptr::tptr showerApproximation() const { return theShowerApproximation; } /** * Set the shower approximation generator. */ void showerApproximationGenerator(Ptr::tptr); /** * Return the shower approximation generator. */ Ptr::tptr showerApproximationGenerator() const; /** * Generate the next emission */ double generate(); public: /** * Set a pt cut on the dipole to generate the radiation */ void ptCut(Energy pt) { dipole()->ptCut(pt); } /** * Return the number of random numbers * needed to sample this kernel. */ int nDim() const { return nDimBorn() + dipole()->nDimRadiation(); } /** * Return the number of random numbers * needed to sample the Born process. */ int nDimBorn() const { return bornCXComb()->lastRandomNumbers().size(); } /** * Flag, which variables are free variables. */ const vector& sampleFlags(); /** * Return the support of the splitting kernel. * The lower bound on the first variable is * assumed to correspond to the cutoff on the * evolution variable. */ const pair,vector >& support(); /** * Return the parameter point associated to the splitting * previously supplied through fixParameters. */ const vector& parameterPoint(); /** * Indicate that presampling of this kernel * will be performed in the next calls to * evaluate until stopPresampling() is called. */ void startPresampling(); /** * Indicate that presampling of this kernel * is done until startPresampling() is called. */ void stopPresampling(); /** * Indicate that a veto with the given kernel value and overestimate has occured. */ void veto(const vector&, double, double) { /** use born and real xcombs in here to figure out what we need to reweight; it should have its kinematic variables completed at this step */ } /** * Indicate that an accept with the given kernel value and overestimate has occured. */ void accept(const vector&, double, double) { /** use born and real xcombs in here to figure out what we need to reweight; it should have its kinematic variables completed at this step */ } /** * Return true, if currently being presampled */ bool presampling() const { return thePresampling; } /** * Return the number of points to presample this * splitting generator. */ unsigned long presamplingPoints() const { return thePresamplingPoints; } /** * Return the maximum number of trials * to generate a splitting. */ unsigned long maxtry() const { return theMaxTry; } /** * Return the number of accepted points after which the grid should * be frozen */ unsigned long freezeGrid() const { return theFreezeGrid; } /** * Set the number of points to presample this * splitting generator. */ void presamplingPoints(unsigned long p) { thePresamplingPoints = p; } /** * Set the maximum number of trials * to generate a splitting. */ void maxtry(unsigned long p) { theMaxTry = p; } /** * Set the number of accepted points after which the grid should * be frozen */ void freezeGrid(unsigned long n) { theFreezeGrid = n; } /** * Evalute the splitting kernel. */ double evaluate(const vector&); /** * Return the index of the random number corresponding * to the evolution variable. */ int evolutionVariable() const { return nDimBorn() + (showerApproximation()->showerInvertedTildeKinematics() ? showerApproximation()->showerInvertedTildeKinematics()->evolutionVariable() : dipole()->invertedTildeKinematics()->evolutionVariable()); } /** * Return the cutoff on the evolution * random number corresponding to the pt cut. */ double evolutionCutoff() const { return showerApproximation()->showerInvertedTildeKinematics() ? showerApproximation()->showerInvertedTildeKinematics()->evolutionCutoff() : dipole()->invertedTildeKinematics()->evolutionCutoff(); } /** * True, if sampler should apply compensation */ void doCompensate(bool yes = true) { theDoCompensate = yes; } public: /**@name Wrap to the exsample2 interface until this is finally cleaned up. */ //@{ inline const vector& variable_flags () { return sampleFlags(); } inline size_t evolution_variable () const { return evolutionVariable(); } inline double evolution_cutoff () const { return evolutionCutoff(); } inline const vector& parameter_point () { return parameterPoint(); } inline void start_presampling () { startPresampling(); } inline void stop_presampling () { stopPresampling(); } inline size_t dimension () const { return nDim(); } inline unsigned long presampling_points () const { return presamplingPoints(); } //@} 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 dipole in charge of the emission */ Ptr::ptr theDipole; /** * The shower approximation to consider */ Ptr::ptr theShowerApproximation; /** * The XComb off which radiation will be generated */ StdXCombPtr theBornXComb; /** * The XComb describing the process after radiation */ StdXCombPtr theRealXComb; /** * The tilde xcomb objects associated to the real xcomb */ vector theTildeXCombs; /** * True, if currently being presampled */ bool thePresampling; /** * The number of points to presample this * splitting generator. */ unsigned long thePresamplingPoints; /** * The maximum number of trials * to generate a splitting. */ unsigned long theMaxTry; /** * Return the number of accepted points after which the grid should * be frozen */ unsigned long theFreezeGrid; /** * The sampling flags */ vector theFlags; /** * The support. */ pair,vector > theSupport; /** * The shower approximation generator. */ Ptr::tptr theShowerApproximationGenerator; /** * The last parameter point */ vector theLastParameterPoint; /** * The last random numbers used for Born sampling */ vector theLastBornPoint; /** * Define the Sudakov sampler */ typedef exsample::exponential_generator ExponentialGenerator; /** * Define a pointer to the Sudakov sampler */ typedef exsample::exponential_generator* ExponentialGeneratorPtr; /** * The Sudakov sampler */ ExponentialGeneratorPtr sampler; /** * True, if sampler should apply compensation */ bool theDoCompensate; /** * The assignment operator is private and must never be called. * In fact, it should not even be implemented. */ ShowerApproximationKernel & operator=(const ShowerApproximationKernel &) = delete; }; } #endif /* Herwig_ShowerApproximationKernel_H */ diff --git a/MatrixElement/Matchbox/Phasespace/FFLightInvertedTildeKinematics.cc b/MatrixElement/Matchbox/Phasespace/FFLightInvertedTildeKinematics.cc --- a/MatrixElement/Matchbox/Phasespace/FFLightInvertedTildeKinematics.cc +++ b/MatrixElement/Matchbox/Phasespace/FFLightInvertedTildeKinematics.cc @@ -1,137 +1,133 @@ // -*- C++ -*- // // FFLightInvertedTildeKinematics.cc is a part of Herwig - A multi-purpose Monte Carlo event generator // Copyright (C) 2002-2019 The Herwig Collaboration // // Herwig is licenced under version 3 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 FFLightInvertedTildeKinematics class. // #include "FFLightInvertedTildeKinematics.h" #include "ThePEG/Interface/ClassDocumentation.h" #include "ThePEG/Utilities/DescribeClass.h" #include "ThePEG/Repository/EventGenerator.h" #include "ThePEG/Persistency/PersistentOStream.h" #include "ThePEG/Persistency/PersistentIStream.h" using namespace Herwig; -FFLightInvertedTildeKinematics::FFLightInvertedTildeKinematics() {} - -FFLightInvertedTildeKinematics::~FFLightInvertedTildeKinematics() {} - IBPtr FFLightInvertedTildeKinematics::clone() const { return new_ptr(*this); } IBPtr FFLightInvertedTildeKinematics::fullclone() const { return new_ptr(*this); } bool FFLightInvertedTildeKinematics::doMap(const double * r) { if ( ptMax() < ptCut() ) { jacobian(0.0); return false; } Lorentz5Momentum emitter = bornEmitterMomentum(); Lorentz5Momentum spectator = bornSpectatorMomentum(); double mapping = 1.0; pair ptz = generatePtZ(mapping,r); if ( mapping == 0.0 ) { jacobian(0.0); return false; } Energy pt = ptz.first; double z = ptz.second; double y = sqr(pt/lastScale())/(z*(1.-z)); if ( y < 0. || y > 1. || z < 0. || z > 1. ) { jacobian(0.0); return false; } mapping *= (1.-y)/(z*(1.-z)); jacobian(mapping*(sqr(lastScale())/sHat())/(16.*sqr(Constants::pi))); double phi = 2.*Constants::pi*r[2]; Lorentz5Momentum kt = getKt(emitter,spectator,pt,phi); subtractionParameters().resize(2); subtractionParameters()[0] = y; subtractionParameters()[1] = z; realEmitterMomentum() = z*emitter + y*(1.-z)*spectator + kt; realEmissionMomentum() = (1.-z)*emitter + y*z*spectator - kt; realSpectatorMomentum() = (1.-y)*spectator; realEmitterMomentum().setMass(ZERO); realEmitterMomentum().rescaleEnergy(); realEmissionMomentum().setMass(ZERO); realEmissionMomentum().rescaleEnergy(); realSpectatorMomentum().setMass(ZERO); realSpectatorMomentum().rescaleEnergy(); return true; } Energy FFLightInvertedTildeKinematics::lastPt() const { Energy scale = sqrt(2.*(bornEmitterMomentum()*bornSpectatorMomentum())); double y = subtractionParameters()[0]; double z = subtractionParameters()[1]; return scale * sqrt(y*z*(1.-z)); } double FFLightInvertedTildeKinematics::lastZ() const { return subtractionParameters()[1]; } Energy FFLightInvertedTildeKinematics::ptMax() const { return lastScale()/2.; } pair FFLightInvertedTildeKinematics::zBounds(Energy pt, Energy hardPt) const { hardPt = hardPt == ZERO ? ptMax() : min(hardPt,ptMax()); if(pt>hardPt) return make_pair(0.5,0.5); double s = sqrt(1.-sqr(pt/hardPt)); return make_pair(0.5*(1.-s),0.5*(1.+s)); } // If needed, insert default implementations of virtual function defined // in the InterfacedBase class here (using ThePEG-interfaced-impl in Emacs). void FFLightInvertedTildeKinematics::persistentOutput(PersistentOStream &) const { } void FFLightInvertedTildeKinematics::persistentInput(PersistentIStream &, int) { } void FFLightInvertedTildeKinematics::Init() { static ClassDocumentation documentation ("FFLightInvertedTildeKinematics inverts the final-final tilde " "kinematics."); } // *** 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 describeHerwigFFLightInvertedTildeKinematics("Herwig::FFLightInvertedTildeKinematics", "Herwig.so"); diff --git a/MatrixElement/Matchbox/Phasespace/FFLightInvertedTildeKinematics.h b/MatrixElement/Matchbox/Phasespace/FFLightInvertedTildeKinematics.h --- a/MatrixElement/Matchbox/Phasespace/FFLightInvertedTildeKinematics.h +++ b/MatrixElement/Matchbox/Phasespace/FFLightInvertedTildeKinematics.h @@ -1,138 +1,123 @@ // -*- C++ -*- // // FFLightInvertedTildeKinematics.h is a part of Herwig - A multi-purpose Monte Carlo event generator // Copyright (C) 2002-2019 The Herwig Collaboration // // Herwig is licenced under version 3 of the GPL, see COPYING for details. // Please respect the MCnet academic guidelines, see GUIDELINES for details. // #ifndef HERWIG_FFLightInvertedTildeKinematics_H #define HERWIG_FFLightInvertedTildeKinematics_H // // This is the declaration of the FFLightInvertedTildeKinematics class. // #include "Herwig/MatrixElement/Matchbox/Phasespace/InvertedTildeKinematics.h" namespace Herwig { using namespace ThePEG; /** * \ingroup Matchbox * \author Simon Platzer * * \brief FFLightInvertedTildeKinematics inverts the final-final tilde * kinematics. * */ class FFLightInvertedTildeKinematics: public Herwig::InvertedTildeKinematics { public: - /** @name Standard constructors and destructors. */ - //@{ - /** - * The default constructor. - */ - FFLightInvertedTildeKinematics(); - - /** - * The destructor. - */ - virtual ~FFLightInvertedTildeKinematics(); - //@} - -public: - /** * Perform the mapping of the tilde kinematics for the * last selected process and store all dimensionless * variables in the subtractionParameters() vector. * Return false, if the calculation of the real * kinematics was impossible for the selected configuration * and true on success. */ virtual bool doMap(const double *); /** * Return the pt associated to the last generated splitting. */ virtual Energy lastPt() const; /** * Return the momentum fraction associated to the last splitting. */ virtual double lastZ() const; /** * Return the upper bound on pt */ virtual Energy ptMax() const; /** * Given a pt, return the boundaries on z */ virtual pair zBounds(Energy pt, Energy hardPt = ZERO) 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. */ FFLightInvertedTildeKinematics & operator=(const FFLightInvertedTildeKinematics &) = delete; }; } #endif /* HERWIG_FFLightInvertedTildeKinematics_H */ diff --git a/MatrixElement/Matchbox/Phasespace/FFLightTildeKinematics.cc b/MatrixElement/Matchbox/Phasespace/FFLightTildeKinematics.cc --- a/MatrixElement/Matchbox/Phasespace/FFLightTildeKinematics.cc +++ b/MatrixElement/Matchbox/Phasespace/FFLightTildeKinematics.cc @@ -1,114 +1,109 @@ // -*- C++ -*- // // FFLightTildeKinematics.cc is a part of Herwig - A multi-purpose Monte Carlo event generator // Copyright (C) 2002-2019 The Herwig Collaboration // // Herwig is licenced under version 3 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 FFLightTildeKinematics class. // #include "FFLightTildeKinematics.h" #include "ThePEG/Interface/ClassDocumentation.h" #include "ThePEG/Utilities/DescribeClass.h" - #include "ThePEG/Persistency/PersistentOStream.h" #include "ThePEG/Persistency/PersistentIStream.h" using namespace Herwig; -FFLightTildeKinematics::FFLightTildeKinematics() {} - -FFLightTildeKinematics::~FFLightTildeKinematics() {} - IBPtr FFLightTildeKinematics::clone() const { return new_ptr(*this); } IBPtr FFLightTildeKinematics::fullclone() const { return new_ptr(*this); } bool FFLightTildeKinematics::doMap() { Lorentz5Momentum emitter = realEmitterMomentum(); Lorentz5Momentum emission = realEmissionMomentum(); Lorentz5Momentum spectator = realSpectatorMomentum(); double y = emission*emitter / (emission*emitter + emission*spectator + emitter*spectator); double z = emitter*spectator / (emitter*spectator + emission*spectator); subtractionParameters().resize(2); subtractionParameters()[0] = y; subtractionParameters()[1] = z; bornEmitterMomentum() = emitter+emission-(y/(1.-y))*spectator; bornSpectatorMomentum() = spectator/(1.-y); bornEmitterMomentum().setMass(ZERO); bornEmitterMomentum().rescaleEnergy(); bornSpectatorMomentum().setMass(ZERO); bornSpectatorMomentum().rescaleEnergy(); return true; } Energy FFLightTildeKinematics::lastPt() const { Energy scale = sqrt(2.*(bornEmitterMomentum()*bornSpectatorMomentum())); double y = subtractionParameters()[0]; double z = subtractionParameters()[1]; return scale * sqrt(y*z*(1.-z)); } Energy FFLightTildeKinematics::lastPt(Lorentz5Momentum emitter,Lorentz5Momentum emission,Lorentz5Momentum spectator)const { Energy scale = (emitter+emission+spectator).m(); double y = emission*emitter/(emission*emitter + emission*spectator + emitter*spectator); double z = emitter*spectator / (emitter*spectator + emission*spectator); Energy ret = scale * sqrt( y * z*(1.-z) ); return ret; } pair FFLightTildeKinematics::zBounds(Energy pt, Energy hardPt) const { if(pt>hardPt) return make_pair(0.5,0.5); double s = sqrt(1.-sqr(pt/hardPt)); return make_pair(0.5*(1.-s),0.5*(1.+s)); } double FFLightTildeKinematics::lastZ() const { return subtractionParameters()[1]; } // If needed, insert default implementations of virtual function defined // in the InterfacedBase class here (using ThePEG-interfaced-impl in Emacs). void FFLightTildeKinematics::persistentOutput(PersistentOStream &) const { } void FFLightTildeKinematics::persistentInput(PersistentIStream &, int) { } void FFLightTildeKinematics::Init() { static ClassDocumentation documentation ("FFLightTildeKinematics implements the 'tilde' kinematics for " "a final-final subtraction dipole."); } // *** 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 describeHerwigFFLightTildeKinematics("Herwig::FFLightTildeKinematics", "Herwig.so"); diff --git a/MatrixElement/Matchbox/Phasespace/FFLightTildeKinematics.h b/MatrixElement/Matchbox/Phasespace/FFLightTildeKinematics.h --- a/MatrixElement/Matchbox/Phasespace/FFLightTildeKinematics.h +++ b/MatrixElement/Matchbox/Phasespace/FFLightTildeKinematics.h @@ -1,144 +1,129 @@ // -*- C++ -*- // // FFLightTildeKinematics.h is a part of Herwig - A multi-purpose Monte Carlo event generator // Copyright (C) 2002-2019 The Herwig Collaboration // // Herwig is licenced under version 3 of the GPL, see COPYING for details. // Please respect the MCnet academic guidelines, see GUIDELINES for details. // #ifndef HERWIG_FFLightTildeKinematics_H #define HERWIG_FFLightTildeKinematics_H // // This is the declaration of the FFLightTildeKinematics class. // #include "Herwig/MatrixElement/Matchbox/Phasespace/TildeKinematics.h" namespace Herwig { using namespace ThePEG; /** * \ingroup Matchbox * \author Simon Platzer * * \brief FFLightTildeKinematics implements the 'tilde' kinematics for * a final-final subtraction dipole. * */ class FFLightTildeKinematics: public TildeKinematics { public: - /** @name Standard constructors and destructors. */ - //@{ - /** - * The default constructor. - */ - FFLightTildeKinematics(); - - /** - * The destructor. - */ - virtual ~FFLightTildeKinematics(); - //@} - -public: - /** * Perform the mapping to the tilde kinematics for the * last selected process and store all dimensionless * variables in the subtractionParameters() vector. * Return false, if the calculation of the tilde * kinematics was impossible for the selected configuration * and true on success. */ virtual bool doMap(); /** * Return the pt associated to the last merged splitting. */ virtual Energy lastPt() const; /** * Return the pt associated to emitter emission and sppectator momentum. */ virtual Energy lastPt(Lorentz5Momentum,Lorentz5Momentum,Lorentz5Momentum) const ; /** * Given a pt, return the boundaries on z */ virtual pair zBounds(Energy pt, Energy hardPt ) const; /** * Return the momentum fraction associated to the last splitting. */ virtual double lastZ() const; /* * True if phase space point is above the alpha cut for this dipole. */ bool aboveAlpha() const {return dipole()->alpha() values(6); pair ptz = generatePtZ(mapping, r, &values); if ( mapping == 0.0 ) { jacobian(0.0); return false; } Energy pt = ptz.first; Energy2 pt2 = sqr(pt); double z = ptz.second; // masses double mui2 = sqr( realEmitterData()->hardProcessMass() / lastScale() ); double muj2 = sqr( realEmissionData()->hardProcessMass() / lastScale() ); double muk2 = sqr( realSpectatorData()->hardProcessMass() / lastScale() ); double Muij2 = sqr( bornEmitterData()->hardProcessMass() / lastScale() ); double Muk2 = sqr( bornSpectatorData()->hardProcessMass() / lastScale() ); // Define the scale Energy2 Qijk = sqr(lastScale()); // Most of the required values have been calculated in ptzAllowed double y = values[0]; double zi = values[1]; double xk = values[2]; double xij = values[3]; double QijN2 = values[4]; double sijkN = values[5]; double sijkN2 = sqr(sijkN); // Construct reference momenta nk, nij Lorentz5Momentum nij = ( sijkN2 / (sijkN2-Muij2*Muk2) ) * (emitter - (Muij2/sijkN)*spectator); Lorentz5Momentum nk = ( sijkN2 / (sijkN2-Muij2*Muk2) ) * (spectator - (Muk2/sijkN)*emitter); // Construct qt double phi = 2.*Constants::pi*r[2]; Lorentz5Momentum qt = getKt(emitter,spectator,pt,phi); // Construct qij, qk, qi and qj Lorentz5Momentum qij = xij*nij + (Muij2/(xij*sijkN))*nk; Lorentz5Momentum spe = xk*nk + (Muk2/(xk*sijkN))*nij; Lorentz5Momentum em = z*qij + ((pt2/Qijk + mui2 - z*z*Muij2)/(xij*sijkN*z))*nk + qt; Lorentz5Momentum emm = (1.-z)*qij + ((pt2/Qijk + muj2 - sqr(1.-z)*Muij2)/(xij*sijkN*(1.-z)))*nk - qt; em.setMass(realEmitterData()->hardProcessMass()); em.rescaleEnergy(); emm.setMass(realEmissionData()->hardProcessMass()); emm.rescaleEnergy(); spe.setMass(realSpectatorData()->hardProcessMass()); spe.rescaleEnergy(); // book realEmitterMomentum() = em; realEmissionMomentum() = emm; realSpectatorMomentum() = spe; // Calculate the jacobian double bar = 1.-mui2-muj2-muk2; // mapFactor defined as dy dz = mapFactor * dpt2/sqr(lastScale()) dz double mapFactor = 0.0; mapFactor = y*(sqr(lastScale()) / (pt2 + sqr(1.-z)*mui2*Qijk + sqr(z)*muj2*Qijk)) * abs(1. - 2.*Muk2*QijN2 / (bar*(1.-y)*xij*xk*sijkN)); // Mapping includes only the variable changes/jacobians mapping *= mapFactor; jacobian( (Qijk*sqr(bar)/rootOfKallen(1.,Muij2,Muk2)) * mapping * (1.-y)/(16.*sqr(Constants::pi)) / sHat() ); // Store the parameters subtractionParameters().resize(3); subtractionParameters()[0] = y; subtractionParameters()[1] = zi; subtractionParameters()[2] = z; return true; } Energy FFMassiveInvertedTildeKinematics::lastPt() const { Energy scale = (bornEmitterMomentum()+bornSpectatorMomentum()).m(); // masses double mui2 = sqr( realEmitterData()->hardProcessMass() / scale ); double muj2 = sqr( realEmissionData()->hardProcessMass() / scale ); double muk2 = sqr( realSpectatorData()->hardProcessMass() / scale ); double y = subtractionParameters()[0]; double z = subtractionParameters()[2]; Energy ret = scale * sqrt( y * (1.-mui2-muj2-muk2) * z*(1.-z) - sqr(1.-z)*mui2 - sqr(z)*muj2 ); return ret; } double FFMassiveInvertedTildeKinematics::lastZ() const { return subtractionParameters()[2]; } Energy FFMassiveInvertedTildeKinematics::ptMax() const { Energy scale = (bornEmitterMomentum()+bornSpectatorMomentum()).m(); // masses double mui2 = sqr( realEmitterData()->hardProcessMass() / scale ); double muj2 = sqr( realEmissionData()->hardProcessMass() / scale ); double muk2 = sqr( realSpectatorData()->hardProcessMass() / scale ); Energy ptmax = rootOfKallen( mui2, muj2, sqr(1.-sqrt(muk2)) ) / ( 2.-2.*sqrt(muk2) ) * scale; return ptmax > 0.*GeV ? ptmax : 0.*GeV; } // NOTE: bounds calculated at this step may be too loose pair FFMassiveInvertedTildeKinematics::zBounds(Energy pt, Energy hardPt) const { hardPt = hardPt == ZERO ? ptMax() : min(hardPt,ptMax()); if(pt>hardPt) return make_pair(0.5,0.5); Energy scale = (bornEmitterMomentum()+bornSpectatorMomentum()).m(); // masses double mui2 = sqr( realEmitterData()->hardProcessMass() / scale ); double muj2 = sqr( realEmissionData()->hardProcessMass() / scale ); double muk2 = sqr( realSpectatorData()->hardProcessMass() / scale ); double zp = ( 1.+mui2-muj2+muk2-2.*sqrt(muk2) + rootOfKallen(mui2,muj2,sqr(1.-sqrt(muk2))) * sqrt( 1.-sqr(pt/hardPt) ) ) / ( 2.*sqr(1.-sqrt(muk2)) ); double zm = ( 1.+mui2-muj2+muk2-2.*sqrt(muk2) - rootOfKallen(mui2,muj2,sqr(1.-sqrt(muk2))) * sqrt( 1.-sqr(pt/hardPt) ) ) / ( 2.*sqr(1.-sqrt(muk2)) ); return make_pair(zm,zp); } // Matches Stephen Webster's thesis bool FFMassiveInvertedTildeKinematics::ptzAllowed(pair ptz, vector* values) const { Energy pt = ptz.first; Energy2 pt2 = sqr(pt); double z = ptz.second; // masses double mui2 = sqr( realEmitterData()->hardProcessMass() / lastScale() ); double muj2 = sqr( realEmissionData()->hardProcessMass() / lastScale() ); double muk2 = sqr( realSpectatorData()->hardProcessMass() / lastScale() ); double Muij2 = sqr( bornEmitterData()->hardProcessMass() / lastScale() ); double Muk2 = sqr( bornSpectatorData()->hardProcessMass() / lastScale() ); // Calculate the scales that we need Energy2 Qijk = sqr(lastScale()); double QijN2 = (pt2/Qijk + (1.-z)*mui2 + z*muj2) / z / (1.-z); double sijkN = 0.5*( 1. - Muij2 - Muk2 + sqrt( sqr(1.-Muij2-Muk2) - 4.*Muij2*Muk2 ) ); double bar = 1.-mui2-muj2-muk2; double y = ( pt2/Qijk + sqr(1.-z)*mui2 + z*z*muj2 ) / (z*(1.-z)*bar); // Calculate the scaling factors, xk and xij double lambdaK = 1. + (Muk2/sijkN); double lambdaIJ = 1. + (Muij2/sijkN); double fac1 = lambdaIJ*lambdaK + (muk2 - QijN2)/sijkN; double xk = ( fac1 + sqrt( sqr(fac1) - 4.*lambdaIJ*lambdaK*muk2/sijkN ) ) / 2. / lambdaK ; double xij = 1. - muk2*(1.-xk) / xk / sijkN; // Calculate zi double zi = ( z*xij*xk*sijkN + muk2*(pt2/Qijk + mui2) / (z*xij*xk*sijkN) ) / (1.-y) / bar; // Limits on zi double facA = (2.*mui2+bar*y)/2./(mui2 + muj2 + bar*y); double facB = sqrt( (sqr(2.*muk2 + bar*(1.-y)) - 4.*muk2) * (sqr(bar)*sqr(y) - 4.*mui2*muj2)) / bar / (1.-y) / (bar*y + 2.*mui2); double zim = facA * (1. - facB); double zip = facA * (1. + facB); // check (y,z) phase space boundary double ym = 2.*sqrt(mui2)*sqrt(muj2)/bar; double yp = 1. - 2.*sqrt(muk2)*(1.-sqrt(muk2))/bar; if ( yyp || zizip ) return false; assert( (*values).size() == 6); (*values)[0] = y; (*values)[1] = zi; (*values)[2] = xk; (*values)[3] = xij; (*values)[4] = QijN2; (*values)[5] = sijkN; return true; } // This is used to generate pt and z pair FFMassiveInvertedTildeKinematics::generatePtZ(double& jac, const double * r, vector * values) const { double kappaMin = ptCut() != ZERO ? sqr(ptCut()/ptMax()) : sqr(0.1*GeV/GeV); double kappa; using namespace RandomHelpers; if ( ptCut() > ZERO ) { pair kw = generate(inverse(0.,kappaMin,1.),r[0]); kappa = kw.first; jac *= kw.second; } else { pair kw = generate((piecewise(), flat(1e-4,kappaMin), match(inverse(0.,kappaMin,1.))),r[0]); kappa = kw.first; jac *= kw.second; } Energy pt = sqrt(kappa)*ptMax(); pair zLims = zBounds(pt); pair zw = generate(inverse(0.,zLims.first,zLims.second)+ inverse(1.,zLims.first,zLims.second),r[1]); double z = zw.first; jac *= zw.second; jac *= sqr(ptMax()/lastScale()); if( !ptzAllowed(make_pair(pt,z), values )) jac = 0.; return make_pair(pt,z); } // If needed, insert default implementations of virtual function defined // in the InterfacedBase class here (using ThePEG-interfaced-impl in Emacs). void FFMassiveInvertedTildeKinematics::persistentOutput(PersistentOStream &) const { } void FFMassiveInvertedTildeKinematics::persistentInput(PersistentIStream &, int) { } void FFMassiveInvertedTildeKinematics::Init() { static ClassDocumentation documentation ("FFMassiveInvertedTildeKinematics inverts the final-final tilde " "kinematics involving a massive particle."); } // *** 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 describeHerwigFFMassiveInvertedTildeKinematics("Herwig::FFMassiveInvertedTildeKinematics", "Herwig.so"); diff --git a/MatrixElement/Matchbox/Phasespace/FFMassiveInvertedTildeKinematics.h b/MatrixElement/Matchbox/Phasespace/FFMassiveInvertedTildeKinematics.h --- a/MatrixElement/Matchbox/Phasespace/FFMassiveInvertedTildeKinematics.h +++ b/MatrixElement/Matchbox/Phasespace/FFMassiveInvertedTildeKinematics.h @@ -1,179 +1,164 @@ // -*- C++ -*- // // FFMassiveInvertedTildeKinematics.h is a part of Herwig - A multi-purpose Monte Carlo event generator // Copyright (C) 2002-2019 The Herwig Collaboration // // Herwig is licenced under version 3 of the GPL, see COPYING for details. // Please respect the MCnet academic guidelines, see GUIDELINES for details. // #ifndef HERWIG_FFMassiveInvertedTildeKinematics_H #define HERWIG_FFMassiveInvertedTildeKinematics_H // // This is the declaration of the FFMassiveInvertedTildeKinematics class. // #include "Herwig/MatrixElement/Matchbox/Phasespace/InvertedTildeKinematics.h" namespace Herwig { using namespace ThePEG; /** * \ingroup Matchbox * \author Simon Platzer, Stephen Webster * * \brief FFMassiveInvertedTildeKinematics inverts the final-final tilde * kinematics. * */ class FFMassiveInvertedTildeKinematics: public Herwig::InvertedTildeKinematics { public: - /** @name Standard constructors and destructors. */ - //@{ - /** - * The default constructor. - */ - FFMassiveInvertedTildeKinematics(); - - /** - * The destructor. - */ - virtual ~FFMassiveInvertedTildeKinematics(); - //@} - -public: - /** * Perform the mapping of the tilde kinematics for the * last selected process and store all dimensionless * variables in the subtractionParameters() vector. * Return false, if the calculation of the real * kinematics was impossible for the selected configuration * and true on success. */ virtual bool doMap(const double *); /** * Return the pt associated to the last generated splitting. */ virtual Energy lastPt() const; /** * Return the momentum fraction associated to the last splitting. */ virtual double lastZ() const; /** * Return the upper bound on pt */ virtual Energy ptMax() const; /** * Given a pt, return the boundaries on z * Note that allowing parton masses these bounds may be too loose */ virtual pair zBounds(Energy pt, Energy hardPt = ZERO) const; /** * For generated pt and z, check if this point is * kinematically allowed */ /*virtual*/ bool ptzAllowed(pair ptz, vector* values ) const; /** * Generate pt and z */ virtual pair generatePtZ(double& jac, const double * r, vector* values) const; public: /** * Triangular / Kallen function */ template inline T rootOfKallen (T a, T b, T c) const { return sqrt( a*a + b*b + c*c - 2.*( a*b+a*c+b*c ) ); } // TODO: remove in both /** * stolen from FFMassiveKinematics.h * 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 rotateToZ (Lorentz5Momentum& pTarget, Lorentz5Momentum& p1) { ThreeVector 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 assignment operator is private and must never be called. * In fact, it should not even be implemented. */ FFMassiveInvertedTildeKinematics & operator=(const FFMassiveInvertedTildeKinematics &) = delete; }; } #endif /* HERWIG_FFMassiveInvertedTildeKinematics_H */ diff --git a/MatrixElement/Matchbox/Phasespace/FFMassiveTildeKinematics.cc b/MatrixElement/Matchbox/Phasespace/FFMassiveTildeKinematics.cc --- a/MatrixElement/Matchbox/Phasespace/FFMassiveTildeKinematics.cc +++ b/MatrixElement/Matchbox/Phasespace/FFMassiveTildeKinematics.cc @@ -1,232 +1,227 @@ // -*- C++ -*- // // FFMassiveTildeKinematics.cc is a part of Herwig - A multi-purpose Monte Carlo event generator // Copyright (C) 2002-2019 The Herwig Collaboration // // Herwig is licenced under version 3 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 FFMassiveTildeKinematics class. // #include "FFMassiveTildeKinematics.h" #include "ThePEG/Interface/ClassDocumentation.h" #include "ThePEG/Utilities/DescribeClass.h" - #include "ThePEG/Persistency/PersistentOStream.h" #include "ThePEG/Persistency/PersistentIStream.h" using namespace Herwig; -FFMassiveTildeKinematics::FFMassiveTildeKinematics() {} - -FFMassiveTildeKinematics::~FFMassiveTildeKinematics() {} - IBPtr FFMassiveTildeKinematics::clone() const { return new_ptr(*this); } IBPtr FFMassiveTildeKinematics::fullclone() const { return new_ptr(*this); } // Matches Stephen Webster's thesis bool FFMassiveTildeKinematics::doMap() { Lorentz5Momentum emitter = realEmitterMomentum(); Lorentz5Momentum emission = realEmissionMomentum(); Lorentz5Momentum spectator = realSpectatorMomentum(); // Compute y double y = emission*emitter / (emission*emitter + emission*spectator + emitter*spectator); // Calculate the scale Lorentz5Momentum pTot = emitter+emission+spectator; Energy scale = pTot.m(); // masses double mui2 = sqr( realEmitterData()->hardProcessMass() / scale ); double muj2 = sqr( realEmissionData()->hardProcessMass() / scale ); double muk2 = sqr( realSpectatorData()->hardProcessMass() / scale ); double Muij2 = sqr( bornEmitterData()->hardProcessMass() / scale ); double Muk2 = sqr( bornSpectatorData()->hardProcessMass() / scale ); // Calculate the invariants Energy2 Qijk = sqr(scale); double sijkN = 0.5*( 1. - Muij2 - Muk2 + sqrt( sqr(1.-Muij2-Muk2) - 4.*Muij2*Muk2 ) ); double bar = 1. - mui2 - muj2 - muk2; // Calculate Qij2 double QijN2 = sqr(emitter + emission)/Qijk; // Calculate the scale factors, xk and xij double lambdaK = 1. + (Muk2/sijkN); double lambdaIJ = 1. + (Muij2/sijkN); double fac1 = lambdaIJ*lambdaK + (muk2 - QijN2)/sijkN; double xk = ( fac1 + sqrt( sqr(fac1) - 4.*lambdaIJ*lambdaK*muk2/sijkN ) ) / 2. / lambdaK ; double xij = 1. - muk2*(1.-xk) / xk / sijkN; // Calculate z = qi.nk / (qi+qj).nk from qi.qk and y double l = Muk2 / (2.*xk*xij*sijkN); double a = (xij*xk*sijkN/2.) - l*(bar*y + mui2 + muj2); double b = (-emitter*spectator)/Qijk + l*(bar*y + 2.*mui2); double z = -b/a; // Calculate zi double zi = emitter*spectator / ((emitter + emission)*spectator); // Store the variables subtractionParameters().resize(3); subtractionParameters()[0] = y; subtractionParameters()[1] = zi; subtractionParameters()[2] = z; // Calculate nij and nk from qi, q, qj double L = QijN2/xij/xk/sijkN; Lorentz5Momentum nij = (emitter + emission - L*spectator)/(xij - L*Muk2/xk/sijkN); Lorentz5Momentum nk = (1./xk)*(spectator - Muk2*nij/(xk*sijkN)); // Calculate the born momenta from nij and nk bornSpectatorMomentum() = nk + (Muk2/sijkN)*nij; bornEmitterMomentum() = pTot - bornSpectatorMomentum(); bornEmitterMomentum().setMass( bornEmitterData()->hardProcessMass() ); bornEmitterMomentum().rescaleEnergy(); bornSpectatorMomentum().setMass( bornSpectatorData()->hardProcessMass() ); bornSpectatorMomentum().rescaleEnergy(); return true; } Energy FFMassiveTildeKinematics::lastPt() const { Energy scale = (bornEmitterMomentum()+bornSpectatorMomentum()).m(); double y = subtractionParameters()[0]; double z = subtractionParameters()[2]; // masses double mui2 = sqr( realEmitterData()->hardProcessMass() / scale ); double muj2 = sqr( realEmissionData()->hardProcessMass() / scale ); double muk2 = sqr( realSpectatorData()->hardProcessMass() / scale ); Energy ret = scale * sqrt( y * (1.-mui2-muj2-muk2) * z*(1.-z) - sqr(1.-z)*mui2 - sqr(z)*muj2 ); return ret; } // Matches Stephen Webster's thesis Energy FFMassiveTildeKinematics::lastPt(Lorentz5Momentum emitter, Lorentz5Momentum emission, Lorentz5Momentum spectator)const { // Compute y double y = emission*emitter / (emission*emitter + emission*spectator + emitter*spectator); // Calculate the scale Lorentz5Momentum pTot = emitter+emission+spectator; Energy scale = pTot.m(); // masses double mui2 = sqr( emitter.mass() / scale ); double muj2 = sqr( emission.mass() / scale ); double muk2 = sqr( spectator.mass() / scale ); // TODO: here we assume a gluon bool isgluon= emitter.mass()==emission.mass(); double Muij2 = sqr(( isgluon?ZERO:max(emission.mass(),emitter.mass()) )/ scale ); double Muk2 = sqr( spectator.mass() / scale ); // Calculate the invariants Energy2 Qijk = sqr(scale); double sijkN = 0.5*( 1. - Muij2 - Muk2 + sqrt( sqr(1.-Muij2-Muk2) - 4.*Muij2*Muk2 ) ); double bar = 1. - mui2 - muj2 - muk2; // Calculate Qij2 double QijN2 = sqr(emitter + emission)/Qijk; // Calculate the scale factors, xk and xij double lambdaK = 1. + (Muk2/sijkN); double lambdaIJ = 1. + (Muij2/sijkN); double fac1 = lambdaIJ*lambdaK + (muk2 - QijN2)/sijkN; double xk = ( fac1 + sqrt( sqr(fac1) - 4.*lambdaIJ*lambdaK*muk2/sijkN ) ) / 2. / lambdaK ; double xij = 1. - muk2*(1.-xk) / xk / sijkN; // Calculate z = qi.nk / (qi+qj).nk from qi.qk and y double l = Muk2 / (2.*xk*xij*sijkN); double a = (xij*xk*sijkN/2.) - l*(bar*y + mui2 + muj2); double b = (-emitter*spectator)/Qijk + l*(bar*y + 2.*mui2); double z = -b/a; Energy ret = scale * sqrt( z*(1.-z)*QijN2 - (1.-z)*mui2 - z*muj2 ); return ret; } // NOTE: bounds calculated at this step may be too loose pair FFMassiveTildeKinematics::zBounds(Energy pt, Energy hardPt) const { if(pt>hardPt) return make_pair(0.5,0.5); Energy scale = (bornEmitterMomentum()+bornSpectatorMomentum()).m(); // masses double mui2 = sqr( realEmitterData()->hardProcessMass() / scale ); double muj2 = sqr( realEmissionData()->hardProcessMass() / scale ); double muk2 = sqr( realSpectatorData()->hardProcessMass() / scale ); double zp = ( 1.+mui2-muj2+muk2-2.*sqrt(muk2) + rootOfKallen(mui2,muj2,sqr(1.-sqrt(muk2))) * sqrt( 1.-sqr(pt/hardPt) ) ) / ( 2.*sqr(1.-sqrt(muk2)) ); double zm = ( 1.+mui2-muj2+muk2-2.*sqrt(muk2) - rootOfKallen(mui2,muj2,sqr(1.-sqrt(muk2))) * sqrt( 1.-sqr(pt/hardPt) ) ) / ( 2.*sqr(1.-sqrt(muk2)) ); return make_pair(zm,zp); } double FFMassiveTildeKinematics::lastZ() const { return subtractionParameters()[2]; } // If needed, insert default implementations of virtual function defined // in the InterfacedBase class here (using ThePEG-interfaced-impl in Emacs). void FFMassiveTildeKinematics::persistentOutput(PersistentOStream &) const { } void FFMassiveTildeKinematics::persistentInput(PersistentIStream &, int) { } void FFMassiveTildeKinematics::Init() { static ClassDocumentation documentation ("FFMassiveTildeKinematics implements the 'tilde' kinematics for " "a final-final subtraction dipole involving a massive particle."); } // *** 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 describeHerwigFFMassiveTildeKinematics("Herwig::FFMassiveTildeKinematics", "Herwig.so"); diff --git a/MatrixElement/Matchbox/Phasespace/FFMassiveTildeKinematics.h b/MatrixElement/Matchbox/Phasespace/FFMassiveTildeKinematics.h --- a/MatrixElement/Matchbox/Phasespace/FFMassiveTildeKinematics.h +++ b/MatrixElement/Matchbox/Phasespace/FFMassiveTildeKinematics.h @@ -1,148 +1,133 @@ // -*- C++ -*- // // FFMassiveTildeKinematics.h is a part of Herwig - A multi-purpose Monte Carlo event generator // Copyright (C) 2002-2019 The Herwig Collaboration // // Herwig is licenced under version 3 of the GPL, see COPYING for details. // Please respect the MCnet academic guidelines, see GUIDELINES for details. // #ifndef HERWIG_FFMassiveTildeKinematics_H #define HERWIG_FFMassiveTildeKinematics_H // // This is the declaration of the FFMassiveTildeKinematics class. // #include "Herwig/MatrixElement/Matchbox/Phasespace/TildeKinematics.h" namespace Herwig { using namespace ThePEG; /** * \ingroup Matchbox * \author Simon Platzer, Stephen Webster * * \brief FFMassiveTildeKinematics implements the 'tilde' kinematics for * a final-final subtraction dipole. * */ class FFMassiveTildeKinematics: public TildeKinematics { public: - /** @name Standard constructors and destructors. */ - //@{ - /** - * The default constructor. - */ - FFMassiveTildeKinematics(); - - /** - * The destructor. - */ - virtual ~FFMassiveTildeKinematics(); - //@} - -public: - /** * Perform the mapping to the tilde kinematics for the * last selected process and store all dimensionless * variables in the subtractionParameters() vector. * Return false, if the calculation of the tilde * kinematics was impossible for the selected configuration * and true on success. */ virtual bool doMap(); /** * Return the pt associated to the last merged splitting. */ virtual Energy lastPt() const; /** * Given a pt, return the boundaries on z */ virtual pair zBounds(Energy pt, Energy hardPt ) const; /** * Return the pt associated to emitter emission and sppectator momentum. */ virtual Energy lastPt(Lorentz5Momentum,Lorentz5Momentum,Lorentz5Momentum) const ; /** * Return the momentum fraction associated to the last splitting. */ virtual double lastZ() const; public: /** * Triangular / Kallen function */ template inline T 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 assignment operator is private and must never be called. * In fact, it should not even be implemented. */ FFMassiveTildeKinematics & operator=(const FFMassiveTildeKinematics &) = delete; }; } #endif /* HERWIG_FFMassiveTildeKinematics_H */ diff --git a/MatrixElement/Matchbox/Phasespace/FILightInvertedTildeKinematics.cc b/MatrixElement/Matchbox/Phasespace/FILightInvertedTildeKinematics.cc --- a/MatrixElement/Matchbox/Phasespace/FILightInvertedTildeKinematics.cc +++ b/MatrixElement/Matchbox/Phasespace/FILightInvertedTildeKinematics.cc @@ -1,136 +1,132 @@ // -*- C++ -*- // // FILightInvertedTildeKinematics.cc is a part of Herwig - A multi-purpose Monte Carlo event generator // Copyright (C) 2002-2019 The Herwig Collaboration // // Herwig is licenced under version 3 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 FILightInvertedTildeKinematics class. // #include "FILightInvertedTildeKinematics.h" #include "ThePEG/Interface/ClassDocumentation.h" #include "ThePEG/Utilities/DescribeClass.h" #include "ThePEG/Persistency/PersistentOStream.h" #include "ThePEG/Persistency/PersistentIStream.h" using namespace Herwig; -FILightInvertedTildeKinematics::FILightInvertedTildeKinematics() {} - -FILightInvertedTildeKinematics::~FILightInvertedTildeKinematics() {} - IBPtr FILightInvertedTildeKinematics::clone() const { return new_ptr(*this); } IBPtr FILightInvertedTildeKinematics::fullclone() const { return new_ptr(*this); } bool FILightInvertedTildeKinematics::doMap(const double * r) { if ( ptMax() < ptCut() ) { jacobian(0.0); return false; } Lorentz5Momentum emitter = bornEmitterMomentum(); Lorentz5Momentum spectator = bornSpectatorMomentum(); double mapping = 1.0; pair ptz = generatePtZ(mapping,r); if ( mapping == 0.0 ) { jacobian(0.0); return false; } Energy pt = ptz.first; double z = ptz.second; double y = sqr(pt/lastScale())/(z*(1.-z)); double x = 1./(1.+y); if ( x < spectatorX() || x > 1. || z < 0. || z > 1. ) { jacobian(0.0); return false; } // This should (and does) have a factor of 1/x relative to // the dipole shower jacobian. mapping /= z*(1.-z); jacobian(mapping*(sqr(lastScale())/sHat())/(16.*sqr(Constants::pi))); double phi = 2.*Constants::pi*r[2]; Lorentz5Momentum kt = getKt(spectator,emitter,pt,phi,true); subtractionParameters().resize(2); subtractionParameters()[0] = x; subtractionParameters()[1] = z; realEmitterMomentum() = z*emitter + (1.-z)*((1.-x)/x)*spectator + kt; realEmissionMomentum() = (1.-z)*emitter + z*((1.-x)/x)*spectator - kt; realSpectatorMomentum() = (1./x)*spectator; realEmitterMomentum().setMass(ZERO); realEmitterMomentum().rescaleEnergy(); realEmissionMomentum().setMass(ZERO); realEmissionMomentum().rescaleEnergy(); realSpectatorMomentum().setMass(ZERO); realSpectatorMomentum().rescaleEnergy(); return true; } Energy FILightInvertedTildeKinematics::lastPt() const { Energy scale = sqrt(2.*(bornEmitterMomentum()*bornSpectatorMomentum())); double x = subtractionParameters()[0]; double z = subtractionParameters()[1]; return scale * sqrt(z*(1.-z)*(1.-x)/x); } double FILightInvertedTildeKinematics::lastZ() const { return subtractionParameters()[1]; } Energy FILightInvertedTildeKinematics::ptMax() const { double x = spectatorX(); return sqrt((1.-x)/x)*lastScale()/2.; } pair FILightInvertedTildeKinematics::zBounds(Energy pt, Energy hardPt) const { hardPt = hardPt == ZERO ? ptMax() : min(hardPt,ptMax()); if(pt>hardPt) return make_pair(0.5,0.5); double s = sqrt(1.-sqr(pt/hardPt)); return make_pair(0.5*(1.-s),0.5*(1.+s)); } void FILightInvertedTildeKinematics::persistentOutput(PersistentOStream &) const { } void FILightInvertedTildeKinematics::persistentInput(PersistentIStream &, int) { } void FILightInvertedTildeKinematics::Init() { static ClassDocumentation documentation ("FILightInvertedTildeKinematics inverts the final-initial tilde " "kinematics."); } // *** 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 describeHerwigFILightInvertedTildeKinematics("Herwig::FILightInvertedTildeKinematics", "Herwig.so"); diff --git a/MatrixElement/Matchbox/Phasespace/FILightInvertedTildeKinematics.h b/MatrixElement/Matchbox/Phasespace/FILightInvertedTildeKinematics.h --- a/MatrixElement/Matchbox/Phasespace/FILightInvertedTildeKinematics.h +++ b/MatrixElement/Matchbox/Phasespace/FILightInvertedTildeKinematics.h @@ -1,138 +1,123 @@ // -*- C++ -*- // // FILightInvertedTildeKinematics.h is a part of Herwig - A multi-purpose Monte Carlo event generator // Copyright (C) 2002-2019 The Herwig Collaboration // // Herwig is licenced under version 3 of the GPL, see COPYING for details. // Please respect the MCnet academic guidelines, see GUIDELINES for details. // #ifndef HERWIG_FILightInvertedTildeKinematics_H #define HERWIG_FILightInvertedTildeKinematics_H // // This is the declaration of the FILightInvertedTildeKinematics class. // #include "Herwig/MatrixElement/Matchbox/Phasespace/InvertedTildeKinematics.h" namespace Herwig { using namespace ThePEG; /** * \ingroup Matchbox * \author Simon Platzer * * \brief FILightInvertedTildeKinematics inverts the final-final tilde * kinematics. * */ class FILightInvertedTildeKinematics: public Herwig::InvertedTildeKinematics { public: - /** @name Standard constructors and destructors. */ - //@{ - /** - * The default constructor. - */ - FILightInvertedTildeKinematics(); - - /** - * The destructor. - */ - virtual ~FILightInvertedTildeKinematics(); - //@} - -public: - /** * Perform the mapping of the tilde kinematics for the * last selected process and store all dimensionless * variables in the subtractionParameters() vector. * Return false, if the calculation of the real * kinematics was impossible for the selected configuration * and true on success. */ virtual bool doMap(const double *); /** * Return the pt associated to the last generated splitting. */ virtual Energy lastPt() const; /** * Return the momentum fraction associated to the last splitting. */ virtual double lastZ() const; /** * Return the upper bound on pt */ virtual Energy ptMax() const; /** * Given a pt, return the boundaries on z */ virtual pair zBounds(Energy pt, Energy hardPt = ZERO) 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. */ FILightInvertedTildeKinematics & operator=(const FILightInvertedTildeKinematics &) = delete; }; } #endif /* HERWIG_FILightInvertedTildeKinematics_H */ diff --git a/MatrixElement/Matchbox/Phasespace/FILightTildeKinematics.cc b/MatrixElement/Matchbox/Phasespace/FILightTildeKinematics.cc --- a/MatrixElement/Matchbox/Phasespace/FILightTildeKinematics.cc +++ b/MatrixElement/Matchbox/Phasespace/FILightTildeKinematics.cc @@ -1,121 +1,116 @@ // -*- C++ -*- // // FILightTildeKinematics.cc is a part of Herwig - A multi-purpose Monte Carlo event generator // Copyright (C) 2002-2019 The Herwig Collaboration // // Herwig is licenced under version 3 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 FILightTildeKinematics class. // #include "FILightTildeKinematics.h" #include "ThePEG/Interface/ClassDocumentation.h" #include "ThePEG/Utilities/DescribeClass.h" - #include "ThePEG/Persistency/PersistentOStream.h" #include "ThePEG/Persistency/PersistentIStream.h" using namespace Herwig; -FILightTildeKinematics::FILightTildeKinematics() {} - -FILightTildeKinematics::~FILightTildeKinematics() {} - IBPtr FILightTildeKinematics::clone() const { return new_ptr(*this); } IBPtr FILightTildeKinematics::fullclone() const { return new_ptr(*this); } bool FILightTildeKinematics::doMap() { Lorentz5Momentum emitter = realEmitterMomentum(); Lorentz5Momentum emission = realEmissionMomentum(); Lorentz5Momentum spectator = realSpectatorMomentum(); double x = (- emission*emitter + emission*spectator + emitter*spectator) / (emitter*spectator + emission*spectator); double z = emitter*spectator / (emitter*spectator + emission*spectator); subtractionParameters().resize(2); subtractionParameters()[0] = x; subtractionParameters()[1] = z; bornEmitterMomentum() = emitter+emission-(1.-x)*spectator; bornSpectatorMomentum() = x*spectator; bornEmitterMomentum().setMass(ZERO); bornEmitterMomentum().rescaleEnergy(); bornSpectatorMomentum().setMass(ZERO); bornSpectatorMomentum().rescaleEnergy(); return true; } Energy FILightTildeKinematics::lastPt() const { Energy scale = sqrt(2.*(bornEmitterMomentum()*bornSpectatorMomentum())); double x = subtractionParameters()[0]; double z = subtractionParameters()[1]; return scale * sqrt(z*(1.-z)*(1.-x)/x); } Energy FILightTildeKinematics::lastPt(Lorentz5Momentum emitter,Lorentz5Momentum emission,Lorentz5Momentum spectator)const { Energy2 scale = - (emitter+emission-spectator).m2(); double x = (- emission*emitter + emission*spectator + emitter*spectator) / (emitter*spectator + emission*spectator); double z = emitter*spectator / (emitter*spectator + emission*spectator); return sqrt( z*(1.-z)*(1.-x)/x*scale ) ; } pair FILightTildeKinematics::zBounds(Energy pt, Energy hardPt) const { if(pt>hardPt) return make_pair(0.5,0.5); double s = sqrt(1.-sqr(pt/hardPt)); return make_pair(0.5*(1.-s),0.5*(1.+s)); } double FILightTildeKinematics::lastZ() const { return subtractionParameters()[1]; } // If needed, insert default implementations of virtual function defined // in the InterfacedBase class here (using ThePEG-interfaced-impl in Emacs). void FILightTildeKinematics::persistentOutput(PersistentOStream &) const { } void FILightTildeKinematics::persistentInput(PersistentIStream &, int) { } void FILightTildeKinematics::Init() { static ClassDocumentation documentation ("FILightTildeKinematics implements the 'tilde' kinematics for " "a final-initial subtraction dipole."); } // *** 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 describeHerwigFILightTildeKinematics("Herwig::FILightTildeKinematics", "Herwig.so"); diff --git a/MatrixElement/Matchbox/Phasespace/FILightTildeKinematics.h b/MatrixElement/Matchbox/Phasespace/FILightTildeKinematics.h --- a/MatrixElement/Matchbox/Phasespace/FILightTildeKinematics.h +++ b/MatrixElement/Matchbox/Phasespace/FILightTildeKinematics.h @@ -1,144 +1,129 @@ // -*- C++ -*- // // FILightTildeKinematics.h is a part of Herwig - A multi-purpose Monte Carlo event generator // Copyright (C) 2002-2019 The Herwig Collaboration // // Herwig is licenced under version 3 of the GPL, see COPYING for details. // Please respect the MCnet academic guidelines, see GUIDELINES for details. // #ifndef HERWIG_FILightTildeKinematics_H #define HERWIG_FILightTildeKinematics_H // // This is the declaration of the FILightTildeKinematics class. // #include "Herwig/MatrixElement/Matchbox/Phasespace/TildeKinematics.h" namespace Herwig { using namespace ThePEG; /** * \ingroup Matchbox * \author Simon Platzer * * \brief FILightTildeKinematics implements the 'tilde' kinematics for * a final-initial subtraction dipole. * */ class FILightTildeKinematics: public TildeKinematics { public: - /** @name Standard constructors and destructors. */ - //@{ - /** - * The default constructor. - */ - FILightTildeKinematics(); - - /** - * The destructor. - */ - virtual ~FILightTildeKinematics(); - //@} - -public: - /** * Perform the mapping to the tilde kinematics for the * last selected process and store all dimensionless * variables in the subtractionParameters() vector. * Return false, if the calculation of the tilde * kinematics was impossible for the selected configuration * and true on success. */ virtual bool doMap(); /** * Return the pt associated to the last merged splitting. */ virtual Energy lastPt() const; /** * Given a pt, return the boundaries on z */ virtual pair zBounds(Energy pt, Energy hardPt ) const; /** * Return the pt associated to emitter emission and sppectator momentum. */ virtual Energy lastPt(Lorentz5Momentum,Lorentz5Momentum,Lorentz5Momentum) const ; /** * Return the momentum fraction associated to the last splitting. */ virtual double lastZ() const; /* * True if phase space point is above the alpha cut for this dipole. */ bool aboveAlpha() const {return dipole()->alpha()<1.-subtractionParameters()[0];} 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. */ FILightTildeKinematics & operator=(const FILightTildeKinematics &) = delete; }; } #endif /* HERWIG_FILightTildeKinematics_H */ diff --git a/MatrixElement/Matchbox/Phasespace/FIMassiveInvertedTildeKinematics.cc b/MatrixElement/Matchbox/Phasespace/FIMassiveInvertedTildeKinematics.cc --- a/MatrixElement/Matchbox/Phasespace/FIMassiveInvertedTildeKinematics.cc +++ b/MatrixElement/Matchbox/Phasespace/FIMassiveInvertedTildeKinematics.cc @@ -1,182 +1,178 @@ // -*- C++ -*- // // FIMassiveInvertedTildeKinematics.cc is a part of Herwig - A multi-purpose Monte Carlo event generator // Copyright (C) 2002-2019 The Herwig Collaboration // // Herwig is licenced under version 3 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 FIMassiveInvertedTildeKinematics class. // #include "FIMassiveInvertedTildeKinematics.h" #include "ThePEG/Interface/ClassDocumentation.h" #include "ThePEG/Utilities/DescribeClass.h" #include "ThePEG/Persistency/PersistentOStream.h" #include "ThePEG/Persistency/PersistentIStream.h" using namespace Herwig; -FIMassiveInvertedTildeKinematics::FIMassiveInvertedTildeKinematics() {} - -FIMassiveInvertedTildeKinematics::~FIMassiveInvertedTildeKinematics() {} - IBPtr FIMassiveInvertedTildeKinematics::clone() const { return new_ptr(*this); } IBPtr FIMassiveInvertedTildeKinematics::fullclone() const { return new_ptr(*this); } bool FIMassiveInvertedTildeKinematics::doMap(const double * r) { if ( ptMax() < ptCut() ) { jacobian(0.0); return false; } Lorentz5Momentum emitter = bornEmitterMomentum(); Lorentz5Momentum spectator = bornSpectatorMomentum(); double mapping = 1.0; pair ptz = generatePtZ(mapping,r); if ( mapping == 0.0 ) { jacobian(0.0); return false; } Energy pt = ptz.first; double z = ptz.second; Energy2 mi2 = sqr(realEmitterData()->hardProcessMass()); Energy2 m2 = sqr(realEmissionData()->hardProcessMass()); Energy2 Mi2 = sqr(bornEmitterData()->hardProcessMass()); Energy2 scale=2.*emitter*spectator; double y = (pt*pt+(1.-z)*mi2+z*m2-z*(1.-z)*Mi2) / (z*(1.-z)*scale); double x = 1./(1.+y); if ( x < spectatorX() ) { jacobian(0.0); return false; } // SW 05/12/2016: Checked this is correct // This should appear to have a factor of 1/x relative // to the dipole shower jacobian. It is cancelled by ratios of // real and born cross sections in the units. mapping /= z*(1.-z); jacobian(mapping*(sqr(lastScale())/sHat())/(16.*sqr(Constants::pi))); double phi = 2.*Constants::pi*r[2]; Lorentz5Momentum kt = getKt(spectator,emitter,pt,phi,true); subtractionParameters().resize(2); subtractionParameters()[0] = x; subtractionParameters()[1] = z; realEmitterMomentum() = z*emitter + (sqr(pt)+mi2-z*z*Mi2)/(z*scale)*spectator + kt; realEmissionMomentum() = (1.-z)*emitter + (pt*pt+m2-sqr(1.-z)*Mi2)/((1.-z)*scale)*spectator - kt; realSpectatorMomentum() = (1.+y)*spectator; double mui2 = x*mi2/scale; double mu2 = x*m2/scale; double Mui2 = x*Mi2/scale; double xp = 1. + Mui2 - sqr(sqrt(mui2)+sqrt(mu2)); double zm = .5*( 1.-x+Mui2+mui2-mu2 - sqrt( sqr(1.-x+Mui2-mui2-mu2)-4.*mui2*mu2 ) ) / (1.-x+Mui2); double zp = .5*( 1.-x+Mui2+mui2-mu2 + sqrt( sqr(1.-x+Mui2-mui2-mu2)-4.*mui2*mu2 ) ) / (1.-x+Mui2); if ( x > xp || z < zm || z > zp ) { jacobian(0.0); return false; } realEmitterMomentum().setMass(sqrt(mi2)); realEmitterMomentum().rescaleEnergy(); realEmissionMomentum().setMass(sqrt(m2)); realEmissionMomentum().rescaleEnergy(); realSpectatorMomentum().setMass(ZERO); realSpectatorMomentum().rescaleEnergy(); return true; } Energy FIMassiveInvertedTildeKinematics::lastPt() const { Energy2 mi2 = sqr(realEmitterData()->hardProcessMass()); Energy2 m2 = sqr(realEmissionData()->hardProcessMass()); Energy2 Mi2 = sqr(bornEmitterData()->hardProcessMass()); Energy2 scale = Mi2 - (realEmitterMomentum()+realEmissionMomentum()-realSpectatorMomentum()).m2(); double x = subtractionParameters()[0]; double z = subtractionParameters()[1]; return sqrt( z*(1.-z)*(1.-x)/x*scale - ((1.-z)*mi2+z*m2-z*(1.-z)*Mi2) ); } double FIMassiveInvertedTildeKinematics::lastZ() const { return subtractionParameters()[1]; } Energy FIMassiveInvertedTildeKinematics::ptMax() const { Energy2 mi2 = sqr(realEmitterData()->hardProcessMass()); Energy2 m2 = sqr(realEmissionData()->hardProcessMass()); Energy2 Mi2 = sqr(bornEmitterData()->hardProcessMass()); double x = spectatorX(); // s^star/x Energy2 scale=2.*bornEmitterMomentum()*bornSpectatorMomentum(); Energy2 s = scale * (1.-x)/x + Mi2; Energy ptmax = .5 * sqrt(s) * rootOfKallen( s/s, mi2/s, m2/s ); return ptmax > 0.*GeV ? ptmax : 0.*GeV; } pair FIMassiveInvertedTildeKinematics::zBounds(Energy pt, Energy hardPt) const { hardPt = hardPt == ZERO ? ptMax() : min(hardPt,ptMax()); if(pt>hardPt) return make_pair(0.5,0.5); Energy2 mi2 = sqr(realEmitterData()->hardProcessMass()); Energy2 m2 = sqr(realEmissionData()->hardProcessMass()); Energy2 Mi2 = sqr(bornEmitterData()->hardProcessMass()); // s^star/x Energy2 scale=2.*bornEmitterMomentum()*bornSpectatorMomentum(); Energy2 s = scale * (1.-spectatorX())/spectatorX() + Mi2; double zm = .5*( 1.+(mi2-m2)/s - rootOfKallen(s/s,mi2/s,m2/s) * sqrt( 1.-sqr(pt/hardPt) ) ); double zp = .5*( 1.+(mi2-m2)/s + rootOfKallen(s/s,mi2/s,m2/s) * sqrt( 1.-sqr(pt/hardPt) ) ); return make_pair(zm, zp); } // If needed, insert default implementations of virtual function defined // in the InterfacedBase class here (using ThePEG-interfaced-impl in Emacs). void FIMassiveInvertedTildeKinematics::persistentOutput(PersistentOStream &) const { } void FIMassiveInvertedTildeKinematics::persistentInput(PersistentIStream &, int) { } void FIMassiveInvertedTildeKinematics::Init() { static ClassDocumentation documentation ("FIMassiveInvertedTildeKinematics inverts the final-initial tilde " "kinematics involving a massive particle."); } // *** 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 describeHerwigFIMassiveInvertedTildeKinematics("Herwig::FIMassiveInvertedTildeKinematics", "Herwig.so"); diff --git a/MatrixElement/Matchbox/Phasespace/FIMassiveInvertedTildeKinematics.h b/MatrixElement/Matchbox/Phasespace/FIMassiveInvertedTildeKinematics.h --- a/MatrixElement/Matchbox/Phasespace/FIMassiveInvertedTildeKinematics.h +++ b/MatrixElement/Matchbox/Phasespace/FIMassiveInvertedTildeKinematics.h @@ -1,147 +1,132 @@ // -*- C++ -*- // // FIMassiveInvertedTildeKinematics.h is a part of Herwig - A multi-purpose Monte Carlo event generator // Copyright (C) 2002-2019 The Herwig Collaboration // // Herwig is licenced under version 3 of the GPL, see COPYING for details. // Please respect the MCnet academic guidelines, see GUIDELINES for details. // #ifndef HERWIG_FIMassiveInvertedTildeKinematics_H #define HERWIG_FIMassiveInvertedTildeKinematics_H // // This is the declaration of the FIMassiveInvertedTildeKinematics class. // #include "Herwig/MatrixElement/Matchbox/Phasespace/InvertedTildeKinematics.h" namespace Herwig { using namespace ThePEG; /** * \ingroup Matchbox * \author Simon Platzer, Martin Stoll * * \brief FIMassiveInvertedTildeKinematics inverts the final-final tilde * kinematics. * */ class FIMassiveInvertedTildeKinematics: public Herwig::InvertedTildeKinematics { public: - /** @name Standard constructors and destructors. */ - //@{ - /** - * The default constructor. - */ - FIMassiveInvertedTildeKinematics(); - - /** - * The destructor. - */ - virtual ~FIMassiveInvertedTildeKinematics(); - //@} - -public: - /** * Perform the mapping of the tilde kinematics for the * last selected process and store all dimensionless * variables in the subtractionParameters() vector. * Return false, if the calculation of the real * kinematics was impossible for the selected configuration * and true on success. */ virtual bool doMap(const double *); /** * Return the pt associated to the last generated splitting. */ virtual Energy lastPt() const; /** * Return the momentum fraction associated to the last splitting. */ virtual double lastZ() const; /** * Return the upper bound on pt */ virtual Energy ptMax() const; /** * Given a pt, return the boundaries on z */ virtual pair zBounds(Energy pt, Energy hardPt = ZERO) const; public: /** * Triangular / Kallen function */ template inline T 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 assignment operator is private and must never be called. * In fact, it should not even be implemented. */ FIMassiveInvertedTildeKinematics & operator=(const FIMassiveInvertedTildeKinematics &) = delete; }; } #endif /* HERWIG_FIMassiveInvertedTildeKinematics_H */ diff --git a/MatrixElement/Matchbox/Phasespace/FIMassiveTildeKinematics.cc b/MatrixElement/Matchbox/Phasespace/FIMassiveTildeKinematics.cc --- a/MatrixElement/Matchbox/Phasespace/FIMassiveTildeKinematics.cc +++ b/MatrixElement/Matchbox/Phasespace/FIMassiveTildeKinematics.cc @@ -1,149 +1,144 @@ // -*- C++ -*- // // FIMassiveTildeKinematics.cc is a part of Herwig - A multi-purpose Monte Carlo event generator // Copyright (C) 2002-2019 The Herwig Collaboration // // Herwig is licenced under version 3 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 FIMassiveTildeKinematics class. // #include "FIMassiveTildeKinematics.h" #include "ThePEG/Interface/ClassDocumentation.h" #include "ThePEG/Utilities/DescribeClass.h" - #include "ThePEG/Persistency/PersistentOStream.h" #include "ThePEG/Persistency/PersistentIStream.h" using namespace Herwig; -FIMassiveTildeKinematics::FIMassiveTildeKinematics() {} - -FIMassiveTildeKinematics::~FIMassiveTildeKinematics() {} - IBPtr FIMassiveTildeKinematics::clone() const { return new_ptr(*this); } IBPtr FIMassiveTildeKinematics::fullclone() const { return new_ptr(*this); } bool FIMassiveTildeKinematics::doMap() { Lorentz5Momentum emitter = realEmitterMomentum(); Lorentz5Momentum emission = realEmissionMomentum(); Lorentz5Momentum spectator = realSpectatorMomentum(); Energy2 mi2 = sqr(realEmitterData()->hardProcessMass()); Energy2 m2 = sqr(realEmissionData()->hardProcessMass()); Energy2 Mi2 = sqr(bornEmitterData()->hardProcessMass()); double x = (- emission*emitter + emission*spectator + emitter*spectator + 0.5*(Mi2-mi2-m2)) / (emitter*spectator + emission*spectator); double z = emitter*spectator / (emitter*spectator + emission*spectator); subtractionParameters().resize(2); subtractionParameters()[0] = x; subtractionParameters()[1] = z; bornEmitterMomentum() = emitter+emission-(1.-x)*spectator; bornSpectatorMomentum() = x*spectator; bornEmitterMomentum().setMass(bornEmitterData()->hardProcessMass()); bornEmitterMomentum().rescaleEnergy(); bornSpectatorMomentum().setMass(bornSpectatorData()->hardProcessMass()); bornSpectatorMomentum().rescaleEnergy(); return true; } Energy FIMassiveTildeKinematics::lastPt() const { Energy2 Mi2 = sqr(bornEmitterData()->hardProcessMass()); Energy2 mi2 = sqr(realEmitterData()->hardProcessMass()); Energy2 m2 = sqr(realEmissionData()->hardProcessMass()); Energy2 scale = Mi2 - (realEmitterMomentum()+realEmissionMomentum()-realSpectatorMomentum()).m2(); double x = subtractionParameters()[0]; double z = subtractionParameters()[1]; return sqrt( z*(1.-z)*(1.-x)/x*scale - ((1.-z)*mi2+z*m2-z*(1.-z)*Mi2) ); } Energy FIMassiveTildeKinematics::lastPt(Lorentz5Momentum emitter,Lorentz5Momentum emission,Lorentz5Momentum spectator)const { // g->QQ or Q -> Qg Energy2 Mi2 = emitter.m()==emission.m()?0.*GeV2:max(emitter.m2(),emission.m2()); Energy2 mi2 = emitter.m2(); Energy2 m2 = emission.m2(); Energy2 scale = Mi2 - (emitter+emission-spectator).m2(); double x = (- emission*emitter + emission*spectator + emitter*spectator + 0.5*(Mi2-mi2-m2)) / (emitter*spectator + emission*spectator); double z = emitter*spectator / (emitter*spectator + emission*spectator); return sqrt( z*(1.-z)*(1.-x)/x*scale - ((1.-z)*mi2+z*m2-z*(1.-z)*Mi2) ); } pair FIMassiveTildeKinematics::zBounds(Energy pt, Energy hardPt) const { if(pt>hardPt) return make_pair(0.5,0.5); Energy2 mi2 = sqr(realEmitterData()->hardProcessMass()); Energy2 m2 = sqr(realEmissionData()->hardProcessMass()); Energy2 Mi2 = sqr(bornEmitterData()->hardProcessMass()); // s^star/x Energy2 scale=2.*bornEmitterMomentum()*bornSpectatorMomentum(); Energy2 s = scale * (1.-spectatorX())/spectatorX() + Mi2; double zm = .5*( 1.+(mi2-m2)/s - rootOfKallen(s/s,mi2/s,m2/s) * sqrt( 1.-sqr(pt/hardPt) ) ); double zp = .5*( 1.+(mi2-m2)/s + rootOfKallen(s/s,mi2/s,m2/s) * sqrt( 1.-sqr(pt/hardPt) ) ); return make_pair(zm, zp); } double FIMassiveTildeKinematics::lastZ() const { return subtractionParameters()[1]; } // If needed, insert default implementations of virtual function defined // in the InterfacedBase class here (using ThePEG-interfaced-impl in Emacs). void FIMassiveTildeKinematics::persistentOutput(PersistentOStream &) const { } void FIMassiveTildeKinematics::persistentInput(PersistentIStream &, int) { } void FIMassiveTildeKinematics::Init() { static ClassDocumentation documentation ("FIMassiveTildeKinematics implements the 'tilde' kinematics for " "a final-initial subtraction dipole involving a massive particle."); } // *** 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 describeHerwigFIMassiveTildeKinematics("Herwig::FIMassiveTildeKinematics", "Herwig.so"); diff --git a/MatrixElement/Matchbox/Phasespace/FIMassiveTildeKinematics.h b/MatrixElement/Matchbox/Phasespace/FIMassiveTildeKinematics.h --- a/MatrixElement/Matchbox/Phasespace/FIMassiveTildeKinematics.h +++ b/MatrixElement/Matchbox/Phasespace/FIMassiveTildeKinematics.h @@ -1,144 +1,129 @@ // -*- C++ -*- // // FIMassiveTildeKinematics.h is a part of Herwig - A multi-purpose Monte Carlo event generator // Copyright (C) 2002-2019 The Herwig Collaboration // // Herwig is licenced under version 3 of the GPL, see COPYING for details. // Please respect the MCnet academic guidelines, see GUIDELINES for details. // #ifndef HERWIG_FIMassiveTildeKinematics_H #define HERWIG_FIMassiveTildeKinematics_H // // This is the declaration of the FIMassiveTildeKinematics class. // #include "Herwig/MatrixElement/Matchbox/Phasespace/TildeKinematics.h" namespace Herwig { using namespace ThePEG; /** * \ingroup Matchbox * \author Simon Platzer, Martin Stoll * * \brief FIMassiveTildeKinematics implements the 'tilde' kinematics for * a final-initial subtraction dipole. * */ class FIMassiveTildeKinematics: public TildeKinematics { public: - /** @name Standard constructors and destructors. */ - //@{ - /** - * The default constructor. - */ - FIMassiveTildeKinematics(); - - /** - * The destructor. - */ - virtual ~FIMassiveTildeKinematics(); - //@} - -public: - /** * Perform the mapping to the tilde kinematics for the * last selected process and store all dimensionless * variables in the subtractionParameters() vector. * Return false, if the calculation of the tilde * kinematics was impossible for the selected configuration * and true on success. */ virtual bool doMap(); /** * Return the pt associated to the last merged splitting. */ virtual Energy lastPt() const; /** * Return the pt associated to emitter emission and sppectator momentum. */ virtual Energy lastPt(Lorentz5Momentum,Lorentz5Momentum,Lorentz5Momentum) const ; /** * Given a pt, return the boundaries on z */ virtual pair zBounds(Energy pt, Energy hardPt ) const; /** * Return the momentum fraction associated to the last splitting. */ virtual double lastZ() const; public: /** * Triangular / Kallen function */ template inline T rootOfKallen (T a, T b, T c) const { return sqrt( a*a + b*b + c*c - 2.*( a*b+a*c+b*c ) ); } /** @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. */ FIMassiveTildeKinematics & operator=(const FIMassiveTildeKinematics &) = delete; }; } #endif /* HERWIG_FIMassiveTildeKinematics_H */ diff --git a/MatrixElement/Matchbox/Phasespace/FlatInvertibleLabframePhasespace.cc b/MatrixElement/Matchbox/Phasespace/FlatInvertibleLabframePhasespace.cc --- a/MatrixElement/Matchbox/Phasespace/FlatInvertibleLabframePhasespace.cc +++ b/MatrixElement/Matchbox/Phasespace/FlatInvertibleLabframePhasespace.cc @@ -1,171 +1,169 @@ // -*- C++ -*- // // FlatInvertiblePhasespace.cc is a part of Herwig - A multi-purpose Monte Carlo event generator // Copyright (C) 2002-2019 The Herwig Collaboration // // Herwig is licenced under version 3 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 FlatInvertibleLabframePhasespace class. // #include "FlatInvertibleLabframePhasespace.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; FlatInvertibleLabframePhasespace::FlatInvertibleLabframePhasespace() : theLogSHat(false) {} -FlatInvertibleLabframePhasespace::~FlatInvertibleLabframePhasespace() {} - IBPtr FlatInvertibleLabframePhasespace::clone() const { return new_ptr(*this); } IBPtr FlatInvertibleLabframePhasespace::fullclone() const { return new_ptr(*this); } double FlatInvertibleLabframePhasespace::invertTwoToNKinematics(const vector& momenta, double* r) const { double weight = 1.; Energy finalstatemass = 0*GeV; for ( vector::const_iterator p = momenta.begin()+2; p != momenta.end(); ++p ) finalstatemass += p->mass(); Lorentz5Momentum pinitial = momenta[0]+momenta[1]; Energy2 sh = pinitial.m2(); double tau = sh/lastS(); Energy2 shmax = lastCuts().sHatMax(); Energy2 shmin = max(lastCuts().sHatMin(),sqr(finalstatemass)); if (theLogSHat) { r[0] = log(sh/shmin)/log(shmax/shmin); weight *= tau*log(shmax/shmin); } else { r[0] = (sh-shmin)/(shmax-shmin); weight *= (shmax-shmin)/lastS(); } double ltau = log(tau); r[1] = 0.5 - pinitial.rapidity()/ltau; weight *= -ltau; vector Pcms = momenta; Boost toCMS = pinitial.findBoostToCM(); for ( vector::iterator pit = Pcms.begin(); pit != Pcms.end(); ++pit ) pit->boost(toCMS); weight *= FlatInvertiblePhasespace::invertTwoToNKinematics(Pcms, r+2); return weight; } double FlatInvertibleLabframePhasespace::generateTwoToNKinematics(const double* r, vector& momenta) { double weight = 1.; Energy finalstatemass = 0*GeV; for ( vector::const_iterator p = momenta.begin()+2; p != momenta.end(); ++p ) finalstatemass += p->mass(); Energy beamenergy = sqrt(lastS())/2.; Energy2 shmax = lastCuts().sHatMax(); Energy2 shmin = max(lastCuts().sHatMin(),sqr(finalstatemass)); Energy2 sh; double tau; if (theLogSHat) { sh = shmin*pow(shmax/shmin, r[0]); tau = sh/lastS(); weight *= tau*log(shmax/shmin); } else { sh = r[0]*(shmax-shmin)+shmin; tau = sh/lastS(); weight *= (shmax-shmin)/lastS(); } double ltau = log(tau); double y = ltau*(0.5 - r[1]); weight *= -ltau; double x1 = sqrt(tau)*exp(y); double x2 = sqrt(tau)*exp(-y); momenta[0] = Lorentz5Momentum(0*GeV,0*GeV,+x1*beamenergy,x1*beamenergy); momenta[1] = Lorentz5Momentum(0*GeV,0*GeV,-x2*beamenergy,x2*beamenergy); lastXCombPtr()->lastX1X2(make_pair(x1,x2)); lastXCombPtr()->lastSHat(sh); weight *= FlatInvertiblePhasespace::generateTwoToNKinematics(r+2, momenta); // find boost to the relevant partonic frame note final state kinematics are // always generated in the CMS for this phase space algorithm Boost boostinitial = (momenta[0]+momenta[1]).findBoostToCM(); for ( vector::iterator pit = momenta.begin()+2; pit != momenta.end(); ++pit ) pit->boost(-boostinitial); return weight; } // If needed, insert default implementations of virtual function defined // in the InterfacedBase class here (using ThePEG-interfaced-impl in Emacs). void FlatInvertibleLabframePhasespace::persistentOutput(PersistentOStream & os) const { os << theLogSHat; } void FlatInvertibleLabframePhasespace::persistentInput(PersistentIStream & is, int) { is >> theLogSHat; } // *** 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 describeHerwigFlatInvertibleLabframePhasespace("Herwig::FlatInvertibleLabframePhasespace", "Herwig.so"); void FlatInvertibleLabframePhasespace::Init() { static ClassDocumentation documentation ("FlatInvertibleLabframePhasespace implements flat, invertible phase space generation in the lab frame."); static Switch interfaceLogSHat ("LogSHat", "Generate a flat distribution in \\f$\\log(\\hat{s})\\f$.", &FlatInvertibleLabframePhasespace::theLogSHat, false, false, false); static SwitchOption interfaceLogSHatYes (interfaceLogSHat, "Yes", "Generate flat in \\f$\\log(\\hat{s})\\f$", true); static SwitchOption interfaceLogSHatNo (interfaceLogSHat, "No", "Generate flat in \\f$\\hat{s}\\f$", false); interfaceLogSHat.rank(-1); } diff --git a/MatrixElement/Matchbox/Phasespace/FlatInvertibleLabframePhasespace.h b/MatrixElement/Matchbox/Phasespace/FlatInvertibleLabframePhasespace.h --- a/MatrixElement/Matchbox/Phasespace/FlatInvertibleLabframePhasespace.h +++ b/MatrixElement/Matchbox/Phasespace/FlatInvertibleLabframePhasespace.h @@ -1,152 +1,144 @@ // -*- C++ -*- // // FlatInvertiblePhasespaceLabFrame.h is a part of Herwig - A multi-purpose Monte Carlo event generator // Copyright (C) 2002-2019 The Herwig Collaboration // // Herwig is licenced under version 3 of the GPL, see COPYING for details. // Please respect the MCnet academic guidelines, see GUIDELINES for details. // #ifndef Herwig_FlatInvertibleLabframePhasespace_H #define Herwig_FlatInvertibleLabframePhasespace_H // // This is the declaration of the FlatInvertibleLabframePhasespace class. // #include "Herwig/MatrixElement/Matchbox/Phasespace/FlatInvertiblePhasespace.h" namespace Herwig { using namespace ThePEG; /** * \ingroup Matchbox * \author Michael Rauch * * \brief FlatInvertibleLabframePhasespace implements flat, invertible phase space generation in the lab frame * */ class FlatInvertibleLabframePhasespace: public FlatInvertiblePhasespace { public: - /** @name Standard constructors and destructors. */ - //@{ /** * The default constructor. */ FlatInvertibleLabframePhasespace(); - /** - * The destructor. - */ - virtual ~FlatInvertibleLabframePhasespace(); - //@} - public: /** * Generate a phase space point and return its weight. */ virtual double generateTwoToNKinematics(const double*, vector& momenta); /** * Return the number of random numbers required to produce a given * multiplicity final state. */ virtual int nDimPhasespace(int nFinal) const { if ( nFinal == 1 ) return 3; return 3*nFinal - 2; } public: /** * 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; } /** * Invert the given phase space point to the random numbers which * would have generated it. */ virtual double invertTwoToNKinematics(const vector& momenta, double* r) const; private: /** * True if SHat should be generated flat in log(SHat/S), * false if SHat should be generated flat in SHat. */ bool theLogSHat; 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. */ FlatInvertibleLabframePhasespace & operator=(const FlatInvertibleLabframePhasespace &) = delete; }; } #endif /* Herwig_FlatInvertiblePhasespace_H */ diff --git a/MatrixElement/Matchbox/Phasespace/FlatInvertiblePhasespace.cc b/MatrixElement/Matchbox/Phasespace/FlatInvertiblePhasespace.cc --- a/MatrixElement/Matchbox/Phasespace/FlatInvertiblePhasespace.cc +++ b/MatrixElement/Matchbox/Phasespace/FlatInvertiblePhasespace.cc @@ -1,304 +1,299 @@ // -*- C++ -*- // // FlatInvertiblePhasespace.cc is a part of Herwig - A multi-purpose Monte Carlo event generator // Copyright (C) 2002-2019 The Herwig Collaboration // // Herwig is licenced under version 3 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); } 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; } double FlatInvertiblePhasespace::generateIntermediates(vector& 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])); } int kap = K.size() + 1; return flatWeights(kap); } double FlatInvertiblePhasespace::invertIntermediates(const vector& 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)); } int kap = K.size() + 1; return flatWeights(kap); } double FlatInvertiblePhasespace::generateIntermediates(vector& M, const vector& m, const double* r) const { size_t n = M.size() + 1; vector 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& M, const vector& m, double* r) const { size_t n = M.size() + 1; vector 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& P, Energy Ecm, const double* r) const { vector m; for ( vector::const_iterator p = P.begin() + 2; p != P.end(); ++p ) m.push_back(p->mass()); size_t n = P.size() - 2; vector 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].setX(q*cphi*s); P[i].setY(q*sphi*s); P[i].setZ(q*c); P[i].rescaleEnergy(); P[i].boost(Q.boostVector()); P[i].rescaleEnergy(); nextQ = Q - P[i]; nextQ.setMass(M[i-1]); nextQ.rescaleEnergy(); Q = nextQ; } P.back() = Q; return weight; } double FlatInvertiblePhasespace::invertKinematics(const vector& P, Energy Ecm, double* r) const { vector m; for ( vector::const_iterator p = P.begin() + 2; p != P.end(); ++p ) m.push_back(p->mass()); size_t n = P.size() - 2; vector M(n-1); M[0] = Ecm; vector 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]; 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::generateTwoToNKinematics(const double* r, vector& momenta) { double weight = generateKinematics(momenta,sqrt(lastXCombPtr()->lastSHat()),r); return weight; } long double FlatInvertiblePhasespace::flatWeights(int k) const{ using Constants::pi; if(k<2) { return -1; } else return pow((pi/2),(k-1)) * pow((2*pi),(4-3*k))/factorial(k-1)/factorial(k-2); } // 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 describeHerwigFlatInvertiblePhasespace("Herwig::FlatInvertiblePhasespace", "Herwig.so"); void FlatInvertiblePhasespace::Init() { static ClassDocumentation documentation ("FlatInvertiblePhasespace implements flat, invertible phase space generation."); } diff --git a/MatrixElement/Matchbox/Phasespace/FlatInvertiblePhasespace.h b/MatrixElement/Matchbox/Phasespace/FlatInvertiblePhasespace.h --- a/MatrixElement/Matchbox/Phasespace/FlatInvertiblePhasespace.h +++ b/MatrixElement/Matchbox/Phasespace/FlatInvertiblePhasespace.h @@ -1,204 +1,189 @@ // -*- C++ -*- // // FlatInvertiblePhasespace.h is a part of Herwig - A multi-purpose Monte Carlo event generator // Copyright (C) 2002-2019 The Herwig Collaboration // // Herwig is licenced under version 3 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: - /** * Generate a phase space point and return its weight. */ virtual double generateTwoToNKinematics(const double*, vector& momenta); /** * Return the number of random numbers required to produce a given * multiplicity final state. */ virtual int nDimPhasespace(int nFinal) const { if ( nFinal == 1 ) return 1; return 3*nFinal - 4; } 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 invertTwoToNKinematics(const vector& momenta, double* r) const { return invertKinematics(momenta,(momenta[0]+momenta[1]).m(),r); } 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& K, const double* r) const; /** * Invert intermediate masses for a massless final state */ double invertIntermediates(const vector& K, double* r) const; /** * Generate intermediate masses for a massive final state */ double generateIntermediates(vector& M, const vector& m, const double* r) const; /** * Invert intermediate masses for a massive final state */ double invertIntermediates(const vector& M, const vector& m, double* r) const; /** * Generate momenta in the CMS */ double generateKinematics(vector& P, Energy Ecm, const double* r) const; /** * Invert momenta in the CMS */ double invertKinematics(const vector& P, Energy Ecm, double* r) const; /** * Return the appropriate phase space weight, * Eq. 11 in 1308.2922 * with the factor (2 pi)^4/(2 pi)^(3n) included * and the SHat of the process divided out to have everything expressed in the units of the ThePEG conventions, i.e. * without the Q^2 factor */ long double flatWeights(int n) 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 &) = delete; }; } #endif /* Herwig_FlatInvertiblePhasespace_H */ diff --git a/MatrixElement/Matchbox/Phasespace/IFLightInvertedTildeKinematics.cc b/MatrixElement/Matchbox/Phasespace/IFLightInvertedTildeKinematics.cc --- a/MatrixElement/Matchbox/Phasespace/IFLightInvertedTildeKinematics.cc +++ b/MatrixElement/Matchbox/Phasespace/IFLightInvertedTildeKinematics.cc @@ -1,150 +1,145 @@ // -*- C++ -*- // // IFLightInvertedTildeKinematics.cc is a part of Herwig - A multi-purpose Monte Carlo event generator // Copyright (C) 2002-2019 The Herwig Collaboration // // Herwig is licenced under version 3 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 IFLightInvertedTildeKinematics class. // #include "IFLightInvertedTildeKinematics.h" #include "ThePEG/Interface/ClassDocumentation.h" #include "ThePEG/Utilities/DescribeClass.h" #include "ThePEG/Repository/EventGenerator.h" - #include "ThePEG/Persistency/PersistentOStream.h" #include "ThePEG/Persistency/PersistentIStream.h" using namespace Herwig; -IFLightInvertedTildeKinematics::IFLightInvertedTildeKinematics() {} - -IFLightInvertedTildeKinematics::~IFLightInvertedTildeKinematics() {} - IBPtr IFLightInvertedTildeKinematics::clone() const { return new_ptr(*this); } IBPtr IFLightInvertedTildeKinematics::fullclone() const { return new_ptr(*this); } bool IFLightInvertedTildeKinematics::doMap(const double * r) { if ( ptMax() < ptCut() ) { jacobian(0.0); return false; } Lorentz5Momentum emitter = bornEmitterMomentum(); Lorentz5Momentum spectator = bornSpectatorMomentum(); double mapping = 1.0; pair ptz = generatePtZ(mapping,r); if ( mapping == 0.0 ) { jacobian(0.0); return false; } Energy pt = ptz.first; double z = ptz.second; double ratio = sqr(pt/lastScale()); double rho = 1. - 4.*ratio*z*(1.-z) / sqr(1. - z + ratio); if ( rho < 0. ) { jacobian(0.0); return false; } double x = 0.5*(1./ratio)*(1.-z+ratio)*(1.-sqrt(rho)); double u = 0.5*(1./(1.-z))*(1.-z+ratio)*(1.-sqrt(rho)); if ( x < emitterX() || x > 1. || u < 0. || u > 1. ) { jacobian(0.0); return false; } // This jacobian is (1/x^2)*dx*du mapping *= (1.-x)/((1.-z)*(z*(1.-z)+sqr(x-z))); jacobian(mapping*(sqr(lastScale())/sHat())/(16.*sqr(Constants::pi))); double phi = 2.*Constants::pi*r[2]; Lorentz5Momentum kt = getKt(emitter,spectator,pt,phi,true); subtractionParameters().resize(2); subtractionParameters()[0] = x; subtractionParameters()[1] = u; realEmitterMomentum() = (1./x)*emitter; realEmissionMomentum() = ((1.-x)*(1.-u)/x)*emitter + u*spectator + kt; realSpectatorMomentum() = ((1.-x)*u/x)*emitter + (1.-u)*spectator - kt; realEmitterMomentum().setMass(ZERO); realEmitterMomentum().rescaleEnergy(); realEmissionMomentum().setMass(ZERO); realEmissionMomentum().rescaleEnergy(); realSpectatorMomentum().setMass(ZERO); realSpectatorMomentum().rescaleEnergy(); return true; } Energy IFLightInvertedTildeKinematics::lastPt() const { Energy scale = sqrt(2.*(bornEmitterMomentum()*bornSpectatorMomentum())); double x = subtractionParameters()[0]; double u = subtractionParameters()[1]; return scale * sqrt(u*(1.-u)*(1.-x)/x); } Energy IFLightInvertedTildeKinematics::ptMax() const { double x = emitterX(); return sqrt((1.-x)/x)*lastScale()/2.; } pair IFLightInvertedTildeKinematics::zBounds(Energy pt, Energy hardPt) const { hardPt = hardPt == ZERO ? ptMax() : min(hardPt,ptMax()); if(pt>hardPt) return make_pair(0.5,0.5); double s = sqrt(1.-sqr(pt/hardPt)); double x = emitterX(); return make_pair(0.5*(1.+x-(1.-x)*s),0.5*(1.+x+(1.-x)*s)); } double IFLightInvertedTildeKinematics::lastZ() const { double x = subtractionParameters()[0]; double u = subtractionParameters()[1]; return 1. - (1.-x)*(1.-u); } // If needed, insert default implementations of virtual function defined // in the InterfacedBase class here (using ThePEG-interfaced-impl in Emacs). void IFLightInvertedTildeKinematics::persistentOutput(PersistentOStream &) const { } void IFLightInvertedTildeKinematics::persistentInput(PersistentIStream &, int) { } void IFLightInvertedTildeKinematics::Init() { static ClassDocumentation documentation ("IFLightInvertedTildeKinematics inverts the initial-final tilde " "kinematics."); } // *** 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 describeHerwigIFLightInvertedTildeKinematics("Herwig::IFLightInvertedTildeKinematics", "Herwig.so"); diff --git a/MatrixElement/Matchbox/Phasespace/IFLightInvertedTildeKinematics.h b/MatrixElement/Matchbox/Phasespace/IFLightInvertedTildeKinematics.h --- a/MatrixElement/Matchbox/Phasespace/IFLightInvertedTildeKinematics.h +++ b/MatrixElement/Matchbox/Phasespace/IFLightInvertedTildeKinematics.h @@ -1,138 +1,123 @@ // -*- C++ -*- // // IFLightInvertedTildeKinematics.h is a part of Herwig - A multi-purpose Monte Carlo event generator // Copyright (C) 2002-2019 The Herwig Collaboration // // Herwig is licenced under version 3 of the GPL, see COPYING for details. // Please respect the MCnet academic guidelines, see GUIDELINES for details. // #ifndef HERWIG_IFLightInvertedTildeKinematics_H #define HERWIG_IFLightInvertedTildeKinematics_H // // This is the declaration of the IFLightInvertedTildeKinematics class. // #include "Herwig/MatrixElement/Matchbox/Phasespace/InvertedTildeKinematics.h" namespace Herwig { using namespace ThePEG; /** * \ingroup Matchbox * \author Simon Platzer * * \brief IFLightInvertedTildeKinematics inverts the final-final tilde * kinematics. * */ class IFLightInvertedTildeKinematics: public Herwig::InvertedTildeKinematics { public: - /** @name Standard constructors and destructors. */ - //@{ - /** - * The default constructor. - */ - IFLightInvertedTildeKinematics(); - - /** - * The destructor. - */ - virtual ~IFLightInvertedTildeKinematics(); - //@} - -public: - /** * Perform the mapping of the tilde kinematics for the * last selected process and store all dimensionless * variables in the subtractionParameters() vector. * Return false, if the calculation of the real * kinematics was impossible for the selected configuration * and true on success. */ virtual bool doMap(const double *); /** * Return the pt associated to the last generated splitting. */ virtual Energy lastPt() const; /** * Return the momentum fraction associated to the last splitting. */ virtual double lastZ() const; /** * Return the upper bound on pt */ virtual Energy ptMax() const; /** * Given a pt, return the boundaries on z */ virtual pair zBounds(Energy pt, Energy hardPt = ZERO) 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. */ IFLightInvertedTildeKinematics & operator=(const IFLightInvertedTildeKinematics &) = delete; }; } #endif /* HERWIG_IFLightInvertedTildeKinematics_H */ diff --git a/MatrixElement/Matchbox/Phasespace/IFLightTildeKinematics.cc b/MatrixElement/Matchbox/Phasespace/IFLightTildeKinematics.cc --- a/MatrixElement/Matchbox/Phasespace/IFLightTildeKinematics.cc +++ b/MatrixElement/Matchbox/Phasespace/IFLightTildeKinematics.cc @@ -1,123 +1,118 @@ // -*- C++ -*- // // IFLightTildeKinematics.cc is a part of Herwig - A multi-purpose Monte Carlo event generator // Copyright (C) 2002-2019 The Herwig Collaboration // // Herwig is licenced under version 3 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 IFLightTildeKinematics class. // #include "IFLightTildeKinematics.h" #include "ThePEG/Interface/ClassDocumentation.h" #include "ThePEG/Utilities/DescribeClass.h" - #include "ThePEG/Persistency/PersistentOStream.h" #include "ThePEG/Persistency/PersistentIStream.h" using namespace Herwig; -IFLightTildeKinematics::IFLightTildeKinematics() {} - -IFLightTildeKinematics::~IFLightTildeKinematics() {} - IBPtr IFLightTildeKinematics::clone() const { return new_ptr(*this); } IBPtr IFLightTildeKinematics::fullclone() const { return new_ptr(*this); } bool IFLightTildeKinematics::doMap() { Lorentz5Momentum emitter = realEmitterMomentum(); Lorentz5Momentum emission = realEmissionMomentum(); Lorentz5Momentum spectator = realSpectatorMomentum(); double x = (- emission*spectator + emitter*spectator + emitter*emission) / (emitter*emission + emitter*spectator); double u = emitter*emission / (emitter*emission + emitter*spectator); subtractionParameters().resize(2); subtractionParameters()[0] = x; subtractionParameters()[1] = u; bornEmitterMomentum() = x*emitter; bornSpectatorMomentum() = spectator + emission - (1.-x)*emitter; bornEmitterMomentum().setMass(ZERO); bornEmitterMomentum().rescaleEnergy(); bornSpectatorMomentum().setMass(ZERO); bornSpectatorMomentum().rescaleEnergy(); return true; } Energy IFLightTildeKinematics::lastPt() const { Energy scale = sqrt(2.*(bornEmitterMomentum()*bornSpectatorMomentum())); double x = subtractionParameters()[0]; double u = subtractionParameters()[1]; return scale * sqrt(u*(1.-u)*(1.-x)/x); } Energy IFLightTildeKinematics::lastPt(Lorentz5Momentum emitter,Lorentz5Momentum emission,Lorentz5Momentum spectator)const { double x = (- emission*spectator + emitter*spectator + emitter*emission) / (emitter*emission + emitter*spectator); double u = emitter*emission / (emitter*emission + emitter*spectator); Energy scale = sqrt(2.*(emission*emitter-emission*spectator+emitter*spectator)); return scale * sqrt(u*(1.-u)*(1.-x)/x); } pair IFLightTildeKinematics::zBounds(Energy pt, Energy hardPt) const { if(pt>hardPt) return make_pair(0.5,0.5); double s = sqrt(1.-sqr(pt/hardPt)); double x = emitterX(); return make_pair(0.5*(1.+x-(1.-x)*s),0.5*(1.+x+(1.-x)*s)); } double IFLightTildeKinematics::lastZ() const { double x = subtractionParameters()[0]; double u = subtractionParameters()[1]; return 1. - (1.-x)*(1.-u); } // If needed, insert default implementations of virtual function defined // in the InterfacedBase class here (using ThePEG-interfaced-impl in Emacs). void IFLightTildeKinematics::persistentOutput(PersistentOStream &) const { } void IFLightTildeKinematics::persistentInput(PersistentIStream &, int) { } void IFLightTildeKinematics::Init() { static ClassDocumentation documentation ("IFLightTildeKinematics implements the 'tilde' kinematics for " "a initial-final subtraction dipole."); } // *** 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 describeHerwigIFLightTildeKinematics("Herwig::IFLightTildeKinematics", "Herwig.so"); diff --git a/MatrixElement/Matchbox/Phasespace/IFLightTildeKinematics.h b/MatrixElement/Matchbox/Phasespace/IFLightTildeKinematics.h --- a/MatrixElement/Matchbox/Phasespace/IFLightTildeKinematics.h +++ b/MatrixElement/Matchbox/Phasespace/IFLightTildeKinematics.h @@ -1,146 +1,131 @@ // -*- C++ -*- // // IFLightTildeKinematics.h is a part of Herwig - A multi-purpose Monte Carlo event generator // Copyright (C) 2002-2019 The Herwig Collaboration // // Herwig is licenced under version 3 of the GPL, see COPYING for details. // Please respect the MCnet academic guidelines, see GUIDELINES for details. // #ifndef HERWIG_IFLightTildeKinematics_H #define HERWIG_IFLightTildeKinematics_H // // This is the declaration of the IFLightTildeKinematics class. // #include "Herwig/MatrixElement/Matchbox/Phasespace/TildeKinematics.h" namespace Herwig { using namespace ThePEG; /** * \ingroup Matchbox * \author Simon Platzer * * \brief IFLightTildeKinematics implements the 'tilde' kinematics for * a initial-final subtraction dipole. * */ class IFLightTildeKinematics: public TildeKinematics { public: - /** @name Standard constructors and destructors. */ - //@{ - /** - * The default constructor. - */ - IFLightTildeKinematics(); - - /** - * The destructor. - */ - virtual ~IFLightTildeKinematics(); - //@} - -public: - /** * Perform the mapping to the tilde kinematics for the * last selected process and store all dimensionless * variables in the subtractionParameters() vector. * Return false, if the calculation of the tilde * kinematics was impossible for the selected configuration * and true on success. */ virtual bool doMap(); /** * Return the pt associated to the last merged splitting. */ virtual Energy lastPt() const; /** * Return the pt associated to emitter emission and sppectator momentum. */ virtual Energy lastPt(Lorentz5Momentum,Lorentz5Momentum,Lorentz5Momentum) const ; /** * Return the momentum fraction associated to the last splitting. */ virtual double lastZ() const; /** * Given a pt, return the boundaries on z */ virtual pair zBounds(Energy pt, Energy hardPt ) const; /* * True if phase space point is above the alpha cut for this dipole. */ bool aboveAlpha() const {return dipole()->alpha() ptz = generatePtZ(mapping,r); if ( mapping == 0.0 ){ jacobian(0.0); return false; } Energy pt = ptz.first; double z = ptz.second; // Compute x and u double ratio = sqr(pt)/scale; double muk2 = sqr(bornSpectatorData()->hardProcessMass())/scale; double rho = 1. - 4.*ratio*(1.-muk2)*z*(1.-z)/sqr(1.-z+ratio); double x = 0.5*((1.-z+ratio)/(ratio*(1.-muk2))) * (1. - sqrt(rho)); double u = x*ratio / (1.-z); // Following Catani-Seymour paper double muk2CS = x*muk2; double up = (1.-x) / ( 1.-x + muk2CS ); if ( x < emitterX() || x > 1. || u < 0. || u > up ) { jacobian(0.0); return false; } // Store x and u subtractionParameters().resize(2); subtractionParameters()[0] = x; subtractionParameters()[1] = u; // jac = sajk*(1./x^2)*dx*du // Note - lastScale() is not equal to scale!!!!!!! double jac = u/x/(u + x - 2.*u*x*(1.-muk2))*scale/sqr(pt); mapping *= jac; jacobian( mapping*(sqr(lastScale())/sHat()) / (16.*sqr(Constants::pi)) ); // Compute the new momenta double phi = 2.*Constants::pi*r[2]; Lorentz5Momentum kt = getKt(emitter,spectator,pt,phi,true); realEmitterMomentum() = (1./x)*emitter; realEmissionMomentum() = ((1.-x)*(1.-u)/x - 2.*u*muk2)*emitter + u*spectator + kt; realSpectatorMomentum() = ((1.-x)*u/x + 2.*u*muk2)*emitter + (1.-u)*spectator - kt; realEmitterMomentum().setMass(ZERO); realEmitterMomentum().rescaleEnergy(); realEmissionMomentum().setMass(ZERO); realEmissionMomentum().rescaleEnergy(); realSpectatorMomentum().setMass(bornSpectatorData()->hardProcessMass()); realSpectatorMomentum().rescaleEnergy(); return true; } Energy IFMassiveInvertedTildeKinematics::lastPt() const { Energy2 scale = 2.*(bornEmitterMomentum()*bornSpectatorMomentum()); double muk2 = sqr(bornSpectatorData()->hardProcessMass())/scale; double x = subtractionParameters()[0]; double u = subtractionParameters()[1]; return sqrt(scale * ( u*(1.-u)*(1.-x)/x - u*u*muk2 )); } double IFMassiveInvertedTildeKinematics::lastZ() const { Energy2 scale = 2.*(bornEmitterMomentum()*bornSpectatorMomentum()); double muk2 = sqr(bornSpectatorData()->hardProcessMass())/scale; double x = subtractionParameters()[0]; double u = subtractionParameters()[1]; return u + x + u*x*(muk2-1.); } Energy IFMassiveInvertedTildeKinematics::ptMax() const { double xe = emitterX(); Energy2 scale = 2.*(bornEmitterMomentum()*bornSpectatorMomentum()); Energy2 A = scale*(1.-xe)/xe; Energy2 mk2 = sqr(bornSpectatorData()->hardProcessMass()); return 0.5*A/sqrt(mk2+A); } pair IFMassiveInvertedTildeKinematics::zBounds(Energy pt, Energy hardPt) const { hardPt = hardPt == ZERO ? ptMax() : min(hardPt,ptMax()); if(pt>hardPt) return make_pair(0.5,0.5); double s = sqrt(1.-sqr(pt/hardPt)); double xe = emitterX(); return make_pair(0.5*(1.+xe-(1.-xe)*s),0.5*(1.+xe+(1.-xe)*s)); } // If needed, insert default implementations of virtual function defined // in the InterfacedBase class here (using ThePEG-interfaced-impl in Emacs). void IFMassiveInvertedTildeKinematics::persistentOutput(PersistentOStream &) const { } void IFMassiveInvertedTildeKinematics::persistentInput(PersistentIStream &, int) { } void IFMassiveInvertedTildeKinematics::Init() { static ClassDocumentation documentation ("IFMassiveInvertedTildeKinematics inverts the initial-final tilde " "kinematics involving a massive particle."); } // *** 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 describeHerwigIFMassiveInvertedTildeKinematics("Herwig::IFMassiveInvertedTildeKinematics", "Herwig.so"); diff --git a/MatrixElement/Matchbox/Phasespace/IFMassiveInvertedTildeKinematics.h b/MatrixElement/Matchbox/Phasespace/IFMassiveInvertedTildeKinematics.h --- a/MatrixElement/Matchbox/Phasespace/IFMassiveInvertedTildeKinematics.h +++ b/MatrixElement/Matchbox/Phasespace/IFMassiveInvertedTildeKinematics.h @@ -1,138 +1,123 @@ // -*- C++ -*- // // IFMassiveInvertedTildeKinematics.h is a part of Herwig - A multi-purpose Monte Carlo event generator // Copyright (C) 2002-2019 The Herwig Collaboration // // Herwig is licenced under version 3 of the GPL, see COPYING for details. // Please respect the MCnet academic guidelines, see GUIDELINES for details. // #ifndef HERWIG_IFMassiveInvertedTildeKinematics_H #define HERWIG_IFMassiveInvertedTildeKinematics_H // // This is the declaration of the IFMassiveInvertedTildeKinematics class. // #include "Herwig/MatrixElement/Matchbox/Phasespace/InvertedTildeKinematics.h" namespace Herwig { using namespace ThePEG; /** * \ingroup Matchbox * \author Simon Platzer, Martin Stoll * * \brief IFMassiveInvertedTildeKinematics inverts the final-final tilde * kinematics. * */ class IFMassiveInvertedTildeKinematics: public Herwig::InvertedTildeKinematics { public: - /** @name Standard constructors and destructors. */ - //@{ - /** - * The default constructor. - */ - IFMassiveInvertedTildeKinematics(); - - /** - * The destructor. - */ - virtual ~IFMassiveInvertedTildeKinematics(); - //@} - -public: - /** * Perform the mapping of the tilde kinematics for the * last selected process and store all dimensionless * variables in the subtractionParameters() vector. * Return false, if the calculation of the real * kinematics was impossible for the selected configuration * and true on success. */ virtual bool doMap(const double *); /** * Return the pt associated to the last generated splitting. */ virtual Energy lastPt() const; /** * Return the momentum fraction associated to the last splitting. */ virtual double lastZ() const; /** * Return the upper bound on pt */ virtual Energy ptMax() const; /** * Given a pt, return the boundaries on z */ virtual pair zBounds(Energy pt, Energy hardPt = ZERO) 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. */ IFMassiveInvertedTildeKinematics & operator=(const IFMassiveInvertedTildeKinematics &) = delete; }; } #endif /* HERWIG_IFMassiveInvertedTildeKinematics_H */ diff --git a/MatrixElement/Matchbox/Phasespace/IFMassiveTildeKinematics.cc b/MatrixElement/Matchbox/Phasespace/IFMassiveTildeKinematics.cc --- a/MatrixElement/Matchbox/Phasespace/IFMassiveTildeKinematics.cc +++ b/MatrixElement/Matchbox/Phasespace/IFMassiveTildeKinematics.cc @@ -1,124 +1,119 @@ // -*- C++ -*- // // IFMassiveTildeKinematics.cc is a part of Herwig - A multi-purpose Monte Carlo event generator // Copyright (C) 2002-2019 The Herwig Collaboration // // Herwig is licenced under version 3 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 IFMassiveTildeKinematics class. // #include "IFMassiveTildeKinematics.h" #include "ThePEG/Interface/ClassDocumentation.h" #include "ThePEG/Utilities/DescribeClass.h" - #include "ThePEG/Persistency/PersistentOStream.h" #include "ThePEG/Persistency/PersistentIStream.h" using namespace Herwig; -IFMassiveTildeKinematics::IFMassiveTildeKinematics() {} - -IFMassiveTildeKinematics::~IFMassiveTildeKinematics() {} - IBPtr IFMassiveTildeKinematics::clone() const { return new_ptr(*this); } IBPtr IFMassiveTildeKinematics::fullclone() const { return new_ptr(*this); } bool IFMassiveTildeKinematics::doMap() { Lorentz5Momentum emitter = realEmitterMomentum(); Lorentz5Momentum emission = realEmissionMomentum(); Lorentz5Momentum spectator = realSpectatorMomentum(); double x = (- emission*spectator + emitter*spectator + emitter*emission) / (emitter*emission + emitter*spectator); double u = emitter*emission / (emitter*emission + emitter*spectator); subtractionParameters().resize(2); subtractionParameters()[0] = x; subtractionParameters()[1] = u; bornEmitterMomentum() = x*emitter; bornSpectatorMomentum() = spectator + emission - (1.-x)*emitter; bornEmitterMomentum().setMass(ZERO); bornEmitterMomentum().rescaleEnergy(); bornSpectatorMomentum().setMass(bornSpectatorData()->hardProcessMass()); bornSpectatorMomentum().rescaleEnergy(); return true; } Energy IFMassiveTildeKinematics::lastPt() const { Energy2 scale = 2.*(realEmissionMomentum()*realEmitterMomentum() -realEmissionMomentum()*realSpectatorMomentum() +realEmitterMomentum()*realSpectatorMomentum()); double x = subtractionParameters()[0]; double u = subtractionParameters()[1]; double muk2 = sqr(bornSpectatorData()->hardProcessMass())/scale; return sqrt(scale * ( u*(1.-u)*(1.-x)/x - u*u*muk2 )); } Energy IFMassiveTildeKinematics::lastPt(Lorentz5Momentum emitter,Lorentz5Momentum emission,Lorentz5Momentum spectator)const { Energy2 scale = 2.*(emission*emitter-emission*spectator+emitter*spectator); double x = 0.5*scale / (emitter*emission + emitter*spectator); double u = emitter*emission / (emitter*emission + emitter*spectator); double muk2 = sqr(spectator.mass())/scale; return sqrt(scale * ( u*(1.-u)*(1.-x)/x - u*u*muk2 )); } pair IFMassiveTildeKinematics::zBounds(Energy pt, Energy hardPt) const { if(pt>hardPt) return make_pair(0.5,0.5); double s = sqrt(1.-sqr(pt/hardPt)); double xe = emitterX(); return make_pair(0.5*(1.+xe-(1.-xe)*s),0.5*(1.+xe+(1.-xe)*s)); } double IFMassiveTildeKinematics::lastZ() const { Energy2 scale = 2.*(realEmissionMomentum()*realEmitterMomentum() -realEmissionMomentum()*realSpectatorMomentum() +realEmitterMomentum()*realSpectatorMomentum()); double x = subtractionParameters()[0]; double u = subtractionParameters()[1]; double muk2 = sqr(bornSpectatorData()->hardProcessMass())/scale; return u + x - u*x*(1.-muk2); } // If needed, insert default implementations of virtual function defined // in the InterfacedBase class here (using ThePEG-interfaced-impl in Emacs). void IFMassiveTildeKinematics::persistentOutput(PersistentOStream &) const { } void IFMassiveTildeKinematics::persistentInput(PersistentIStream &, int) { } void IFMassiveTildeKinematics::Init() { static ClassDocumentation documentation ("IFMassiveTildeKinematics implements the 'tilde' kinematics for " "a initial-final subtraction dipole involving a massive particle."); } // *** 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 describeHerwigIFMassiveTildeKinematics("Herwig::IFMassiveTildeKinematics", "Herwig.so"); diff --git a/MatrixElement/Matchbox/Phasespace/IFMassiveTildeKinematics.h b/MatrixElement/Matchbox/Phasespace/IFMassiveTildeKinematics.h --- a/MatrixElement/Matchbox/Phasespace/IFMassiveTildeKinematics.h +++ b/MatrixElement/Matchbox/Phasespace/IFMassiveTildeKinematics.h @@ -1,138 +1,123 @@ // -*- C++ -*- // // IFMassiveTildeKinematics.h is a part of Herwig - A multi-purpose Monte Carlo event generator // Copyright (C) 2002-2019 The Herwig Collaboration // // Herwig is licenced under version 3 of the GPL, see COPYING for details. // Please respect the MCnet academic guidelines, see GUIDELINES for details. // #ifndef HERWIG_IFMassiveTildeKinematics_H #define HERWIG_IFMassiveTildeKinematics_H // // This is the declaration of the IFMassiveTildeKinematics class. // #include "Herwig/MatrixElement/Matchbox/Phasespace/TildeKinematics.h" namespace Herwig { using namespace ThePEG; /** * \ingroup Matchbox * \author Simon Platzer, Martin Stoll * * \brief IFMassiveTildeKinematics implements the 'tilde' kinematics for * a initial-final subtraction dipole. * */ class IFMassiveTildeKinematics: public TildeKinematics { public: - /** @name Standard constructors and destructors. */ - //@{ - /** - * The default constructor. - */ - IFMassiveTildeKinematics(); - - /** - * The destructor. - */ - virtual ~IFMassiveTildeKinematics(); - //@} - -public: - /** * Perform the mapping to the tilde kinematics for the * last selected process and store all dimensionless * variables in the subtractionParameters() vector. * Return false, if the calculation of the tilde * kinematics was impossible for the selected configuration * and true on success. */ virtual bool doMap(); /** * Return the pt associated to the last merged splitting. */ virtual Energy lastPt() const; /** * Return the pt associated to emitter emission and sppectator momentum. */ virtual Energy lastPt(Lorentz5Momentum,Lorentz5Momentum,Lorentz5Momentum) const ; /** * Given a pt, return the boundaries on z */ virtual pair zBounds(Energy pt, Energy hardPt ) const; /** * Return the momentum fraction associated to the last splitting. */ virtual double lastZ() 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. */ IFMassiveTildeKinematics & operator=(const IFMassiveTildeKinematics &) = delete; }; } #endif /* HERWIG_IFMassiveTildeKinematics_H */ diff --git a/MatrixElement/Matchbox/Phasespace/IILightTildeKinematics.cc b/MatrixElement/Matchbox/Phasespace/IILightTildeKinematics.cc --- a/MatrixElement/Matchbox/Phasespace/IILightTildeKinematics.cc +++ b/MatrixElement/Matchbox/Phasespace/IILightTildeKinematics.cc @@ -1,125 +1,120 @@ // -*- C++ -*- // // IILightTildeKinematics.cc is a part of Herwig - A multi-purpose Monte Carlo event generator // Copyright (C) 2002-2019 The Herwig Collaboration // // Herwig is licenced under version 3 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 IILightTildeKinematics class. // #include "IILightTildeKinematics.h" #include "ThePEG/Interface/ClassDocumentation.h" #include "ThePEG/Utilities/DescribeClass.h" - #include "ThePEG/Persistency/PersistentOStream.h" #include "ThePEG/Persistency/PersistentIStream.h" using namespace Herwig; -IILightTildeKinematics::IILightTildeKinematics() {} - -IILightTildeKinematics::~IILightTildeKinematics() {} - IBPtr IILightTildeKinematics::clone() const { return new_ptr(*this); } IBPtr IILightTildeKinematics::fullclone() const { return new_ptr(*this); } Lorentz5Momentum IILightTildeKinematics::transform(const Lorentz5Momentum& k) const { LorentzMomentum res = k - 2.*((k*(K+Ktilde)/(K+Ktilde).m2())*(K+Ktilde)-((k*K)/(K.m2()))*Ktilde); return res; } bool IILightTildeKinematics::doMap() { Lorentz5Momentum emitter = realEmitterMomentum(); Lorentz5Momentum emission = realEmissionMomentum(); Lorentz5Momentum spectator = realSpectatorMomentum(); double x = (emitter*spectator - emitter*emission - spectator*emission)/(emitter*spectator); double v = (emitter*emission)/(emitter*spectator); subtractionParameters().resize(2); subtractionParameters()[0] = x; subtractionParameters()[1] = v; bornEmitterMomentum() = x * emitter; bornSpectatorMomentum() = spectator; bornEmitterMomentum().setMass(ZERO); bornEmitterMomentum().rescaleEnergy(); bornSpectatorMomentum().setMass(ZERO); bornSpectatorMomentum().rescaleEnergy(); K = emitter + spectator - emission; Ktilde = x * emitter + spectator; return true; } Energy IILightTildeKinematics::lastPt() const { Energy scale = sqrt(2.*(bornEmitterMomentum()*bornSpectatorMomentum())); double x = subtractionParameters()[0]; double v = subtractionParameters()[1]; return scale * sqrt(v*(1.-x-v)/x); } Energy IILightTildeKinematics::lastPt(Lorentz5Momentum ,Lorentz5Momentum emission,Lorentz5Momentum )const { return emission.perp(); } pair IILightTildeKinematics::zBounds(Energy pt, Energy hardPt) const { if(pt>hardPt) return make_pair(0.5,0.5); double root = (1.-emitterX())*sqrt(1.-sqr(pt/hardPt)); return make_pair(0.5*( 1.+emitterX() - root),0.5*( 1.+emitterX() + root)); } double IILightTildeKinematics::lastZ() const { double x = subtractionParameters()[0]; double v = subtractionParameters()[1]; return x + v; } // If needed, insert default implementations of virtual function defined // in the InterfacedBase class here (using ThePEG-interfaced-impl in Emacs). void IILightTildeKinematics::persistentOutput(PersistentOStream & os) const { os << ounit(K,GeV) << ounit(Ktilde,GeV); } void IILightTildeKinematics::persistentInput(PersistentIStream & is, int) { is >> iunit(K,GeV) >> iunit(Ktilde,GeV); } void IILightTildeKinematics::Init() { static ClassDocumentation documentation ("IILightTildeKinematics implements the 'tilde' kinematics for " "a initial-initial subtraction dipole."); } // *** 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 describeHerwigIILightTildeKinematics("Herwig::IILightTildeKinematics", "Herwig.so"); diff --git a/MatrixElement/Matchbox/Phasespace/IILightTildeKinematics.h b/MatrixElement/Matchbox/Phasespace/IILightTildeKinematics.h --- a/MatrixElement/Matchbox/Phasespace/IILightTildeKinematics.h +++ b/MatrixElement/Matchbox/Phasespace/IILightTildeKinematics.h @@ -1,171 +1,156 @@ // -*- C++ -*- // // IILightTildeKinematics.h is a part of Herwig - A multi-purpose Monte Carlo event generator // Copyright (C) 2002-2019 The Herwig Collaboration // // Herwig is licenced under version 3 of the GPL, see COPYING for details. // Please respect the MCnet academic guidelines, see GUIDELINES for details. // #ifndef HERWIG_IILightTildeKinematics_H #define HERWIG_IILightTildeKinematics_H // // This is the declaration of the IILightTildeKinematics class. // #include "Herwig/MatrixElement/Matchbox/Phasespace/TildeKinematics.h" namespace Herwig { using namespace ThePEG; /** * \ingroup Matchbox * \author Simon Platzer * * \breif IILightTildeKinematics implements the 'tilde' kinematics for * a initial-initial subtraction dipole. * */ class IILightTildeKinematics: public TildeKinematics { public: - /** @name Standard constructors and destructors. */ - //@{ - /** - * The default constructor. - */ - IILightTildeKinematics(); - - /** - * The destructor. - */ - virtual ~IILightTildeKinematics(); - //@} - -public: - /** * Perform the mapping to the tilde kinematics for the * last selected process and store all dimensionless * variables in the subtractionParameters() vector. * Return false, if the calculation of the tilde * kinematics was impossible for the selected configuration * and true on success. */ virtual bool doMap(); /** * Return the pt associated to the last merged splitting. */ virtual Energy lastPt() const; /** * Return the pt associated to emitter emission and sppectator momentum. */ //TODO: make this static? virtual Energy lastPt(Lorentz5Momentum,Lorentz5Momentum,Lorentz5Momentum) const ; /** * Given a pt, return the boundaries on z */ virtual pair zBounds(Energy pt, Energy hardPt ) const; /** * Return the momentum fraction associated to the last splitting. */ virtual double lastZ() const; /** * Return true, if this TildeKinematics object needs to transform * all other particles in the process except the emitter and spectator */ virtual bool doesTransform() const { return true; } /** * If this TildeKinematics object needs to transform all other particles * in the process except the emitter and spectator, return the transformed * momentum. */ virtual Lorentz5Momentum transform(const Lorentz5Momentum& p) const; /* * True if phase space point is above the alpha cut for this dipole. */ bool aboveAlpha() const {return dipole()->alpha() #include "InvertedTildeKinematics.h" #include "ThePEG/Interface/ClassDocumentation.h" #include "ThePEG/Utilities/DescribeClass.h" #include "ThePEG/Utilities/Rebinder.h" - #include "ThePEG/Persistency/PersistentOStream.h" #include "ThePEG/Persistency/PersistentIStream.h" - #include "Herwig/MatrixElement/Matchbox/Phasespace/RandomHelpers.h" using namespace Herwig; InvertedTildeKinematics::InvertedTildeKinematics() : HandlerBase(), theJacobian(0.0), thePtCut(0.0*GeV) {} -InvertedTildeKinematics::~InvertedTildeKinematics() {} - // If needed, insert default implementations of virtual function defined // in the InterfacedBase class here (using ThePEG-interfaced-impl in Emacs). Lorentz5Momentum InvertedTildeKinematics::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; boost &= (P*Q-Q.mass2())/GeV2 > 1e-8; 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; } Energy InvertedTildeKinematics::lastScale() const { if ( ( theDipole->bornEmitter() < 2 && theDipole->bornSpectator() > 1 ) || ( theDipole->bornEmitter() > 1 && theDipole->bornSpectator() < 2 ) ) { return -(bornEmitterMomentum()-bornSpectatorMomentum()).m(); } return (bornEmitterMomentum()+bornSpectatorMomentum()).m(); } pair InvertedTildeKinematics::generatePtZ(double& jac, const double * r, double pow, vector* ) const { double kappaMin = ptCut() != ZERO ? sqr(ptCut()/ptMax()) : sqr(0.1*GeV/GeV); double kappa; using namespace RandomHelpers; if ( ptCut() > ZERO ) { pair kw = pow==1. ? generate(inverse(0.,kappaMin,1.),r[0]) : generate(power(0.,-pow,kappaMin,1.),r[0]); kappa = kw.first; jac *= kw.second; } else { pair kw = generate((piecewise(), flat(1e-4,kappaMin), match(inverse(0.,kappaMin,1.))),r[0]); kappa = kw.first; jac *= kw.second; } Energy pt = sqrt(kappa)*ptMax(); pair zLims = zBounds(pt); pair zw(0,0);// = // generate(inverse(0.,zLims.first,zLims.second)+ // inverse(1.,zLims.first,zLims.second),r[1]); // FlatZ = 1 if ( theDipole->samplingZ() == 1 ) { zw = generate(flat(zLims.first,zLims.second),r[1]); } // OneOverZ = 2 if ( theDipole->samplingZ() == 2 ) { zw = generate(inverse(0.0,zLims.first,zLims.second),r[1]); } // OneOverOneMinusZ = 3 if ( theDipole->samplingZ() == 3 ) { zw = generate(inverse(1.0,zLims.first,zLims.second),r[1]); } // OneOverZOneMinusZ = 4 if ( theDipole->samplingZ() == 4 ) { zw = generate(inverse(0.0,zLims.first,zLims.second) + inverse(1.0,zLims.first,zLims.second),r[1]); } double z = zw.first; jac *= zw.second; jac *= sqr(ptMax()/lastScale()); return make_pair(pt,z); } void InvertedTildeKinematics::rebind(const TranslationMap & trans) { theDipole = trans.translate(theDipole); HandlerBase::rebind(trans); } IVector InvertedTildeKinematics::getReferences() { IVector ret = HandlerBase::getReferences(); ret.push_back(theDipole); return ret; } void InvertedTildeKinematics::persistentOutput(PersistentOStream & os) const { os << theDipole << theRealXComb << theBornXComb << ounit(theRealEmitterMomentum,GeV) << ounit(theRealEmissionMomentum,GeV) << ounit(theRealSpectatorMomentum,GeV) << theJacobian << ounit(thePtCut,GeV); } void InvertedTildeKinematics::persistentInput(PersistentIStream & is, int) { is >> theDipole >> theRealXComb >> theBornXComb >> iunit(theRealEmitterMomentum,GeV) >> iunit(theRealEmissionMomentum,GeV) >> iunit(theRealSpectatorMomentum,GeV) >> theJacobian >> iunit(thePtCut,GeV); } void InvertedTildeKinematics::Init() { static ClassDocumentation documentation ("InvertedTildeKinematics is the base class for the inverted 'tilde' " "kinematics being used for subtraction terms in the " "formalism of Catani and Seymour."); } // *** 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 describeInvertedTildeKinematics("Herwig::InvertedTildeKinematics", "Herwig.so"); diff --git a/MatrixElement/Matchbox/Phasespace/InvertedTildeKinematics.h b/MatrixElement/Matchbox/Phasespace/InvertedTildeKinematics.h --- a/MatrixElement/Matchbox/Phasespace/InvertedTildeKinematics.h +++ b/MatrixElement/Matchbox/Phasespace/InvertedTildeKinematics.h @@ -1,450 +1,442 @@ // -*- C++ -*- // // InvertedTildeKinematics.h is a part of Herwig - A multi-purpose Monte Carlo event generator // Copyright (C) 2002-2019 The Herwig Collaboration // // Herwig is licenced under version 3 of the GPL, see COPYING for details. // Please respect the MCnet academic guidelines, see GUIDELINES for details. // #ifndef HERWIG_InvertedTildeKinematics_H #define HERWIG_InvertedTildeKinematics_H // // This is the declaration of the InvertedTildeKinematics class. // #include "ThePEG/Handlers/HandlerBase.h" #include "ThePEG/Handlers/StandardXComb.h" #include "ThePEG/Repository/EventGenerator.h" #include "Herwig/MatrixElement/Matchbox/Dipoles/SubtractionDipole.h" namespace Herwig { using namespace ThePEG; /** * \ingroup Matchbox * \author Simon Platzer * * \brief InvertedTildeKinematics is the base class for the inverted 'tilde' * kinematics being used for subtraction terms in the * formalism of Catani and Seymour. * */ class InvertedTildeKinematics: public HandlerBase { public: - /** @name Standard constructors and destructors. */ - //@{ /** * The default constructor. */ InvertedTildeKinematics(); - /** - * The destructor. - */ - virtual ~InvertedTildeKinematics(); - //@} - public: /** @name Access to kinematic quantities. */ //@{ /** * Return the momentum of the emitter in the real emission process */ const Lorentz5Momentum& realEmitterMomentum() const { return theRealEmitterMomentum; } /** * Return the momentum of the emission in the real emission process */ const Lorentz5Momentum& realEmissionMomentum() const { return theRealEmissionMomentum; } /** * Return the momentum of the spectator in the real emission process */ const Lorentz5Momentum& realSpectatorMomentum() const { return theRealSpectatorMomentum; } /** * Return the momentum of the emitter in the underlying Born process */ const Lorentz5Momentum& bornEmitterMomentum() const { return theBornXComb->meMomenta()[theDipole->bornEmitter()]; } /** * Return the momentum of the spectator in the underlying Born process */ const Lorentz5Momentum& bornSpectatorMomentum() const { return theBornXComb->meMomenta()[theDipole->bornSpectator()]; } /** * Return the momentum fraction of the emitter */ double emitterX() const { return theDipole->bornEmitter() == 0 ? theBornXComb->lastX1() : theBornXComb->lastX2(); } /** * Return the momentum fraction of the spectator */ double spectatorX() const { return theDipole->bornSpectator() == 0 ? theBornXComb->lastX1() : theBornXComb->lastX2(); } /** * Return the vector of dimensionless variables calculated */ const vector& subtractionParameters() const { return theDipole->subtractionParameters(); } /** * Return true, if this InvertedTildeKinematics object needs to transform * all other particles in the process except the emitter, emission and spectator */ virtual bool doesTransform() const { return false; } /** * If this InvertedTildeKinematics object needs to transform all other particles * in the process except the emitter, emission and spectator, return the transformed * momentum. */ virtual Lorentz5Momentum transform(const Lorentz5Momentum& p) const { return p; } /** * Return the centre of mass energy for the underlying Born configuration */ Energy2 sHat() const { return theBornXComb->lastSHat(); } //@} public: /** * Clone this object */ Ptr::ptr cloneMe() const { return dynamic_ptr_cast::ptr>(clone()); } /** @name Access to process data. */ //@{ /** * Prepare given a dipole, and XCombs describing the real emission * and underlying Born processes, respectively. */ void prepare(tcStdXCombPtr newRealXComb, tcStdXCombPtr newBornXComb) { theRealXComb = newRealXComb; theBornXComb = newBornXComb; } /** * Return the real xcomb */ tcStdXCombPtr realXComb() const { return theRealXComb; } /** * Return the Born xcomb */ tcStdXCombPtr bornXComb() const { return theBornXComb; } /** * Set the current dipole */ void dipole(Ptr::tptr dip) { theDipole = dip; } /** * Return the current dipole */ Ptr::tptr dipole() { return theDipole; } /** * Return the current dipole */ Ptr::tcptr dipole() const { return theDipole; } /** * Return the number of random numbers needed to generate * a real emission configuration off the underlying Born * configuration. */ virtual int nDimRadiation() const { return 3; } /** * Perform the mapping of the tilde kinematics for the * last selected process and store all dimensionless * variables in the subtractionParameters() vector. * Return false, if the calculation of the real * kinematics was impossible for the selected configuration * and true on success. */ virtual bool doMap(const double *) = 0; /** * Set an optional cutoff on the emission's * transverse momentum. */ void ptCut(Energy pt) { thePtCut = pt; } /** * Return the optional cutoff on the emission's * transverse momentum. */ Energy ptCut() const { return thePtCut; } /** * Return the random number index * corresponding to the evolution variable. */ virtual int evolutionVariable() const { return 0; } /** * Return the cutoff on the evolution * random number corresponding to the pt cut. */ virtual double evolutionCutoff() const { return 0.0; } /** * Return the pt associated to the last generated splitting. */ virtual Energy lastPt() const = 0; /** * Return the momentum fraction associated to the last splitting. */ virtual double lastZ() const = 0; /** * Return the relevant dipole scale */ virtual Energy lastScale() const; /** * Return the upper bound on pt */ virtual Energy ptMax() const = 0; /** * Given a pt and a hard pt, return the boundaries on z; if the hard * pt is zero, ptMax() will be used. */ virtual pair zBounds(Energy pt, Energy hardPt = ZERO) const = 0; /** * Generate pt and z */ virtual pair generatePtZ(double& jac, const double * r, double power=1., vector* values = NULL) const; /** * Return the single particle phase space weight in units * of sHat() for the last selected configuration. */ double jacobian() const { return theJacobian; } /** * Return the particle type of the emitter in the real emission process */ cPDPtr realEmitterData() const { return (theDipole && theRealXComb) ? theRealXComb->mePartonData()[theDipole->realEmitter()] : cPDPtr(); } /** * Return the particle type of the emission in the real emission process */ cPDPtr realEmissionData() const { return (theDipole && theRealXComb) ? theRealXComb->mePartonData()[theDipole->realEmission()] : cPDPtr(); } /** * Return the particle type of the spectator in the real emission process */ cPDPtr realSpectatorData() const { return (theDipole && theRealXComb) ? theRealXComb->mePartonData()[theDipole->realSpectator()] : cPDPtr(); } /** * Return the particle type of the emitter in the underlying Born process */ cPDPtr bornEmitterData() const { return (theDipole && theBornXComb) ? theBornXComb->mePartonData()[theDipole->bornEmitter()] : cPDPtr(); } /** * Return the particle type of the spectator in the underlying Born process */ cPDPtr bornSpectatorData() const { return (theDipole && theBornXComb) ? theBornXComb->mePartonData()[theDipole->bornSpectator()] : cPDPtr(); } //@} protected: /** * Access the momentum of the emitter in the real emission process */ Lorentz5Momentum& realEmitterMomentum() { return theRealEmitterMomentum; } /** * Access the momentum of the emission in the real emission process */ Lorentz5Momentum& realEmissionMomentum() { return theRealEmissionMomentum; } /** * Access the momentum of the spectator in the real emission process */ Lorentz5Momentum& realSpectatorMomentum() { return theRealSpectatorMomentum; } /** * Access the vector of dimensionless variables calculated */ vector& subtractionParameters() { return theDipole->subtractionParameters(); } /** * Set the single particle phase space weight in units * of sHat() for the last selected configuration. */ void jacobian(double w) { theJacobian = w; } /** * 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; 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(); // If needed, insert declarations of virtual function defined in the // InterfacedBase class here (using ThePEG-interfaced-decl in Emacs). protected: /** @name Standard Interfaced functions. */ //@{ /** * Rebind pointer to other Interfaced objects. Called in the setup phase * after all objects used in an EventGenerator has been cloned so that * the pointers will refer to the cloned objects afterwards. * @param trans a TranslationMap relating the original objects to * their respective clones. * @throws RebindException if no cloned object was found for a given * pointer. */ virtual void rebind(const TranslationMap & trans); /** * Return a vector of all pointers to Interfaced objects used in this * object. * @return a vector of pointers. */ virtual IVector getReferences(); //@} private: /** * The last dipole this InvertedTildeKinematics has been selected for */ Ptr::tptr theDipole; /** * The XComb object describing the real emission process */ tcStdXCombPtr theRealXComb; /** * The XComb object describing the underlying Born process */ tcStdXCombPtr theBornXComb; /** * The momentum of the emitter in the real emission process */ Lorentz5Momentum theRealEmitterMomentum; /** * The momentum of the emission in the real emission process */ Lorentz5Momentum theRealEmissionMomentum; /** * The momentum of the spectator in the real emission process */ Lorentz5Momentum theRealSpectatorMomentum; /** * Return the single particle phase space weight in units * of sHat() for the last selected configuration. */ double theJacobian; /** * The optional cutoff on the emission's * transverse momentum. */ Energy thePtCut; private: /** * The assignment operator is private and must never be called. * In fact, it should not even be implemented. */ InvertedTildeKinematics & operator=(const InvertedTildeKinematics &) = delete; }; } #endif /* HERWIG_InvertedTildeKinematics_H */ diff --git a/MatrixElement/Matchbox/Phasespace/MatchboxPhasespace.cc b/MatrixElement/Matchbox/Phasespace/MatchboxPhasespace.cc --- a/MatrixElement/Matchbox/Phasespace/MatchboxPhasespace.cc +++ b/MatrixElement/Matchbox/Phasespace/MatchboxPhasespace.cc @@ -1,565 +1,563 @@ // -*- C++ -*- // // MatchboxPhasespace.cc is a part of Herwig - A multi-purpose Monte Carlo event generator // Copyright (C) 2002-2019 The Herwig Collaboration // // Herwig is licenced under version 3 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 MatchboxPhasespace class. // #include "MatchboxPhasespace.h" #include "ThePEG/Interface/ClassDocumentation.h" #include "ThePEG/Interface/Parameter.h" #include "ThePEG/Interface/Switch.h" #include "ThePEG/Interface/Command.h" #include "ThePEG/Interface/Reference.h" #include "ThePEG/EventRecord/Particle.h" #include "ThePEG/Repository/UseRandom.h" #include "ThePEG/Repository/EventGenerator.h" #include "ThePEG/Utilities/DescribeClass.h" #include "Herwig/MatrixElement/Matchbox/Utility/ProcessData.h" #include "Herwig/MatrixElement/Matchbox/MatchboxFactory.h" using namespace Herwig; MatchboxPhasespace::MatchboxPhasespace() : singularCutoff(10*GeV), theUseMassGenerators(false), theLoopParticleIdMin(200001), theLoopParticleIdMax(200100) {} -MatchboxPhasespace::~MatchboxPhasespace() {} - void MatchboxPhasespace::cloneDependencies(const std::string&) {} Ptr::tcptr MatchboxPhasespace::factory() const { return MatchboxFactory::currentFactory(); } Ptr::tptr MatchboxPhasespace::processData() const { return factory()->processData(); } double MatchboxPhasespace::generateKinematics(const double* r, vector& momenta) { diagramWeights().clear(); cPDVector::const_iterator pd = mePartonData().begin() + 2; vector::iterator p = momenta.begin() + 2; double massJacobian = 1.; Energy summ = ZERO; if ( useMassGenerators() ) { Energy gmass = ZERO; tGenericMassGeneratorPtr mgen; Energy maxMass = (!haveX1X2() && momenta.size() > 3) ? sqrt(lastSHat()) : sqrt(lastS()); for ( ; pd != mePartonData().end(); ++pd, ++p ) { mgen = processData()->massGenerator(*pd); if ( mgen && !isInvertible() ) { Energy massMax = min((**pd).massMax(),maxMass); Energy massMin = (**pd).massMin(); if ( massMin > massMax ) return 0.0; gmass = mgen->mass(massJacobian,**pd,massMin,massMax,r[0]); ++r; } else if ( (**pd).hardProcessWidth() != ZERO ) { Energy massMax = min((**pd).massMax(),maxMass); Energy massMin = (**pd).massMin(); if ( massMin > massMax ) return 0.0; // use a standard Breit Wigner here which we can invert // see invertKinematics as well double bwILow = atan((sqr(massMin)-sqr((**pd).hardProcessMass()))/((**pd).hardProcessMass() * (**pd).hardProcessWidth())); double bwIUp = atan((sqr(massMax)-sqr((**pd).hardProcessMass()))/((**pd).hardProcessMass() * (**pd).hardProcessWidth())); gmass = sqrt(sqr((**pd).hardProcessMass()) + (**pd).hardProcessMass()*(**pd).hardProcessWidth()*tan(bwILow+r[0]*(bwIUp-bwILow))); ++r; } else { gmass = (**pd).hardProcessMass(); } maxMass -= gmass; p->setMass(gmass); summ += gmass; } } else { for ( ; pd != mePartonData().end(); ++pd, ++p ) { summ += (**pd).hardProcessMass(); p->setMass((**pd).hardProcessMass()); } } if ( momenta.size() > 3 && !haveX1X2() ) { if ( summ > (momenta[0]+momenta[1]).m() ) return 0.0; } double weight = momenta.size() > 3 ? generateTwoToNKinematics(r,momenta) : generateTwoToOneKinematics(r,momenta); fillDiagramWeights(); return weight*massJacobian; } double MatchboxPhasespace::generateTwoToOneKinematics(const double* r, vector& momenta) { double tau = momenta[2].mass2()/lastXCombPtr()->lastS(); double ltau = log(tau)/2.; //old: y = ltau - 2.*r[0]*ltau; x1 = sqrt(tau)*exp(y); x2 = sqrt(tau)*exp(-y); double x1=pow(tau,1.-r[0]); double x2=pow(tau,r[0]); // Due to the proton mass and P1.e() + P2.e() == lastS() we multiply here // with the correction factor abs(P1.e()/P1.z()) to produce incoming // p1/2 = (e1/2,0,0,+/- e1/2) Lorentz5Momentum P1 = lastXCombPtr()->lastParticles().first->momentum(); ThreeVector p1 = x1 * (P1.vect()) * abs(P1.e()/P1.z()); Lorentz5Momentum P2 = lastXCombPtr()->lastParticles().second->momentum(); ThreeVector p2 = x2 * (P2.vect()) * abs(P2.e()/P2.z()); ThreeVector q = p1 + p2; momenta[0] = Lorentz5Momentum(momenta[0].mass(),p1); momenta[1] = Lorentz5Momentum(momenta[1].mass(),p2); momenta[2] = Lorentz5Momentum(momenta[2].mass(),q); // check for energy conservation: if ((momenta[0]+momenta[1]-momenta[2]).e()>pow(10,-9)*GeV) generator()->log() << "Warning: Momentum conservation in generateTwoToOneKinematics not precise.\n" << flush; lastXCombPtr()->lastX1X2({x1,x2}); lastXCombPtr()->lastSHat((momenta[0]+momenta[1]).m2()); return -4.*Constants::pi*ltau; } double MatchboxPhasespace::invertKinematics(const vector& momenta, double* r) const { if ( useMassGenerators() ) { Energy gmass = ZERO; Energy maxMass = (!haveX1X2() && momenta.size() > 3) ? sqrt((momenta[0]+momenta[1]).m2()) : sqrt(lastS()); cPDVector::const_iterator pd = mePartonData().begin() + 2; vector::const_iterator p = momenta.begin() + 2; for ( ; pd != mePartonData().end(); ++pd, ++p ) { if ( (**pd).hardProcessWidth() != ZERO ) { Energy massMax = min((**pd).massMax(),maxMass); Energy massMin = (**pd).massMin(); if ( massMin > massMax ) return 0.0; double bwILow = atan((sqr(massMin)-sqr((**pd).hardProcessMass()))/((**pd).hardProcessMass() * (**pd).hardProcessWidth())); double bwIUp = atan((sqr(massMax)-sqr((**pd).hardProcessMass()))/((**pd).hardProcessMass() * (**pd).hardProcessWidth())); gmass = p->mass(); double bw = atan((sqr(gmass)-sqr((**pd).hardProcessMass()))/((**pd).hardProcessMass() * (**pd).hardProcessWidth())); r[0] = (bw-bwILow)/(bwIUp-bwILow); ++r; } else { gmass = (**pd).hardProcessMass(); } maxMass -= gmass; } } return momenta.size() > 3 ? invertTwoToNKinematics(momenta,r) : invertTwoToOneKinematics(momenta,r); } double MatchboxPhasespace::invertTwoToOneKinematics(const vector& momenta, double* r) const { double tau = momenta[2].mass2()/lastXCombPtr()->lastS(); double ltau = log(tau)/2.; r[0] = (ltau - (momenta[0]+momenta[1]).rapidity())/(2.*ltau); return -4.*Constants::pi*ltau; } void MatchboxPhasespace::setCoupling(long a, long b, long c, double coupling, bool includeCrossings) { cPDPtr A = getParticleData(a); cPDPtr B = getParticleData(b); cPDPtr C = getParticleData(c); if ( !A || !B || !C ) { generator()->log() << "Warning: could not determine particle data for ids " << a << " " << b << " " << c << " when setting coupling in MatchboxPhasespace.\n" << flush; return; } if ( !includeCrossings ) { theCouplings->couplings()[LTriple(a,b,c)] = coupling; return; } if ( A->CC() ) { theCouplings->couplings()[LTriple(-a,b,c)] = coupling; theCouplings->couplings()[LTriple(-a,c,b)] = coupling; } else { theCouplings->couplings()[LTriple(a,b,c)] = coupling; theCouplings->couplings()[LTriple(a,c,b)] = coupling; } if ( B->CC() ) { theCouplings->couplings()[LTriple(-b,a,c)] = coupling; theCouplings->couplings()[LTriple(-b,c,a)] = coupling; } else { theCouplings->couplings()[LTriple(b,a,c)] = coupling; theCouplings->couplings()[LTriple(b,c,a)] = coupling; } if ( C->CC() ) { theCouplings->couplings()[LTriple(-c,a,b)] = coupling; theCouplings->couplings()[LTriple(-c,b,a)] = coupling; } else { theCouplings->couplings()[LTriple(c,a,b)] = coupling; theCouplings->couplings()[LTriple(c,b,a)] = coupling; } } string MatchboxPhasespace::doSetCoupling(string in) { istringstream is(in); long a,b,c; double coupling; is >> a >> b >> c >> coupling; if ( !is ) return "MatchboxPhasespace: error in setting coupling."; setCoupling(a,b,c,coupling,true); return ""; } string MatchboxPhasespace::doSetPhysicalCoupling(string in) { istringstream is(in); long a,b,c; double coupling; is >> a >> b >> c >> coupling; if ( !is ) return "MatchboxPhasespace: error in setting coupling."; setCoupling(a,b,c,coupling,false); return ""; } pair MatchboxPhasespace::timeLikeWeight(const Tree2toNDiagram& diag, int branch, double flatCut) const { pair children = diag.children(branch); if ( children.first == -1 ) { return make_pair(1.,meMomenta()[diag.externalId(branch)]); } pair res = timeLikeWeight(diag,children.first,flatCut); pair other = timeLikeWeight(diag,children.second,flatCut); res.first *= other.first; res.second += other.second; LTriple vertexKey(diag.allPartons()[branch]->id(), diag.allPartons()[children.first]->id(), diag.allPartons()[children.second]->id()); map::const_iterator cit = theCouplings->couplings().find(vertexKey); if ( cit != theCouplings->couplings().end() ){ res.first *= cit->second; } Energy2 mass2 = sqr(diag.allPartons()[branch]->hardProcessMass()); Energy2 width2 = sqr(diag.allPartons()[branch]->hardProcessWidth()); if ( abs(diag.allPartons()[branch]->id()) >= theLoopParticleIdMin && abs(diag.allPartons()[branch]->id()) <= theLoopParticleIdMax ) { // "loop particle" if ( abs((res.second.m2()-mass2)/lastSHat()) > flatCut ) { res.first /= abs((res.second.m2()-mass2)/GeV2); res.first *= log(abs((res.second.m2()-mass2)/GeV2)); // normal. of the argument in the log? } } else { if ( width2 == ZERO ) { if ( abs((res.second.m2()-mass2)/lastSHat()) > flatCut ) res.first /= abs((res.second.m2()-mass2)/GeV2); } else { res.first /= (sqr((res.second.m2()-mass2)/GeV2) + mass2*width2/sqr(GeV2))/(abs(res.second.m2()/GeV2)); } } return res; } double MatchboxPhasespace::spaceLikeWeight(const Tree2toNDiagram& diag, const Lorentz5Momentum& incoming, int branch, double flatCut) const { if ( branch == -1 ) return 1.; pair children = diag.children(branch); pair res = timeLikeWeight(diag,children.second,flatCut); LTriple vertexKey(diag.allPartons()[branch]->id(), diag.allPartons()[children.first]->id(), diag.allPartons()[children.second]->id()); if ( children.first == diag.nSpace() - 1 ) { if ( diag.allPartons()[children.first]->CC() ) vertexKey = LTriple(diag.allPartons()[branch]->id(), diag.allPartons()[children.second]->id(), diag.allPartons()[children.first]->CC()->id()); else vertexKey = LTriple(diag.allPartons()[branch]->id(), diag.allPartons()[children.second]->id(), diag.allPartons()[children.first]->id()); } map::const_iterator cit = theCouplings->couplings().find(vertexKey); if ( cit != theCouplings->couplings().end() ){ res.first *= cit->second; } if ( children.first == diag.nSpace() - 1 ) { return res.first; } res.second = incoming - res.second; Energy2 mass2 = sqr(diag.allPartons()[children.first]->hardProcessMass()); Energy2 width2 = sqr(diag.allPartons()[children.first]->hardProcessWidth()); if ( abs(diag.allPartons()[children.first]->id()) >= theLoopParticleIdMin && (diag.allPartons()[children.first]->id()) <= theLoopParticleIdMax ) { // "loop particle" if ( abs((res.second.m2()-mass2)/lastSHat()) > flatCut ) { res.first /= abs((res.second.m2()-mass2)/GeV2); res.first *= log(abs((res.second.m2()-mass2)/GeV2)); // normal. of the argument in the log? } } else { if ( width2 == ZERO ) { if ( abs((res.second.m2()-mass2)/lastSHat()) > flatCut ) res.first /= abs((res.second.m2()-mass2)/GeV2); } else { res.first /= (sqr((res.second.m2()-mass2)/GeV2) + mass2*width2/sqr(GeV2))/(abs(res.second.m2()/GeV2)); } } return res.first * spaceLikeWeight(diag,res.second,children.first,flatCut); } void MatchboxPhasespace::fillDiagramWeights(double flatCut) { if ( !diagramWeights().empty() ) return; for ( auto & d : lastXComb().diagrams() ) { diagramWeights()[d->id()] = spaceLikeWeight(dynamic_cast(*d),meMomenta()[0],0,flatCut); } } Selector MatchboxPhasespace::selectDiagrams(const MEBase::DiagramVector& diags) const { Selector ret; for ( MEBase::DiagramIndex d = 0; d < diags.size(); ++d ) { ret.insert(diagramWeight(dynamic_cast(*diags[d])),d); } return ret; } bool MatchboxPhasespace::matchConstraints(const vector& momenta) { if ( singularLimits().empty() ) return true; lastSingularLimit() = singularLimits().begin(); for ( ; lastSingularLimit() != singularLimits().end(); ++lastSingularLimit() ) { if ( lastSingularLimit()->first == lastSingularLimit()->second && momenta[lastSingularLimit()->first].t() < singularCutoff ) break; if ( lastSingularLimit()->first != lastSingularLimit()->second && sqrt(momenta[lastSingularLimit()->first]* momenta[lastSingularLimit()->second]) < singularCutoff ) { bool match = true; for ( set >::const_iterator other = singularLimits().begin(); other != singularLimits().end(); ++other ) { if ( other == lastSingularLimit() ) continue; if ( other->first == other->second && momenta[other->first].t() < singularCutoff ) { match = false; break; } if ( other->first != other->second && sqrt(momenta[other->first]* momenta[other->second]) < singularCutoff ) { match = false; break; } } if ( match ) break; } } return lastSingularLimit() != singularLimits().end(); } int MatchboxPhasespace::nDim(const cPDVector& data) const { int ndimps = nDimPhasespace(data.size()-2); if ( useMassGenerators() ) { for ( cPDVector::const_iterator pd = data.begin(); pd != data.end(); ++pd ) { if ( (**pd).massGenerator() || (**pd).hardProcessWidth() != ZERO ) { ++ndimps; } } } return ndimps; } // If needed, insert default implementations of virtual function defined // in the InterfacedBase class here (using ThePEG-interfaced-impl in Emacs). void MatchboxPhasespace::persistentOutput(PersistentOStream & os) const { os << theLastXComb << ounit(singularCutoff,GeV) << theUseMassGenerators << theLoopParticleIdMin << theLoopParticleIdMax << theCouplings; } void MatchboxPhasespace::persistentInput(PersistentIStream & is, int) { is >> theLastXComb >> iunit(singularCutoff,GeV) >> theUseMassGenerators >> theLoopParticleIdMin >> theLoopParticleIdMax >> theCouplings; lastMatchboxXComb(theLastXComb); } // *** 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 describeMatchboxPhasespace("Herwig::MatchboxPhasespace", "Herwig.so"); void MatchboxPhasespace::Init() { static ClassDocumentation documentation ("MatchboxPhasespace defines an abstract interface to a phase " "space generator."); static Parameter interfaceSingularCutoff ("SingularCutoff", "[debug] Cutoff below which a region is considered singular.", &MatchboxPhasespace::singularCutoff, GeV, 10.0*GeV, 0.0*GeV, 0*GeV, false, false, Interface::lowerlim); interfaceSingularCutoff.rank(-1); /* static Switch interfaceUseMassGenerators ("UseMassGenerators", "Use mass generators instead of fixed masses.", &MatchboxPhasespace::theUseMassGenerators, false, false, false); static SwitchOption interfaceUseMassGeneratorsYes (interfaceUseMassGenerators, "Yes", "Use mass generators.", true); static SwitchOption interfaceUseMassGeneratorsNo (interfaceUseMassGenerators, "No", "Do not use mass generators.", false); */ static Command interfaceSetCoupling ("SetCoupling", "", &MatchboxPhasespace::doSetCoupling, false); static Command interfaceSetPhysicalCoupling ("SetPhysicalCoupling", "", &MatchboxPhasespace::doSetPhysicalCoupling, false); static Parameter interfaceLoopParticleIdMin ("LoopParticleIdMin", "First id in a range of id's meant to denote fictitious " "'ghost' particles to be used by the diagram generator " "in loop induced processes.", &MatchboxPhasespace::theLoopParticleIdMin, 200001, 0, 0, false, false, Interface::lowerlim); interfaceLoopParticleIdMin.rank(-1); static Parameter interfaceLoopParticleIdMax ("LoopParticleIdMax", "Last id in a range of id's meant to denote fictitious " "'ghost' particles to be used by the diagram generator " "in loop induced processes.", &MatchboxPhasespace::theLoopParticleIdMax, 200100, 0, 0, false, false, Interface::lowerlim); interfaceLoopParticleIdMax.rank(-1); static Reference interfaceCouplingData ("CouplingData", "Set the storage for the couplings.", &MatchboxPhasespace::theCouplings, false, false, true, false, false); interfaceCouplingData.rank(-1); } 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,366 +1,358 @@ // -*- C++ -*- // // MatchboxPhasespace.h is a part of Herwig - A multi-purpose Monte Carlo event generator // Copyright (C) 2002-2019 The Herwig Collaboration // // Herwig is licenced under version 3 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" #include "Herwig/MatrixElement/Matchbox/Utility/LastMatchboxXCombInfo.h" #include "Herwig/MatrixElement/Matchbox/Utility/ProcessData.fh" #include "Herwig/MatrixElement/Matchbox/MatchboxFactory.fh" #include "Herwig/MatrixElement/Matchbox/Phasespace/PhasespaceCouplings.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, public LastMatchboxXCombInfo { public: - /** @name Standard constructors and destructors. */ - //@{ /** * The default constructor. */ MatchboxPhasespace(); - /** - * The destructor. - */ - virtual ~MatchboxPhasespace(); - //@} - public: /** * Set the XComb object steering the Born matrix * element this class represents virtual corrections to. */ virtual void setXComb(tStdXCombPtr xc) { theLastXComb = xc; lastMatchboxXComb(xc); } /** * Return the factory object */ Ptr::tcptr factory() const; /** * Return the process data object */ Ptr::tptr processData() const; /** * Generate a phase space point and return its weight. */ virtual double generateKinematics(const double* r, vector& momenta); /** * Generate a phase space point and return its weight. */ virtual double generateTwoToNKinematics(const double*, vector& momenta) = 0; /** * Generate a 2 -> 1 phase space point and return its weight. */ virtual double generateTwoToOneKinematics(const double*, vector& momenta); /** * Return the number of random numbers required to produce a given * multiplicity final state. */ virtual int nDim(const cPDVector&) const; /** * Return the number of random numbers required to produce a given * multiplicity final state. */ virtual int nDimPhasespace(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; } /** * True, if mass generators should be used instead of fixed masses */ bool useMassGenerators() const { return theUseMassGenerators; } /** * Fill a diagram selector for the last phase space point. */ virtual Selector selectDiagrams(const MEBase::DiagramVector&) const; /** * Return the momentum and weight appropriate to the given timelike * branch of the diagram. */ pair 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); /** * Clear the diagram weights. */ void clearDiagramWeights() { diagramWeights().clear(); } /** * Clone this phase space generator. */ Ptr::ptr cloneMe() const { return dynamic_ptr_cast::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& momenta, double* r) const; /** * Invert the given phase space point to the random numbers which * would have generated it. */ virtual double invertTwoToNKinematics(const vector&, double*) const { return 0.; } /** * Invert the given 2 -> 1 phase space point to the random numbers which * would have generated it. */ virtual double invertTwoToOneKinematics(const vector&, double*) const; 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& lastSingularIndices() const { assert(lastSingularLimit() != singularLimits().end()); return *lastSingularLimit(); } /** * Return true, if constraints on phasespace generation have been met. */ bool matchConstraints(const vector& momenta); protected: /** * Set a coupling for the given vertex; the convention is that all * legs are outgoing, and all possible crossings will be taken care * of. If not set, coupling weights default to one. */ void setCoupling(long a, long b, long c, double coupling, bool includeCrossings = true); 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: /** * A cutoff below which a region is considered singular. */ Energy singularCutoff; /** * True, if mass generators should be used instead of fixed masses */ bool theUseMassGenerators; /** * Couplings to be used in diagram weighting */ Ptr::ptr theCouplings; /** * Interface function to setcoupling */ string doSetCoupling(string); /** * Interface function to setcoupling */ string doSetPhysicalCoupling(string); /** * The first id in a range of id's meant to denote fictitious * 'ghost' particles to be used by the diagram generator * in loop induced processes. */ int theLoopParticleIdMin; /** * The last id in a range of id's meant to denote fictitious * 'ghost' particles to be used by the diagram generator * in loop induced processes. */ int theLoopParticleIdMax; /** * The assignment operator is private and must never be called. * In fact, it should not even be implemented. */ MatchboxPhasespace & operator=(const MatchboxPhasespace &) = delete; }; } #endif /* HERWIG_MatchboxPhasespace_H */ diff --git a/MatrixElement/Matchbox/Phasespace/MatchboxRambo.cc b/MatrixElement/Matchbox/Phasespace/MatchboxRambo.cc --- a/MatrixElement/Matchbox/Phasespace/MatchboxRambo.cc +++ b/MatrixElement/Matchbox/Phasespace/MatchboxRambo.cc @@ -1,263 +1,261 @@ // -*- C++ -*- // // MatchboxRambo.cc is a part of Herwig - A multi-purpose Monte Carlo event generator // Copyright (C) 2002-2019 The Herwig Collaboration // // Herwig is licenced under version 3 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 MatchboxRambo class. // #include "MatchboxRambo.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; MatchboxRambo::MatchboxRambo() : needToReshuffle(false), theMakeReferenceSample(false), referenceSample(0) {} -MatchboxRambo::~MatchboxRambo() {} - IBPtr MatchboxRambo::clone() const { return new_ptr(*this); } IBPtr MatchboxRambo::fullclone() const { return new_ptr(*this); } static double weights[7] = { -1.,-1., 0.039788735772973833942, 0.00012598255637968550463, 1.3296564302788840628E-7, 7.0167897579949011130E-11, 2.2217170114046130768E-14 }; void MatchboxRambo::setXComb(tStdXCombPtr xc) { MatchboxPhasespace::setXComb(xc); needToReshuffle = false; if ( xc ) { for ( cPDVector::const_iterator d = mePartonData().begin(); d != mePartonData().end(); ++d ) { if ( (**d).hardProcessMass() != ZERO ) { needToReshuffle = true; break; } } } } void MatchboxRambo::dumpReference(const vector& momenta, double weight) const { *referenceSample << lastX1() << " " << lastX2() << " "; Boost toLab = (lastPartons().first->momentum() + lastPartons().second->momentum()).boostVector(); for ( vector::const_iterator p = momenta.begin(); p != momenta.end(); ++p ) { Lorentz5Momentum pl = *p; if ( toLab.mag2() > Constants::epsilon ) pl.boost(toLab); *referenceSample << (pl.x()/GeV) << " " << (pl.y()/GeV) << " " << (pl.z()/GeV) << " " << (pl.t()/GeV) << " " << (pl.mass()/GeV) << " "; } double ymax = lastCuts().yHatMax(); double ymin = lastCuts().yHatMin(); double km = log(lastCuts().sHatMax()/lastCuts().sHatMin()); ymax = min(ymax, log(lastCuts().x1Max()*sqrt(lastS()/lastSHat()))); ymin = max(ymin, -log(lastCuts().x2Max()*sqrt(lastS()/lastSHat()))); *referenceSample << weight*km*(ymax-ymin)/(lastX1()*lastX2()) << "\n" << flush; } double MatchboxRambo::generateTwoToNKinematics(const double* r, vector& momenta) { if ( theMakeReferenceSample ) { map::iterator ref = referenceSamples.find(mePartonData()); if ( ref == referenceSamples.end() ) { ostringstream refname; for ( cPDVector::const_iterator p = mePartonData().begin(); p != mePartonData().end(); ++p ) { refname << (**p).PDGName(); } refname << ".rambo"; referenceSamples[mePartonData()] = new ofstream(refname.str().c_str(),std::ios_base::app); ref = referenceSamples.find(mePartonData()); *(ref->second) << setprecision(26); } assert(ref != referenceSamples.end()); referenceSample = ref->second; } size_t offset = 2; if ( lastXCombPtr() ) offset = dynamic_cast(*lastXComb().diagrams().front()).nSpace() > 0 ? 2 : 1; Energy w = sqrt(lastSHat()); size_t count = 0; Lorentz5Momentum Q; for ( vector::iterator k = momenta.begin() + offset; k != momenta.end(); ++k ) { Energy q = -w*log(r[count]*r[count+1]); double ct = 2.*r[count+2]-1.; double st = sqrt(1.-sqr(ct)); double phi = 2.*Constants::pi*r[count+3]; double cphi = cos(phi); double sphi = sqrt(1.-sqr(cphi)); if ( phi > Constants::pi ) sphi = -sphi; (*k).setMass(ZERO); (*k).setT(q); (*k).setX(q*cphi*st); (*k).setY(q*sphi*st); (*k).setZ(q*ct); count += 4; Q += *k; } Energy M = sqrt(Q.m2()); double x = w/M; Boost beta = -(Q.vect() * (1./M)); double gamma = Q.t()/M; double a = 1./(1.+gamma); for ( vector::iterator k = momenta.begin() + offset; k != momenta.end(); ++k ) { Energy q = (*k).t(); Energy bq = beta*(*k).vect(); (*k).setT(x*(gamma*q+bq)); (*k).setVect(x*((*k).vect()+(q+a*bq)*beta)); } size_t n = momenta.size()-offset; double weight = weights[n]; if ( !needToReshuffle ) { if ( !matchConstraints(momenta) ) return 0.; if ( theMakeReferenceSample ) dumpReference(momenta, weight); return weight; } double xi; ReshuffleEquation solve(w,mePartonData().begin()+offset,mePartonData().end(), momenta.begin()+2,momenta.end()); GSLBisection solver(1e-10,1e-8,10000); try { xi = solver.value(solve,0.0,1.1); } catch (GSLBisection::GSLerror) { return 0.; } catch (GSLBisection::IntervalError) { return 0.; } weight *= pow(xi,3.*(n-1.)); Energy num = ZERO; Energy den = ZERO; cPDVector::const_iterator d = mePartonData().begin()+offset; for ( vector::iterator k = momenta.begin()+offset; k != momenta.end(); ++k, ++d ) { num += (*k).vect().mag2()/(*k).t(); Energy q = (*k).t(); (*k).setT(sqrt(sqr((**d).hardProcessMass())+xi*xi*sqr((*k).t()))); (*k).setVect(xi*(*k).vect()); weight *= q/(*k).t(); den += (*k).vect().mag2()/(*k).t(); (*k).setMass((**d).hardProcessMass()); } if ( !matchConstraints(momenta) ) return 0.; weight *= num/den; if ( theMakeReferenceSample ) dumpReference(momenta, weight); return weight; } Energy MatchboxRambo::ReshuffleEquation::operator() (double xi) const { cPDVector::const_iterator d = dataBegin; vector::const_iterator p = momentaBegin; Energy res = -w; for ( ; d != dataEnd; ++d, ++p ) { res += sqrt(sqr((**d).hardProcessMass()) + xi*xi*sqr(p->t())); } return res; } // If needed, insert default implementations of virtual function defined // in the InterfacedBase class here (using ThePEG-interfaced-impl in Emacs). void MatchboxRambo::persistentOutput(PersistentOStream & os) const { os << needToReshuffle << theMakeReferenceSample; } void MatchboxRambo::persistentInput(PersistentIStream & is, int) { is >> needToReshuffle >> theMakeReferenceSample; } // *** 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 describeHerwigMatchboxRambo("Herwig::MatchboxRambo", "Herwig.so"); void MatchboxRambo::Init() { static ClassDocumentation documentation ("MatchboxRambo implements RAMBO phase space generation."); static Switch interfaceMakeReferenceSample ("MakeReferenceSample", "Switch on generation of a reference sample of phase space points.", &MatchboxRambo::theMakeReferenceSample, false, false, false); static SwitchOption interfaceMakeReferenceSampleYes (interfaceMakeReferenceSample, "Yes", "Generate a reference sample.", true); static SwitchOption interfaceMakeReferenceSampleNo (interfaceMakeReferenceSample, "No", "Do not generate a reference sample.", false); interfaceMakeReferenceSample.rank(-1); } diff --git a/MatrixElement/Matchbox/Phasespace/MatchboxRambo.h b/MatrixElement/Matchbox/Phasespace/MatchboxRambo.h --- a/MatrixElement/Matchbox/Phasespace/MatchboxRambo.h +++ b/MatrixElement/Matchbox/Phasespace/MatchboxRambo.h @@ -1,188 +1,180 @@ // -*- C++ -*- // // MatchboxRambo.h is a part of Herwig - A multi-purpose Monte Carlo event generator // Copyright (C) 2002-2019 The Herwig Collaboration // // Herwig is licenced under version 3 of the GPL, see COPYING for details. // Please respect the MCnet academic guidelines, see GUIDELINES for details. // #ifndef Herwig_MatchboxRambo_H #define Herwig_MatchboxRambo_H // // This is the declaration of the MatchboxRambo class. // #include "Herwig/MatrixElement/Matchbox/Phasespace/MatchboxPhasespace.h" namespace Herwig { using namespace ThePEG; /** * \ingroup Matchbox * \author Simon Platzer * * \brief MatchboxRambo implements RAMBO phase space generation. * */ class MatchboxRambo: public MatchboxPhasespace { public: - /** @name Standard constructors and destructors. */ - //@{ /** * The default constructor. */ MatchboxRambo(); - /** - * The destructor. - */ - virtual ~MatchboxRambo(); - //@} - public: /** * Prepare a phase space generator for the given xcomb object. */ virtual void setXComb(tStdXCombPtr); /** * Generate a phase space point and return its weight. */ virtual double generateTwoToNKinematics(const double*, vector& momenta); /** * Return the number of random numbers required to produce a given * multiplicity final state. */ virtual int nDimPhasespace(int nFinal) const { if ( nFinal == 1 ) return 1; return 4*nFinal; } protected: /** * The function object defining the equation * to be solved. */ struct ReshuffleEquation { typedef double ArgType; typedef Energy ValType; static double aUnit() { return 1.; } static Energy vUnit() { return 1.*GeV; } Energy operator() (double xi) const; Energy w; cPDVector::const_iterator dataBegin; cPDVector::const_iterator dataEnd; vector::const_iterator momentaBegin; vector::const_iterator momentaEnd; ReshuffleEquation(Energy q, cPDVector::const_iterator dBegin, cPDVector::const_iterator dEnd, vector::const_iterator mBegin, vector::const_iterator mEnd) : w(q), dataBegin(dBegin), dataEnd(dEnd), momentaBegin(mBegin), momentaEnd(mEnd) {} }; 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. */ MatchboxRambo & operator=(const MatchboxRambo &) = delete; /** * Whether or not we need to reshuffle. */ bool needToReshuffle; /** * True, if a reference sample of phasespace points should be * generated. */ bool theMakeReferenceSample; /** * Map processes to streams for reference samples */ map referenceSamples; /** * The stream to fill for the reference sample */ ofstream* referenceSample; /** * Write the generated point to the reference sample */ void dumpReference(const vector&, double) const; }; } #endif /* Herwig_MatchboxRambo_H */ diff --git a/MatrixElement/Matchbox/Phasespace/MatchboxReference.cc b/MatrixElement/Matchbox/Phasespace/MatchboxReference.cc --- a/MatrixElement/Matchbox/Phasespace/MatchboxReference.cc +++ b/MatrixElement/Matchbox/Phasespace/MatchboxReference.cc @@ -1,105 +1,100 @@ // -*- C++ -*- // // MatchboxReference.cc is a part of Herwig - A multi-purpose Monte Carlo event generator // Copyright (C) 2002-2019 The Herwig Collaboration // // Herwig is licenced under version 3 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 MatchboxReference class. // #include "MatchboxReference.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; -MatchboxReference::MatchboxReference() {} - -MatchboxReference::~MatchboxReference() {} - IBPtr MatchboxReference::clone() const { return new_ptr(*this); } IBPtr MatchboxReference::fullclone() const { return new_ptr(*this); } double MatchboxReference::generateTwoToNKinematics(const double*, vector& momenta) { map::iterator ref = referenceSamples.find(mePartonData()); if ( ref == referenceSamples.end() ) { ostringstream refname; for ( cPDVector::const_iterator p = mePartonData().begin(); p != mePartonData().end(); ++p ) { refname << (**p).PDGName(); } refname << ".rambo"; referenceSamples[mePartonData()] = new ifstream(refname.str().c_str()); ref = referenceSamples.find(mePartonData()); } assert(ref != referenceSamples.end()); ifstream& in = *(ref->second); assert(in); double x1,x2; double x,y,z,t,m; double weight; in >> x1 >> x2; for ( vector::iterator p = momenta.begin(); p != momenta.end(); ++p ) { in >> x >> y >> z >> t >> m; *p = Lorentz5Momentum(x*GeV,y*GeV,z*GeV,t*GeV,m*GeV); } in >> weight; lastXCombPtr()->lastX1X2(make_pair(x1,x2)); lastXCombPtr()->lastSHat((momenta[0]+momenta[1]).m2()); return weight; } // If needed, insert default implementations of virtual function defined // in the InterfacedBase class here (using ThePEG-interfaced-impl in Emacs). void MatchboxReference::persistentOutput(PersistentOStream &) const {} void MatchboxReference::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 describeHerwigMatchboxReference("Herwig::MatchboxReference", "Herwig.so"); void MatchboxReference::Init() { static ClassDocumentation documentation ("MatchboxReference implements reference sample phase space generation."); } diff --git a/MatrixElement/Matchbox/Phasespace/MatchboxReference.h b/MatrixElement/Matchbox/Phasespace/MatchboxReference.h --- a/MatrixElement/Matchbox/Phasespace/MatchboxReference.h +++ b/MatrixElement/Matchbox/Phasespace/MatchboxReference.h @@ -1,140 +1,125 @@ // -*- C++ -*- // // MatchboxReference.h is a part of Herwig - A multi-purpose Monte Carlo event generator // Copyright (C) 2002-2019 The Herwig Collaboration // // Herwig is licenced under version 3 of the GPL, see COPYING for details. // Please respect the MCnet academic guidelines, see GUIDELINES for details. // #ifndef Herwig_MatchboxReference_H #define Herwig_MatchboxReference_H // // This is the declaration of the MatchboxReference class. // #include "Herwig/MatrixElement/Matchbox/Phasespace/MatchboxPhasespace.h" namespace Herwig { using namespace ThePEG; /** * \ingroup Matchbox * \author Simon Platzer * * \brief MatchboxReference implements reference sample phase space generation. * */ class MatchboxReference: public MatchboxPhasespace { public: - /** @name Standard constructors and destructors. */ - //@{ - /** - * The default constructor. - */ - MatchboxReference(); - - /** - * The destructor. - */ - virtual ~MatchboxReference(); - //@} - -public: - /** * Generate a phase space point and return its weight. */ virtual double generateTwoToNKinematics(const double*, vector& momenta); /** * Return the number of random numbers required to produce a given * multiplicity final state. */ virtual int nDimPhasespace(int nFinal) const { if ( nFinal == 1 ) return 1; return 4*nFinal + 2; } /** * Return true, if this phase space 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: /** @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. */ MatchboxReference & operator=(const MatchboxReference &) = delete; /** * Stream to read the reference samples. */ map referenceSamples; }; } #endif /* Herwig_MatchboxReference_H */ diff --git a/MatrixElement/Matchbox/Phasespace/PhasespaceCouplings.cc b/MatrixElement/Matchbox/Phasespace/PhasespaceCouplings.cc --- a/MatrixElement/Matchbox/Phasespace/PhasespaceCouplings.cc +++ b/MatrixElement/Matchbox/Phasespace/PhasespaceCouplings.cc @@ -1,77 +1,71 @@ // -*- C++ -*- // // PhasespaceCouplings.cc is a part of Herwig - A multi-purpose Monte Carlo event generator // Copyright (C) 2002-2019 The Herwig Collaboration // // Herwig is licenced under version 3 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 PhasespaceCouplings class. // #include "PhasespaceCouplings.h" #include "ThePEG/Interface/ClassDocumentation.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" using namespace Herwig; -PhasespaceCouplings::PhasespaceCouplings() {} - -PhasespaceCouplings::~PhasespaceCouplings() {} - IBPtr PhasespaceCouplings::clone() const { return new_ptr(*this); } IBPtr PhasespaceCouplings::fullclone() const { return new_ptr(*this); } // If needed, insert default implementations of virtual function defined // in the InterfacedBase class here (using ThePEG-interfaced-impl in Emacs). void PhasespaceCouplings::persistentOutput(PersistentOStream & os) const { os << theCouplings.size(); for ( map::const_iterator cit = theCouplings.begin(); cit != theCouplings.end(); ++cit ) os << cit->first << cit->second; } void PhasespaceCouplings::persistentInput(PersistentIStream & is, int) { theCouplings.clear(); size_t size; LTriple k; is >> size; while ( size-- && is ) { is >> k; is >> theCouplings[k]; } } // *** 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 describeHerwigPhasespaceCouplings("Herwig::PhasespaceCouplings", "Herwig.so"); void PhasespaceCouplings::Init() { static ClassDocumentation documentation ("Store couplings for the phase space generator."); } diff --git a/MatrixElement/Matchbox/Phasespace/PhasespaceCouplings.h b/MatrixElement/Matchbox/Phasespace/PhasespaceCouplings.h --- a/MatrixElement/Matchbox/Phasespace/PhasespaceCouplings.h +++ b/MatrixElement/Matchbox/Phasespace/PhasespaceCouplings.h @@ -1,139 +1,124 @@ // -*- C++ -*- // // PhasespaceCouplings.h is a part of Herwig - A multi-purpose Monte Carlo event generator // Copyright (C) 2002-2019 The Herwig Collaboration // // Herwig is licenced under version 3 of the GPL, see COPYING for details. // Please respect the MCnet academic guidelines, see GUIDELINES for details. // #ifndef Herwig_PhasespaceCouplings_H #define Herwig_PhasespaceCouplings_H // // This is the declaration of the PhasespaceCouplings class. // #include "ThePEG/Handlers/HandlerBase.h" #include "ThePEG/Persistency/PersistentOStream.h" #include "ThePEG/Persistency/PersistentIStream.h" namespace Herwig { using namespace ThePEG; typedef std::tuple LTriple; inline PersistentOStream& operator<<(PersistentOStream& os, const LTriple& t) { os << std::get<0>(t) << std::get<1>(t) << std::get<2>(t); return os; } inline PersistentIStream& operator>>(PersistentIStream& is, LTriple& t) { is >> std::get<0>(t) >> std::get<1>(t) >> std::get<2>(t); return is; } /** * * \ingroup Matchbox * \author Simon Platzer * * \brief Store couplings for the phase space generator. * * @see \ref PhasespaceCouplingsInterfaces "The interfaces" * defined for PhasespaceCouplings. */ class PhasespaceCouplings: public HandlerBase { public: - /** @name Standard constructors and destructors. */ - //@{ - /** - * The default constructor. - */ - PhasespaceCouplings(); - - /** - * The destructor. - */ - virtual ~PhasespaceCouplings(); - //@} - -public: - /** * Couplings to be used in diagram weighting */ map& couplings() { return theCouplings; } /** * Couplings to be used in diagram weighting */ const map& couplings() const { return theCouplings; } 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: /** * Couplings to be used in diagram weighting */ map theCouplings; /** * The assignment operator is private and must never be called. * In fact, it should not even be implemented. */ PhasespaceCouplings & operator=(const PhasespaceCouplings &) = delete; }; } #endif /* Herwig_PhasespaceCouplings_H */ diff --git a/MatrixElement/Matchbox/Phasespace/TildeKinematics.cc b/MatrixElement/Matchbox/Phasespace/TildeKinematics.cc --- a/MatrixElement/Matchbox/Phasespace/TildeKinematics.cc +++ b/MatrixElement/Matchbox/Phasespace/TildeKinematics.cc @@ -1,78 +1,72 @@ // -*- C++ -*- // // TildeKinematics.cc is a part of Herwig - A multi-purpose Monte Carlo event generator // Copyright (C) 2002-2019 The Herwig Collaboration // // Herwig is licenced under version 3 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 TildeKinematics class. // #include "TildeKinematics.h" #include "ThePEG/Interface/ClassDocumentation.h" #include "ThePEG/Utilities/DescribeClass.h" #include "ThePEG/Utilities/Rebinder.h" - #include "ThePEG/Persistency/PersistentOStream.h" #include "ThePEG/Persistency/PersistentIStream.h" using namespace Herwig; -TildeKinematics::TildeKinematics() - : HandlerBase() {} - -TildeKinematics::~TildeKinematics() {} - Energy TildeKinematics::lastScale() const { if ( ( theDipole->bornEmitter() < 2 && theDipole->bornSpectator() > 1 ) || ( theDipole->bornEmitter() > 1 && theDipole->bornSpectator() < 2 ) ) { return -(bornEmitterMomentum()-bornSpectatorMomentum()).m(); } return (bornEmitterMomentum()+bornSpectatorMomentum()).m(); } // If needed, insert default implementations of virtual function defined // in the InterfacedBase class here (using ThePEG-interfaced-impl in Emacs). void TildeKinematics::rebind(const TranslationMap & trans) { theDipole = trans.translate(theDipole); HandlerBase::rebind(trans); } IVector TildeKinematics::getReferences() { IVector ret = HandlerBase::getReferences(); ret.push_back(theDipole); return ret; } void TildeKinematics::persistentOutput(PersistentOStream & os) const { os << theDipole << theRealXComb << theBornXComb << ounit(theBornEmitterMomentum,GeV) << ounit(theBornSpectatorMomentum,GeV); } void TildeKinematics::persistentInput(PersistentIStream & is, int) { is >> theDipole >> theRealXComb >> theBornXComb >> iunit(theBornEmitterMomentum,GeV) >> iunit(theBornSpectatorMomentum,GeV); } void TildeKinematics::Init() { static ClassDocumentation documentation ("TildeKinematics is the base class for the 'tilde' " "kinematics being used for subtraction terms in the " "formalism of Catani and Seymour."); } // *** 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 describeTildeKinematics("Herwig::TildeKinematics", "Herwig.so"); diff --git a/MatrixElement/Matchbox/Phasespace/TildeKinematics.h b/MatrixElement/Matchbox/Phasespace/TildeKinematics.h --- a/MatrixElement/Matchbox/Phasespace/TildeKinematics.h +++ b/MatrixElement/Matchbox/Phasespace/TildeKinematics.h @@ -1,384 +1,369 @@ // -*- C++ -*- // // TildeKinematics.h is a part of Herwig - A multi-purpose Monte Carlo event generator // Copyright (C) 2002-2019 The Herwig Collaboration // // Herwig is licenced under version 3 of the GPL, see COPYING for details. // Please respect the MCnet academic guidelines, see GUIDELINES for details. // #ifndef HERWIG_TildeKinematics_H #define HERWIG_TildeKinematics_H // // This is the declaration of the TildeKinematics class. // #include "ThePEG/Handlers/HandlerBase.h" #include "ThePEG/Handlers/StandardXComb.h" #include "Herwig/MatrixElement/Matchbox/Dipoles/SubtractionDipole.h" namespace Herwig { using namespace ThePEG; /** * \ingroup Matchbox * \author Simon Platzer * * \brief TildeKinematics is the base class for the 'tilde' * kinematics being used for subtraction terms in the * formalism of Catani and Seymour. * */ class TildeKinematics: public HandlerBase { public: - /** @name Standard constructors and destructors. */ - //@{ - /** - * The default constructor. - */ - TildeKinematics(); - - /** - * The destructor. - */ - virtual ~TildeKinematics(); - //@} - -public: - /** * Clone this object */ Ptr::ptr cloneMe() const { return dynamic_ptr_cast::ptr>(clone()); } /** @name Access to kinematic quantities. */ //@{ /** * Return the momentum of the emitter in the real emission process */ const Lorentz5Momentum& realEmitterMomentum() const { return theRealXComb->meMomenta()[theDipole->realEmitter()]; } /** * Return the momentum of the emission in the real emission process */ const Lorentz5Momentum& realEmissionMomentum() const { return theRealXComb->meMomenta()[theDipole->realEmission()]; } /** * Return the momentum of the spectator in the real emission process */ const Lorentz5Momentum& realSpectatorMomentum() const { return theRealXComb->meMomenta()[theDipole->realSpectator()]; } /** * Return the momentum of the emitter in the underlying Born process */ const Lorentz5Momentum& bornEmitterMomentum() const { return theBornEmitterMomentum; } /** * Return the momentum of the spectator in the underlying Born process */ const Lorentz5Momentum& bornSpectatorMomentum() const { return theBornSpectatorMomentum; } /** * Return the vector of dimensionless variables calculated */ const vector& subtractionParameters() const { return theDipole->subtractionParameters(); } /** * Return true, if this TildeKinematics object needs to transform * all other particles in the process except the emitter and spectator */ virtual bool doesTransform() const { return false; } /** * If this TildeKinematics object needs to transform all other particles * in the process except the emitter and spectator, return the transformed * momentum. */ virtual Lorentz5Momentum transform(const Lorentz5Momentum& p) const { return p; } //@} /** * If this tilde kinematics is implementing a mapping different from * the baseline dipole mapping, determine the relevant shower * parameters and check for phase space boundaries. Note that real * emission kinematics only are available at this stage. */ virtual void getShowerVariables() const {} /** * If this tilde kinematics is implementing a mapping different from * the baseline dipole mapping, return the ratio of phase space * factorization Jacobians for this and the nominal dipole * mapping. This is used for matching subtractions. */ virtual double jacobianRatio() const { return 1.; } public: /** @name Access to process data. */ //@{ /** * Prepare given a dipole, and XCombs describing the real emission * and underlying Born processes, respectively. */ void prepare(tcStdXCombPtr newRealXComb, tcStdXCombPtr newBornXComb) { theRealXComb = newRealXComb; theBornXComb = newBornXComb; } /** * Set the current dipole */ void dipole(Ptr::tptr dip) { theDipole = dip; } /** * Return the current dipole */ Ptr::tptr dipole() { return theDipole; } /** * Return the current dipole */ Ptr::tcptr dipole() const { return theDipole; } /** * Perform the mapping to the tilde kinematics for the * last selected process and store all dimensionless * variables in the subtractionParameters() vector. * Return false, if the calculation of the tilde * kinematics was impossible for the selected configuration * and true on success. */ virtual bool doMap() = 0; /** * Return the pt associated to the last merged splitting. */ virtual Energy lastPt() const = 0; /** * Return the pt associated to emitter emission and sppectator momentum. */ virtual Energy lastPt(Lorentz5Momentum,Lorentz5Momentum,Lorentz5Momentum) const =0 ; /** * Given a pt and a hard pt, return the boundaries on z; */ virtual pair zBounds(Energy pt, Energy hardPt ) const = 0; /** * Return the momentum fraction associated to the last splitting. */ virtual double lastZ() const = 0; /** * Return the relevant dipole scale */ virtual Energy lastScale() const; virtual bool aboveAlpha() const { cerr<<"only implemented for light kinematics"; assert(false); return false; } /** * Return the particle type of the emitter in the real emission process */ cPDPtr realEmitterData() const { return (theDipole && theRealXComb) ? theRealXComb->mePartonData()[theDipole->realEmitter()] : cPDPtr(); } /** * Return the particle type of the emission in the real emission process */ cPDPtr realEmissionData() const { return (theDipole && theRealXComb) ? theRealXComb->mePartonData()[theDipole->realEmission()] : cPDPtr(); } /** * Return the particle type of the spectator in the real emission process */ cPDPtr realSpectatorData() const { return (theDipole && theRealXComb) ? theRealXComb->mePartonData()[theDipole->realSpectator()] : cPDPtr(); } /** * Return the particle type of the emitter in the underlying Born process */ cPDPtr bornEmitterData() const { return (theDipole && theBornXComb) ? theBornXComb->mePartonData()[theDipole->bornEmitter()] : cPDPtr(); } /** * Return the particle type of the spectator in the underlying Born process */ cPDPtr bornSpectatorData() const { return (theDipole && theBornXComb) ? theBornXComb->mePartonData()[theDipole->bornSpectator()] : cPDPtr(); } //@} protected: /** * Access the momentum of the emitter in the underlying Born process */ Lorentz5Momentum& bornEmitterMomentum() { return theBornEmitterMomentum; } /** * Access the momentum of the spectator in the underlying Born process */ Lorentz5Momentum& bornSpectatorMomentum() { return theBornSpectatorMomentum; } /** * Access the vector of dimensionless variables calculated */ vector& subtractionParameters() { return theDipole->subtractionParameters(); } public: /** * Return the momentum fraction of the emitter */ double emitterX() const { return theDipole->bornEmitter() == 0 ? theBornXComb->lastX1() : theBornXComb->lastX2(); } /** * Return the momentum fraction of the spectator */ double spectatorX() const { return theDipole->bornSpectator() == 0 ? theBornXComb->lastX1() : theBornXComb->lastX2(); } 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(); // If needed, insert declarations of virtual function defined in the // InterfacedBase class here (using ThePEG-interfaced-decl in Emacs). protected: /** @name Standard Interfaced functions. */ //@{ /** * Rebind pointer to other Interfaced objects. Called in the setup phase * after all objects used in an EventGenerator has been cloned so that * the pointers will refer to the cloned objects afterwards. * @param trans a TranslationMap relating the original objects to * their respective clones. * @throws RebindException if no cloned object was found for a given * pointer. */ virtual void rebind(const TranslationMap & trans); /** * Return a vector of all pointers to Interfaced objects used in this * object. * @return a vector of pointers. */ virtual IVector getReferences(); //@} private: /** * The last dipole this TildeKinematics has been selected for */ Ptr::tptr theDipole; /** * The XComb object describing the real emission process */ tcStdXCombPtr theRealXComb; /** * The XComb object describing the underlying Born process */ tcStdXCombPtr theBornXComb; /** * The momentum of the emitter in the underlying Born process */ Lorentz5Momentum theBornEmitterMomentum; /** * The momentum of the spectator in the underlying Born process */ Lorentz5Momentum theBornSpectatorMomentum; private: /** * The assignment operator is private and must never be called. * In fact, it should not even be implemented. */ TildeKinematics & operator=(const TildeKinematics &) = delete; }; } #endif /* HERWIG_TildeKinematics_H */ diff --git a/MatrixElement/Matchbox/Phasespace/TreePhasespace.cc b/MatrixElement/Matchbox/Phasespace/TreePhasespace.cc --- a/MatrixElement/Matchbox/Phasespace/TreePhasespace.cc +++ b/MatrixElement/Matchbox/Phasespace/TreePhasespace.cc @@ -1,234 +1,232 @@ // -*- C++ -*- // // TreePhasespace.cc is a part of Herwig - A multi-purpose Monte Carlo event generator // Copyright (C) 2002-2019 The Herwig Collaboration // // Herwig is licenced under version 3 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 TreePhasespace class. // #include #include #include "TreePhasespace.h" #include "ThePEG/Interface/ClassDocumentation.h" #include "ThePEG/Interface/Parameter.h" #include "ThePEG/Interface/Reference.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/MatrixElement/Matchbox/Utility/DiagramDrawer.h" #include "ThePEG/Persistency/PersistentOStream.h" #include "ThePEG/Persistency/PersistentIStream.h" using namespace Herwig; using namespace Herwig::PhasespaceHelpers; TreePhasespace::TreePhasespace() : x0(0.01), xc(1e-4), M0(ZERO), Mc(ZERO) { lastPhasespaceInfo.x0 = x0; lastPhasespaceInfo.xc = xc; lastPhasespaceInfo.M0 = M0; lastPhasespaceInfo.Mc = Mc; theIncludeMirrored = true; } -TreePhasespace::~TreePhasespace() {} - IBPtr TreePhasespace::clone() const { return new_ptr(*this); } IBPtr TreePhasespace::fullclone() const { return new_ptr(*this); } void TreePhasespace::setXComb(tStdXCombPtr xco) { MatchboxPhasespace::setXComb(xco); lastChannelsIterator = channelMap().find(lastXCombPtr()); if ( lastChannelsIterator == channelMap().end() ) { map::ptr,pair > channels; for ( auto const & d : lastXComb().diagrams()) { PhasespaceTree tree; Ptr::ptr diag = dynamic_ptr_cast::ptr>(d); tree.setup(*diag); PhasespaceTree treeMirror; treeMirror.setupMirrored(*diag, diag->nSpace() - 1); channels[diag] = make_pair(tree,treeMirror); } channelMap()[lastXCombPtr()] = channels; lastChannelsIterator = channelMap().find(lastXCombPtr()); } } double TreePhasespace::generateTwoToNKinematics(const double* random, vector& momenta) { lastPhasespaceInfo.sHat = lastXComb().lastSHat(); lastPhasespaceInfo.sqrtSHat = sqrt(lastXComb().lastSHat()); lastPhasespaceInfo.weight = 1.; size_t nchannels = lastXComb().diagrams().size(); bool doMirror = (UseRandom::rnd() < 0.5) && theIncludeMirrored; map::ptr, pair >::iterator ds = lastChannels().begin(); size_t i = (size_t)(random[0]*nchannels); advance(ds,i); Ptr::ptr channel = ds->first; ++random; lastPhasespaceInfo.rnd.numbers = random; lastPhasespaceInfo.rnd.nRnd = 3*momenta.size() - 10; try { if ( !doMirror ) lastChannels()[channel].first.generateKinematics(lastPhasespaceInfo,momenta); else lastChannels()[channel].second.generateKinematics(lastPhasespaceInfo,momenta); } catch (Veto) { return 0.; } if ( !matchConstraints(momenta) ) return 0.; double flatCut = x0; if ( M0 != ZERO ) flatCut = M0/sqrt(lastSHat()); fillDiagramWeights(flatCut); double sum = 0.; for ( auto const & d : lastChannels()) sum += diagramWeight(*(d.first)); double piWeight = pow(2.*Constants::pi,(double)(3*(momenta.size()-2)-4)); for ( auto & k : momenta ) k.rescaleRho(); return nchannels*lastPhasespaceInfo.weight*diagramWeight(*channel)/(sum*piWeight); } // If needed, insert default implementations of virtual function defined // in the InterfacedBase class here (using ThePEG-interfaced-impl in Emacs). void TreePhasespace::doinit() { MatchboxPhasespace::doinit(); lastPhasespaceInfo.x0 = x0; lastPhasespaceInfo.xc = xc; lastPhasespaceInfo.M0 = M0; lastPhasespaceInfo.Mc = Mc; } void TreePhasespace::doinitrun() { MatchboxPhasespace::doinitrun(); lastPhasespaceInfo.x0 = x0; lastPhasespaceInfo.xc = xc; lastPhasespaceInfo.M0 = M0; lastPhasespaceInfo.Mc = Mc; } void TreePhasespace::persistentOutput(PersistentOStream & os) const { os << theChannelMap << x0 << xc << ounit(M0,GeV) << ounit(Mc,GeV) << theIncludeMirrored << theLastXComb; } void TreePhasespace::persistentInput(PersistentIStream & is, int) { is >> theChannelMap >> x0 >> xc >> iunit(M0,GeV) >> iunit(Mc,GeV) >> theIncludeMirrored >> theLastXComb; lastPhasespaceInfo.x0 = x0; lastPhasespaceInfo.xc = xc; lastPhasespaceInfo.M0 = M0; lastPhasespaceInfo.Mc = Mc; lastChannelsIterator = channelMap().find(lastXCombPtr()); } // *** 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 describeHerwigTreePhasespace("Herwig::TreePhasespace", "Herwig.so"); void TreePhasespace::Init() { static ClassDocumentation documentation ("TreePhasespace is a multi-channel phase space generator " "adapting to singularity structures as determined from the matrix " "elements diagrams."); static Reference interfaceChannelMap ("ChannelMap", "Set the object storing the channels.", &TreePhasespace::theChannelMap, false, false, true, false, false); interfaceChannelMap.rank(-1); static Parameter interfaceX0 ("X0", "Set the cut below which flat virtuality sampling is imposed.", &TreePhasespace::x0, 0.01, 0.0, 0, false, false, Interface::lowerlim); static Parameter interfaceXC ("XC", "Set the cut below which no virtualities are generated.", &TreePhasespace::xc, 1e-4, 0.0, 0, false, false, Interface::lowerlim); static Parameter interfaceM0 ("M0", "Set the cut below which flat virtuality sammpling is imposed.", &TreePhasespace::M0, GeV, 0.0*GeV, 0.0*GeV, 0*GeV, false, false, Interface::lowerlim); static Parameter interfaceMC ("MC", "Set the cut below which no virtualities are generated.", &TreePhasespace::Mc, GeV, 0.0*GeV, 0.0*GeV, 0*GeV, false, false, Interface::lowerlim); static Switch interfaceIncludeMirrored ("IncludeMirrored", "Choose whether to include mirrored diagrams for PS generation", &TreePhasespace::theIncludeMirrored, true, true, false); static SwitchOption interfaceIncludeMirroredYes (interfaceIncludeMirrored, "Yes", "Use unmirrored and mirrored diagrams", true); static SwitchOption interfaceIncludeMirroredNo (interfaceIncludeMirrored, "No", "Use only unmirrored diagrams", false); interfaceIncludeMirrored.rank(-1); } diff --git a/MatrixElement/Matchbox/Phasespace/TreePhasespace.h b/MatrixElement/Matchbox/Phasespace/TreePhasespace.h --- a/MatrixElement/Matchbox/Phasespace/TreePhasespace.h +++ b/MatrixElement/Matchbox/Phasespace/TreePhasespace.h @@ -1,217 +1,209 @@ // -*- C++ -*- // // TreePhasespace.h is a part of Herwig - A multi-purpose Monte Carlo event generator // Copyright (C) 2002-2019 The Herwig Collaboration // // Herwig is licenced under version 3 of the GPL, see COPYING for details. // Please respect the MCnet academic guidelines, see GUIDELINES for details. // #ifndef Herwig_TreePhasespace_H #define Herwig_TreePhasespace_H // // This is the declaration of the TreePhasespace class. // #include "Herwig/MatrixElement/Matchbox/Phasespace/MatchboxPhasespace.h" #include "Herwig/MatrixElement/Matchbox/Phasespace/TreePhasespaceChannels.h" namespace Herwig { using namespace ThePEG; /** * \ingroup Matchbox * \author Simon Platzer, Ken Arnold * * \brief TreePhasespace is a multi-channel phase space generator * adapting to singularity structures as determined from the matrix * elements diagrams. * * @see \ref TreePhasespaceInterfaces "The interfaces" * defined for TreePhasespace. */ class TreePhasespace: public MatchboxPhasespace { public: - /** @name Standard constructors and destructors. */ - //@{ /** * The default constructor. */ TreePhasespace(); - /** - * The destructor. - */ - virtual ~TreePhasespace(); - //@} - public: /** * Prepare a phase space generator for the given xcomb object. */ virtual void setXComb(tStdXCombPtr); /** * Generate a phase space point and return its weight. */ virtual double generateTwoToNKinematics(const double*, vector& momenta); /** * Return the number of random numbers required to produce a given * multiplicity final state. */ virtual int nDimPhasespace(int nFinal) const { if ( nFinal == 1 ) return 1; return 3*(nFinal - 1); // one additional number needed for channel selection } 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). protected: /** @name Standard Interfaced functions. */ //@{ /** * Initialize this object after the setup phase before saving an * EventGenerator to disk. * @throws InitException if object could not be initialized properly. */ virtual void doinit(); /** * Initialize this object. Called in the run phase just before * a run begins. */ virtual void doinitrun(); //@} private: /** * The object storing channel maps */ Ptr::ptr theChannelMap; /** * Map xcomb's to channel vectors indexed by diagram id. */ map::ptr, pair > >& channelMap() { return theChannelMap->channelMap(); } /** * The currently active channels. */ map::ptr, pair > >::iterator lastChannelsIterator; /** * The phase space info object to be used. */ PhasespaceHelpers::PhasespaceInfo lastPhasespaceInfo; /** * Parameter steering from which on propagator virtualities are * sampled flat. */ double x0; /** * Parameter steering at which virtuality singularities of * propagators are actually cut off. */ double xc; /** * Parameter steering from which on propagator virtualities are * sampled flat. */ Energy M0; /** * Parameter steering at which virtuality singularities of * propagators are actually cut off. */ Energy Mc; /** * Choose whether to also use mirrored phase space generation */ bool theIncludeMirrored; /** * Return the currently active channels. */ map::ptr, pair >& lastChannels() { return lastChannelsIterator->second; } private: /** * The assignment operator is private and must never be called. * In fact, it should not even be implemented. */ TreePhasespace & operator=(const TreePhasespace &) = delete; }; } #endif /* Herwig_TreePhasespace_H */ diff --git a/MatrixElement/Matchbox/Phasespace/TreePhasespaceChannels.cc b/MatrixElement/Matchbox/Phasespace/TreePhasespaceChannels.cc --- a/MatrixElement/Matchbox/Phasespace/TreePhasespaceChannels.cc +++ b/MatrixElement/Matchbox/Phasespace/TreePhasespaceChannels.cc @@ -1,89 +1,83 @@ // -*- C++ -*- // // TreePhasespaceChannels.cc is a part of Herwig - A multi-purpose Monte Carlo event generator // Copyright (C) 2002-2019 The Herwig Collaboration // // Herwig is licenced under version 3 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 TreePhasespaceChannels class. // #include "TreePhasespaceChannels.h" #include "ThePEG/Interface/ClassDocumentation.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" using namespace Herwig; using namespace Herwig::PhasespaceHelpers; -TreePhasespaceChannels::TreePhasespaceChannels() {} - -TreePhasespaceChannels::~TreePhasespaceChannels() {} - IBPtr TreePhasespaceChannels::clone() const { return new_ptr(*this); } IBPtr TreePhasespaceChannels::fullclone() const { return new_ptr(*this); } // If needed, insert default implementations of virtual function defined // in the InterfacedBase class here (using ThePEG-interfaced-impl in Emacs). void TreePhasespaceChannels::persistentOutput(PersistentOStream & os) const { os << theChannelMap.size(); for ( map::ptr,pair > >::const_iterator k = theChannelMap.begin(); k != theChannelMap.end(); ++k ) { os << k->first << k->second.size(); for ( map::ptr,pair >::const_iterator l = k->second.begin(); l != k->second.end(); ++l ) { os << l->first; l->second.first.put(os); l->second.second.put(os); } } } void TreePhasespaceChannels::persistentInput(PersistentIStream & is, int) { size_t nk; is >> nk; for ( size_t k = 0; k < nk; ++k ) { tStdXCombPtr xc; is >> xc; size_t nl; is >> nl; map::ptr,pair > cm; for ( size_t l = 0; l < nl; ++l ) { Ptr::ptr ci; is >> ci; pair cp; cp.first.get(is); cp.second.get(is); cm[ci] = cp; } theChannelMap[xc] = cm; } } // *** 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 describeHerwigTreePhasespaceChannels("Herwig::TreePhasespaceChannels", "Herwig.so"); void TreePhasespaceChannels::Init() { static ClassDocumentation documentation ("Store channels for the tree phase space."); } diff --git a/MatrixElement/Matchbox/Phasespace/TreePhasespaceChannels.h b/MatrixElement/Matchbox/Phasespace/TreePhasespaceChannels.h --- a/MatrixElement/Matchbox/Phasespace/TreePhasespaceChannels.h +++ b/MatrixElement/Matchbox/Phasespace/TreePhasespaceChannels.h @@ -1,128 +1,113 @@ // -*- C++ -*- // // TreePhasespaceChannels.h is a part of Herwig - A multi-purpose Monte Carlo event generator // Copyright (C) 2002-2019 The Herwig Collaboration // // Herwig is licenced under version 3 of the GPL, see COPYING for details. // Please respect the MCnet academic guidelines, see GUIDELINES for details. // #ifndef Herwig_TreePhasespaceChannels_H #define Herwig_TreePhasespaceChannels_H // // This is the declaration of the TreePhasespaceChannels class. // #include "ThePEG/Handlers/HandlerBase.h" #include "Herwig/MatrixElement/Matchbox/Phasespace/PhasespaceHelpers.h" namespace Herwig { using namespace ThePEG; /** * * \ingroup Matchbox * \author Simon Platzer, Ken Arnold * * \brief Store channels for the tree phasespace. * * @see \ref TreePhasespaceChannelsInterfaces "The interfaces" * defined for TreePhasespaceChannels. */ class TreePhasespaceChannels: public HandlerBase { public: - /** @name Standard constructors and destructors. */ - //@{ - /** - * The default constructor. - */ - TreePhasespaceChannels(); - - /** - * The destructor. - */ - virtual ~TreePhasespaceChannels(); - //@} - -public: - /** * Access the channel map */ map::ptr,pair > >& channelMap() { return theChannelMap; } /** * Return the channel map */ const map::ptr,pair > >& channelMap() const { return theChannelMap; } 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: /** * Map xcomb's to channel vectors indexed by diagram id. */ map::ptr,pair > > theChannelMap; /** * The assignment operator is private and must never be called. * In fact, it should not even be implemented. */ TreePhasespaceChannels & operator=(const TreePhasespaceChannels &) = delete; }; } #endif /* Herwig_TreePhasespaceChannels_H */