diff --git a/DipoleShower/Kinematics/DipoleSplittingKinematics.cc b/DipoleShower/Kinematics/DipoleSplittingKinematics.cc
--- a/DipoleShower/Kinematics/DipoleSplittingKinematics.cc
+++ b/DipoleShower/Kinematics/DipoleSplittingKinematics.cc
@@ -1,238 +1,239 @@
 // -*- C++ -*-
 //
 // DipoleSplittingKinematics.h is a part of Herwig - A multi-purpose Monte Carlo event generator
 // Copyright (C) 2002-2007 The Herwig Collaboration
 //
 // Herwig is licenced under version 2 of the GPL, see COPYING for details.
 // Please respect the MCnet academic guidelines, see GUIDELINES for details.
 //
 //
 // This is the implementation of the non-inlined, non-templated member
 // functions of the DipoleSplittingKinematics class.
 //
 
 #include "DipoleSplittingKinematics.h"
 #include "Herwig/DipoleShower/Base/DipoleSplittingInfo.h"
 #include "ThePEG/Interface/ClassDocumentation.h"
 #include "ThePEG/Interface/Reference.h"
 #include "ThePEG/Interface/Parameter.h"
 
 #include "ThePEG/Persistency/PersistentOStream.h"
 #include "ThePEG/Persistency/PersistentIStream.h"
 
 #include "Herwig/MatrixElement/Matchbox/Phasespace/RandomHelpers.h"
 
 #include <limits>
 
 using namespace Herwig;
 
 DipoleSplittingKinematics::DipoleSplittingKinematics()
   : HandlerBase(), theIRCutoff(1.0*GeV), 
     theXMin(1.e-5), theJacobian(0.0),
     theLastPt(0.0*GeV), theLastZ(0.0), theLastPhi(0.0),
     theLastEmitterZ(1.0), theLastSpectatorZ(1.0),
     theLastSplittingParameters() {}
 
 DipoleSplittingKinematics::~DipoleSplittingKinematics() {}
 
 void DipoleSplittingKinematics::persistentOutput(PersistentOStream & os) const {
   os << ounit(theIRCutoff,GeV) << theXMin << theMCCheck;
 }
 
 void DipoleSplittingKinematics::persistentInput(PersistentIStream & is, int) {
   is >> iunit(theIRCutoff,GeV) >> theXMin >> theMCCheck;
 }
 
 void DipoleSplittingKinematics::prepareSplitting(DipoleSplittingInfo& dInfo) {
 
   dInfo.splittingKinematics(this);
 
   if ( lastPt() > IRCutoff() )
     dInfo.lastPt(lastPt());
   else {
     dInfo.lastPt(0.0*GeV);
     dInfo.didStopEvolving();
   }
 
   dInfo.lastZ(lastZ());
   dInfo.lastPhi(lastPhi());
   dInfo.lastEmitterZ(lastEmitterZ());
   dInfo.lastSpectatorZ(lastSpectatorZ());
   dInfo.splittingParameters().resize(lastSplittingParameters().size());
   copy(lastSplittingParameters().begin(),lastSplittingParameters().end(),
        dInfo.splittingParameters().begin());
   
 }
 
 Energy DipoleSplittingKinematics::generatePt(double r, Energy dScale,
 					     double emX, double specX,
 					     const DipoleIndex& dIndex,
 					     const DipoleSplittingKernel& split,
 					     double& weight) const {
 
   Energy maxPt = ptMax(dScale,emX,specX,dIndex,split);
   if ( maxPt <= IRCutoff() ) {
     weight = 0.0;
     return ZERO;
   }
 
   weight *= log(sqr(maxPt/IRCutoff()));
 
   return IRCutoff()*pow(maxPt/IRCutoff(),r);
 
 }
 
 double DipoleSplittingKinematics::ptToRandom(Energy pt, Energy dScale,
 					     double emX, double specX,
 					     const DipoleIndex& dIndex,
 					     const DipoleSplittingKernel& split) const {
 
   Energy maxPt = ptMax(dScale,emX,specX,dIndex,split);
   assert(pt >= IRCutoff() && pt <= maxPt);
 
   return log(pt/IRCutoff())/log(maxPt/IRCutoff());
 
 }
 
 double DipoleSplittingKinematics::generateZ(double r, Energy pt, int sampling,
 					    const DipoleSplittingInfo& dInfo,
 					    const DipoleSplittingKernel& split,
 					    double& weight) const {
 
   pair<double,double> zLims = zBoundaries(pt,dInfo,split);
 
   using namespace RandomHelpers;
 
   if ( sampling == FlatZ ) {
     pair<double,double> kw = generate(flat(zLims.first,zLims.second),r);
     weight *= kw.second;
     return kw.first;
   }
 
   if ( sampling == OneOverZ ) {
     pair<double,double> kw = generate(inverse(0.0,zLims.first,zLims.second),r);
     weight *= kw.second;
     return kw.first;
   }
 
   if ( sampling == OneOverOneMinusZ ) {
     pair<double,double> kw = generate(inverse(1.0,zLims.first,zLims.second),r);
     weight *= kw.second;
     return kw.first;
   }
 
   if ( sampling == OneOverZOneMinusZ ) {
     pair<double,double> kw = generate(inverse(0.0,zLims.first,zLims.second) + 
 				      inverse(1.0,zLims.first,zLims.second),r);
     weight *= kw.second;
     return kw.first;
   }
 
   weight = 0.0;
   return 0.0;
 
 }
 
 Lorentz5Momentum DipoleSplittingKinematics::getKt(const Lorentz5Momentum& p1,
 						  const Lorentz5Momentum& p2,
 						  Energy pt,
 						  double phi,
 						  bool spacelike) const {
 
   Lorentz5Momentum P;
   if ( !spacelike )
     P = p1 + p2;
   else
     P = p1 - p2;
 
   Energy2 Q2 = abs(P.m2());
 
   Lorentz5Momentum Q = 
     !spacelike ? 
     Lorentz5Momentum(ZERO,ZERO,ZERO,sqrt(Q2),sqrt(Q2)) :
     Lorentz5Momentum(ZERO,ZERO,sqrt(Q2),ZERO,-sqrt(Q2));
 
   if ( spacelike && Q.z() < P.z() )
     Q.setZ(-Q.z());
 
   bool boost =
     abs((P-Q).vect().mag2()/GeV2) > 1e-10 ||
     abs((P-Q).t()/GeV) > 1e-5;
+  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;
 
 }
 
 // If needed, insert default implementations of virtual function defined
 // in the InterfacedBase class here (using ThePEG-interfaced-impl in Emacs).
 
 AbstractClassDescription<DipoleSplittingKinematics> DipoleSplittingKinematics::initDipoleSplittingKinematics;
 // Definition of the static class description member.
 
 void DipoleSplittingKinematics::Init() {
 
   static ClassDocumentation<DipoleSplittingKinematics> documentation
     ("DipoleSplittingKinematics is the base class for dipole splittings "
      "as performed in the dipole shower.");
 
 
   static Parameter<DipoleSplittingKinematics,Energy> interfaceIRCutoff
     ("IRCutoff",
      "The IR cutoff to be used by this splitting kinematics.",
      &DipoleSplittingKinematics::theIRCutoff, GeV, 1.0*GeV, 0.0*GeV, 0*GeV,
      false, false, Interface::lowerlim);
 
 
   static Parameter<DipoleSplittingKinematics,double> interfaceXMin
     ("XMin",
      "The minimum momentum fraction for incoming partons",
      &DipoleSplittingKinematics::theXMin, 1.0e-5, 0.0, 1.0,
      false, false, Interface::limited);
 
 
   static Reference<DipoleSplittingKinematics,DipoleMCCheck> interfaceMCCheck
     ("MCCheck",
      "[debug option] MCCheck",
      &DipoleSplittingKinematics::theMCCheck, false, false, true, true, false);
 
   interfaceMCCheck.rank(-1);
 
 }
 
diff --git a/MatrixElement/Matchbox/Base/MatchboxMEBase.cc b/MatrixElement/Matchbox/Base/MatchboxMEBase.cc
--- a/MatrixElement/Matchbox/Base/MatchboxMEBase.cc
+++ b/MatrixElement/Matchbox/Base/MatchboxMEBase.cc
@@ -1,1708 +1,1722 @@
 // -*- C++ -*-
 //
 // MatchboxMEBase.cc is a part of Herwig - A multi-purpose Monte Carlo event generator
 // Copyright (C) 2002-2012 The Herwig Collaboration
 //
 // Herwig is licenced under version 2 of the GPL, see COPYING for details.
 // Please respect the MCnet academic guidelines, see GUIDELINES for details.
 //
 //
 // This is the implementation of the non-inlined, non-templated member
 // functions of the MatchboxMEBase class.
 //
 
 #include "MatchboxMEBase.h"
 #include "ThePEG/Utilities/DescribeClass.h"
 #include "ThePEG/Interface/ClassDocumentation.h"
 #include "ThePEG/Interface/Parameter.h"
 #include "ThePEG/Interface/Reference.h"
 #include "ThePEG/Interface/RefVector.h"
 #include "ThePEG/Interface/Switch.h"
 #include "ThePEG/Persistency/PersistentOStream.h"
 #include "ThePEG/Persistency/PersistentIStream.h"
 #include "ThePEG/PDF/PDF.h"
 #include "ThePEG/PDT/PDT.h"
 #include "ThePEG/StandardModel/StandardModelBase.h"
 #include "ThePEG/Cuts/Cuts.h"
 #include "ThePEG/Handlers/StdXCombGroup.h"
 #include "ThePEG/EventRecord/SubProcess.h"
 #include "Herwig/MatrixElement/Matchbox/Dipoles/SubtractionDipole.h"
 #include "Herwig/MatrixElement/Matchbox/Utility/DiagramDrawer.h"
 #include "Herwig/MatrixElement/Matchbox/MatchboxFactory.h"
 #include "Herwig/Utilities/RunDirectories.h"
 #include "Herwig/MatrixElement/ProductionMatrixElement.h"
 #include "Herwig/MatrixElement/HardVertex.h"
 
 #include <boost/foreach.hpp>
 #include <cctype>
 
 #include <iterator>
 using std::ostream_iterator;
 
 using namespace Herwig;
 
 MatchboxMEBase::MatchboxMEBase() 
   : MEBase(), 
     theOneLoop(false),
     theOneLoopNoBorn(false),
     theOneLoopNoLoops(false),
     theNoCorrelations(false),
     theHavePDFs(false,false), checkedPDFs(false),
     theDiagramWeightVerboseDown(10000000000000.),
     theDiagramWeightVerboseUp(0.) {}
 
 MatchboxMEBase::~MatchboxMEBase() {}
 
 Ptr<MatchboxFactory>::tptr MatchboxMEBase::factory() const { return theFactory; }
 
 void MatchboxMEBase::factory(Ptr<MatchboxFactory>::tptr f) { theFactory = f; }
 
 Ptr<Tree2toNGenerator>::tptr MatchboxMEBase::diagramGenerator() const { return factory()->diagramGenerator(); }
 
 Ptr<ProcessData>::tptr MatchboxMEBase::processData() const { return factory()->processData(); }
 
 unsigned int MatchboxMEBase::getNLight() const { return factory()->nLight(); }
 
 vector<int> MatchboxMEBase::getNLightJetVec() const { return factory()->nLightJetVec(); }
 
 vector<int> MatchboxMEBase::getNHeavyJetVec() const { return factory()->nHeavyJetVec(); }
 
 vector<int> MatchboxMEBase::getNLightProtonVec() const { return factory()->nLightProtonVec(); }
 
 double MatchboxMEBase::factorizationScaleFactor() const { return factory()->factorizationScaleFactor(); }
 
 double MatchboxMEBase::renormalizationScaleFactor() const { return factory()->renormalizationScaleFactor(); }
 
 bool MatchboxMEBase::fixedCouplings() const { return factory()->fixedCouplings(); }
 
 bool MatchboxMEBase::fixedQEDCouplings() const { return factory()->fixedQEDCouplings(); }
 
 bool MatchboxMEBase::checkPoles() const { return factory()->checkPoles(); }
 
 bool MatchboxMEBase::verbose() const { return factory()->verbose(); }
 
 bool MatchboxMEBase::initVerbose() const { return factory()->initVerbose(); }
 
 void MatchboxMEBase::getDiagrams() const {
 
   if ( diagramGenerator() && processData() ) {
 
     vector<Ptr<Tree2toNDiagram>::ptr> diags;
 
     vector<Ptr<Tree2toNDiagram>::ptr>& res =
       processData()->diagramMap()[subProcess().legs];
     if ( res.empty() ) {
       res = diagramGenerator()->generate(subProcess().legs,orderInAlphaS(),orderInAlphaEW());
     }
     copy(res.begin(),res.end(),back_inserter(diags));
     processData()->fillMassGenerators(subProcess().legs);
 
     if ( diags.empty() )
       return;
 
     for ( vector<Ptr<Tree2toNDiagram>::ptr>::iterator d = diags.begin();
 	  d != diags.end(); ++d ) {
       add(*d);
     }
 
     return;
 
   }
 
   throw Exception()
     << "MatchboxMEBase::getDiagrams() expects a Tree2toNGenerator and ProcessData object.\n"
     << "Please check your setup." << Exception::runerror;
 
 }
 
 Selector<MEBase::DiagramIndex> 
 MatchboxMEBase::diagrams(const DiagramVector & diags) const {
 
   if ( phasespace() ) {
     return phasespace()->selectDiagrams(diags);
   }
 
   throw Exception()
     << "MatchboxMEBase::diagrams() expects a MatchboxPhasespace object.\n"
     << "Please check your setup." << Exception::runerror;
   return Selector<MEBase::DiagramIndex>();
 
 }
 
 Selector<const ColourLines *>
 MatchboxMEBase::colourGeometries(tcDiagPtr diag) const {
 
   if ( matchboxAmplitude() ) {
     if ( matchboxAmplitude()->haveColourFlows() ) {
       if ( matchboxAmplitude()->treeAmplitudes() )
 	matchboxAmplitude()->prepareAmplitudes(this);
       return matchboxAmplitude()->colourGeometries(diag);
     }
   }
 
   Ptr<Tree2toNDiagram>::tcptr tdiag =
     dynamic_ptr_cast<Ptr<Tree2toNDiagram>::tcptr>(diag);
   assert(diag && processData());
 
   vector<ColourLines*>& flows = processData()->colourFlowMap()[tdiag];
 
   if ( flows.empty() ) {
 
     list<list<list<pair<int,bool> > > > cflows =
       ColourBasis::colourFlows(tdiag);
 
     for ( list<list<list<pair<int,bool> > > >::const_iterator fit =
 	    cflows.begin(); fit != cflows.end(); ++fit ) {
       flows.push_back(new ColourLines(ColourBasis::cfstring(*fit)));
     }
 
   }
 
   Selector<const ColourLines *> res;
   for ( vector<ColourLines*>::const_iterator f = flows.begin();
 	f != flows.end(); ++f )
     res.insert(1.0,*f);
 
   return res;
 
 }
 
 void MatchboxMEBase::constructVertex(tSubProPtr sub, const ColourLines* cl) {
 
   if ( !canFillRhoMatrix() || !factory()->spinCorrelations() )
     return;
 
   assert(matchboxAmplitude());
   assert(matchboxAmplitude()->colourBasis());
 
   // get the colour structure for the selected colour flow
   size_t cStructure = 
     matchboxAmplitude()->colourBasis()->tensorIdFromFlow(lastXComb().lastDiagram(),cl);
 
   // hard process for processing the spin info
   tPVector hard;
   hard.push_back(sub->incoming().first);
   hard.push_back(sub->incoming().second);
   
   vector<PDT::Spin> out;
   for ( size_t k = 0; k < sub->outgoing().size(); ++k ) {
     out.push_back(sub->outgoing()[k]->data().iSpin());
     hard.push_back(sub->outgoing()[k]);
   }
 
   // calculate dummy wave functions to fill the spin info
   static vector<VectorWaveFunction> dummyPolarizations;
   static vector<SpinorWaveFunction> dummySpinors;
   static vector<SpinorBarWaveFunction> dummyBarSpinors;
   for ( size_t k = 0; k < hard.size(); ++k ) {
     if ( hard[k]->data().iSpin() == PDT::Spin1Half ) {
       if ( hard[k]->id() > 0 && k > 1 ) {
 	SpinorBarWaveFunction(dummyBarSpinors,hard[k],
 			      outgoing, true);
       } else if ( hard[k]->id() < 0 && k > 1 ) {
 	SpinorWaveFunction(dummySpinors,hard[k],
 			   outgoing, true);
       } else if ( hard[k]->id() > 0 && k < 2 ) {
 	SpinorWaveFunction(dummySpinors,hard[k],
 			   incoming, false);
       } else if ( hard[k]->id() < 0 && k < 2 ) {
 	SpinorBarWaveFunction(dummyBarSpinors,hard[k],
 			      incoming, false);
       }
     } 
     else if ( hard[k]->data().iSpin() == PDT::Spin1 ) {
       VectorWaveFunction(dummyPolarizations,hard[k],
 			 k > 1 ? outgoing : incoming,
 			 k > 1 ? true : false,
 			 hard[k]->data().hardProcessMass() == ZERO);
     }
     else if (hard[k]->data().iSpin() == PDT::Spin0 ) {
       ScalarWaveFunction(hard[k],k > 1 ? outgoing : incoming,
 			 k > 1 ? true : false);
     }
     else
       assert(false);
   }
 
   // fill the production matrix element
   ProductionMatrixElement pMe(mePartonData()[0]->iSpin(),
 			      mePartonData()[1]->iSpin(),
 			      out);
   for ( map<vector<int>,CVector>::const_iterator lamp = lastLargeNAmplitudes().begin();
 	lamp != lastLargeNAmplitudes().end(); ++lamp ) {
     vector<unsigned int> pMeHelicities
       = matchboxAmplitude()->physicalHelicities(lamp->first);
     pMe(pMeHelicities) = lamp->second[cStructure];
   }
 
   // set the spin information
   HardVertexPtr hardvertex = new_ptr(HardVertex());
   hardvertex->ME(pMe);
   if ( sub->incoming().first->spinInfo() )
     sub->incoming().first->spinInfo()->productionVertex(hardvertex);
   if ( sub->incoming().second->spinInfo() )
     sub->incoming().second->spinInfo()->productionVertex(hardvertex);
   for ( ParticleVector::const_iterator p = sub->outgoing().begin();
 	p != sub->outgoing().end(); ++p ) {
     if ( (**p).spinInfo() )
       (**p).spinInfo()->productionVertex(hardvertex);
   }
 
 }
 
 unsigned int MatchboxMEBase::orderInAlphaS() const {
   return subProcess().orderInAlphaS;
 }
 
 unsigned int MatchboxMEBase::orderInAlphaEW() const {
   return subProcess().orderInAlphaEW;
 }
 
 void MatchboxMEBase::setXComb(tStdXCombPtr xc) {
 
   MEBase::setXComb(xc);
   lastMatchboxXComb(xc);
   if ( phasespace() )
     phasespace()->setXComb(xc);
   if ( scaleChoice() )
     scaleChoice()->setXComb(xc);
   if ( matchboxAmplitude() )
     matchboxAmplitude()->setXComb(xc);
 
 }
 
 double MatchboxMEBase::generateIncomingPartons(const double* r1, const double* r2) {
   
   // shamelessly stolen from PartonExtractor.cc
 
   Energy2 shmax = lastCuts().sHatMax();
   Energy2 shmin = lastCuts().sHatMin();
   Energy2 sh = shmin*pow(shmax/shmin, *r1);
   double ymax = lastCuts().yHatMax();
   double ymin = lastCuts().yHatMin();
   double km = log(shmax/shmin);
   ymax = min(ymax, log(lastCuts().x1Max()*sqrt(lastS()/sh)));
   ymin = max(ymin, -log(lastCuts().x2Max()*sqrt(lastS()/sh)));
 
   double y = ymin + (*r2)*(ymax - ymin);
   double x1 = exp(-0.5*log(lastS()/sh) + y);
   double x2 = exp(-0.5*log(lastS()/sh) - y);
 
   Lorentz5Momentum P1 = lastParticles().first->momentum();
   LorentzMomentum p1 = lightCone((P1.rho() + P1.e())*x1, Energy());
   p1.rotateY(P1.theta());
   p1.rotateZ(P1.phi());
   meMomenta()[0] = p1;
 
   Lorentz5Momentum P2 = lastParticles().second->momentum();
   LorentzMomentum p2 = lightCone((P2.rho() + P2.e())*x2, Energy());
   p2.rotateY(P2.theta());
   p2.rotateZ(P2.phi());
   meMomenta()[1] = p2;
 
   lastXCombPtr()->lastX1X2(make_pair(x1,x2));
   lastXCombPtr()->lastSHat((meMomenta()[0]+meMomenta()[1]).m2());
 
   return km*(ymax - ymin);
 
 }
 
 bool MatchboxMEBase::generateKinematics(const double * r) {
 
   if ( phasespace() ) {
 
     jacobian(phasespace()->generateKinematics(r,meMomenta()));
     if ( jacobian() == 0.0 )
       return false;
 
     setScale();
     logGenerateKinematics(r);
 
     assert(lastMatchboxXComb());
 
     if ( nDimAmplitude() > 0 ) {
       amplitudeRandomNumbers().resize(nDimAmplitude());
       copy(r + nDimPhasespace(), 
 	   r + nDimPhasespace() + nDimAmplitude(),
 	   amplitudeRandomNumbers().begin());
     }
 
     if ( nDimInsertions() > 0 ) {
       insertionRandomNumbers().resize(nDimInsertions());
       copy(r + nDimPhasespace() + nDimAmplitude(), 
 	   r + nDimPhasespace() + nDimAmplitude() + nDimInsertions(),
 	   insertionRandomNumbers().begin());
     }
 
     return true;
 
   }
 
   throw Exception()
     << "MatchboxMEBase::generateKinematics() expects a MatchboxPhasespace object.\n"
     << "Please check your setup." << Exception::runerror;
 
   return false;
 
 }
 
 int MatchboxMEBase::nDim() const { 
 
   if ( lastMatchboxXComb() )
     return nDimPhasespace() + nDimAmplitude() + nDimInsertions();
 
   int ampAdd = 0;
   if ( matchboxAmplitude() ) {
     ampAdd = matchboxAmplitude()->nDimAdditional();
   }
 
   int insertionAdd = 0;
   for ( vector<Ptr<MatchboxInsertionOperator>::ptr>::const_iterator v =
 	  virtuals().begin(); v != virtuals().end(); ++v ) {
     insertionAdd = max(insertionAdd,(**v).nDimAdditional());
   }
 
   return nDimBorn() + ampAdd + insertionAdd;
 
 }
 
 int MatchboxMEBase::nDimBorn() const { 
 
   if ( lastMatchboxXComb() )
     return nDimPhasespace();
 
   if ( phasespace() )
     return phasespace()->nDim(diagrams().front()->partons());
 
   throw Exception()
     << "MatchboxMEBase::nDim() expects a MatchboxPhasespace object.\n"
     << "Please check your setup." << Exception::runerror;
 
   return 0;
 
 }
 
 void MatchboxMEBase::setScale() const {
   if ( haveX1X2() ) {
     lastXCombPtr()->lastSHat((meMomenta()[0]+meMomenta()[1]).m2());
   }
   Energy2 fcscale = factorizationScale();
   Energy2 fscale = fcscale*sqr(factorizationScaleFactor());
   Energy2 rscale = renormalizationScale()*sqr(renormalizationScaleFactor());
   Energy2 ewrscale = renormalizationScaleQED();
   lastXCombPtr()->lastScale(fscale);
   lastXCombPtr()->lastCentralScale(fcscale);
+  lastXCombPtr()->lastShowerScale(showerScale());
   lastMatchboxXComb()->lastRenormalizationScale(rscale);
   if ( !fixedCouplings() ) {
     if ( rscale > lastCuts().scaleMin() )
       lastXCombPtr()->lastAlphaS(SM().alphaS(rscale));
     else
       lastXCombPtr()->lastAlphaS(SM().alphaS(lastCuts().scaleMin()));
   } else {
     lastXCombPtr()->lastAlphaS(SM().alphaS());
   }
   if ( !fixedQEDCouplings() ) {
     lastXCombPtr()->lastAlphaEM(SM().alphaEMME(ewrscale));
   } else {
     lastXCombPtr()->lastAlphaEM(SM().alphaEMMZ());
   }
   logSetScale();
 }
 
 Energy2 MatchboxMEBase::factorizationScale() const {
   if ( scaleChoice() ) {
     return scaleChoice()->factorizationScale();
   }
 
   throw Exception()
     << "MatchboxMEBase::factorizationScale() expects a MatchboxScaleChoice object.\n"
     << "Please check your setup." << Exception::runerror;
 
   return ZERO;
 
 }
 
 Energy2 MatchboxMEBase::renormalizationScale() const {
   if ( scaleChoice() ) {
     return scaleChoice()->renormalizationScale();
   }
 
   throw Exception()
     << "MatchboxMEBase::renormalizationScale() expects a MatchboxScaleChoice object.\n"
     << "Please check your setup." << Exception::runerror;
 
   return ZERO;
 
 }
 
 Energy2 MatchboxMEBase::renormalizationScaleQED() const {
   if ( scaleChoice() ) {
     return scaleChoice()->renormalizationScaleQED();
   }
   return renormalizationScale();
 }
 
+Energy2 MatchboxMEBase::showerScale() const {
+  if ( scaleChoice() ) {
+    return scaleChoice()->showerScale();
+  }
+
+  throw Exception()
+    << "MatchboxMEBase::showerScale() expects a MatchboxScaleChoice object.\n"
+    << "Please check your setup." << Exception::runerror;
+
+  return ZERO;
+
+}
+
 void MatchboxMEBase::setVetoScales(tSubProPtr) const {}
 
 bool MatchboxMEBase::havePDFWeight1() const {
   if ( checkedPDFs )
     return theHavePDFs.first;
   theHavePDFs.first = 
     factory()->isIncoming(mePartonData()[0]) && 
     lastXCombPtr()->partonBins().first->pdf();
   theHavePDFs.second = 
     factory()->isIncoming(mePartonData()[1]) &&
     lastXCombPtr()->partonBins().second->pdf();
   checkedPDFs = true;
   return theHavePDFs.first;
 }
 
 bool MatchboxMEBase::havePDFWeight2() const {
   if ( checkedPDFs )
     return theHavePDFs.second;
   theHavePDFs.first = 
     factory()->isIncoming(mePartonData()[0]) && 
     lastXCombPtr()->partonBins().first->pdf();
   theHavePDFs.second = 
     factory()->isIncoming(mePartonData()[1]) &&
     lastXCombPtr()->partonBins().second->pdf();
   checkedPDFs = true;
   return theHavePDFs.second;
 }
 
 void MatchboxMEBase::getPDFWeight(Energy2 factorizationScale) const {
 
   if ( !havePDFWeight1() && !havePDFWeight2() ) {
     lastMEPDFWeight(1.0);
     logPDFWeight();
     return;
   }
 
   double w = 1.;
 
   if ( havePDFWeight1() )
     w *= pdf1(factorizationScale);
 
   if ( havePDFWeight2() )
     w *= pdf2(factorizationScale);
 
   lastMEPDFWeight(w);
 
   logPDFWeight();
 
 }
 
 double MatchboxMEBase::pdf1(Energy2 fscale, double xEx, double xFactor) const {
 
   assert(lastXCombPtr()->partonBins().first->pdf());
 
   if ( xEx < 1. && lastX1()*xFactor >= xEx ) {
     return
       ( ( 1. - lastX1()*xFactor ) / ( 1. - xEx ) ) *
       lastXCombPtr()->partonBins().first->pdf()->xfx(lastParticles().first->dataPtr(),
 						     lastPartons().first->dataPtr(),
 						     fscale == ZERO ? lastScale() : fscale,
 						     xEx)/xEx;
   }
 
   return lastXCombPtr()->partonBins().first->pdf()->xfx(lastParticles().first->dataPtr(),
 							lastPartons().first->dataPtr(),
 							fscale == ZERO ? lastScale() : fscale,
 							lastX1()*xFactor)/lastX1()/xFactor;
 }
 
 double MatchboxMEBase::pdf2(Energy2 fscale, double xEx, double xFactor) const {
 
   assert(lastXCombPtr()->partonBins().second->pdf());
 
   if ( xEx < 1. && lastX2()*xFactor >= xEx ) {
     return
       ( ( 1. - lastX2()*xFactor ) / ( 1. - xEx ) ) *
       lastXCombPtr()->partonBins().second->pdf()->xfx(lastParticles().second->dataPtr(),
 						      lastPartons().second->dataPtr(),
 						      fscale == ZERO ? lastScale() : fscale,
 						      xEx)/xEx;
   }
 
   return lastXCombPtr()->partonBins().second->pdf()->xfx(lastParticles().second->dataPtr(),
 							 lastPartons().second->dataPtr(),
 							 fscale == ZERO ? lastScale() : fscale,
 							 lastX2()*xFactor)/lastX2()/xFactor;
 
 }
 
 double MatchboxMEBase::me2() const {
 
   if ( matchboxAmplitude() ) {
 
     if ( matchboxAmplitude()->treeAmplitudes() )
       matchboxAmplitude()->prepareAmplitudes(this);
 
     double res = 
       matchboxAmplitude()->me2()*
       me2Norm();
 
     return res;
 
   }
 
   throw Exception()
     << "MatchboxMEBase::me2() expects a MatchboxAmplitude object.\n"
     << "Please check your setup." << Exception::runerror;
   return 0.;
 
 }
 
 double MatchboxMEBase::largeNME2(Ptr<ColourBasis>::tptr largeNBasis) const {
 
   if ( matchboxAmplitude() ) {
 
     if ( matchboxAmplitude()->treeAmplitudes() ) {
       largeNBasis->prepare(mePartonData(),false);
       matchboxAmplitude()->prepareAmplitudes(this);
     }
 
     double res = 
       matchboxAmplitude()->largeNME2(largeNBasis)*
       me2Norm();
 
     return res;
 
   }
 
   throw Exception()
     << "MatchboxMEBase::largeNME2() expects a MatchboxAmplitude object.\n"
     << "Please check your setup." << Exception::runerror;
   return 0.;
 
 }
 
 double MatchboxMEBase::finalStateSymmetry() const {
 
   if ( symmetryFactor() > 0.0 )
     return symmetryFactor();
 
   double sFactor = 1.;
 
   map<long,int> counts;
 
   cPDVector checkData;
   copy(mePartonData().begin()+2,mePartonData().end(),back_inserter(checkData));
 
   cPDVector::iterator p = checkData.begin();
   while ( !checkData.empty() ) {
     if ( counts.find((**p).id()) != counts.end() ) {
       counts[(**p).id()] += 1;
     } else {
       counts[(**p).id()] = 1;
     }
     checkData.erase(p);
     p = checkData.begin();
     continue;
   }
 
   for ( map<long,int>::const_iterator c = counts.begin();
 	c != counts.end(); ++c ) {
     if ( c->second == 1 )
       continue;
     if ( c->second == 2 )
       sFactor /= 2.;
     else if ( c->second == 3 )
       sFactor /= 6.;
     else if ( c->second == 4 )
       sFactor /= 24.;
   }
 
   symmetryFactor(sFactor);
 
   return symmetryFactor();
 
 }
 
 double MatchboxMEBase::me2Norm(unsigned int addAlphaS) const {
 
   // assume that we always have incoming
   // spin-1/2 or massless spin-1 particles
   double fac = 1./4.;
 
   if ( hasInitialAverage() )
     fac = 1.;
 
   double couplings = 1.0;
   if ( (orderInAlphaS() > 0 || addAlphaS != 0) && !hasRunningAlphaS() ) {
     fac *= pow(lastAlphaS()/SM().alphaS(),double(orderInAlphaS()+addAlphaS));
     couplings *= pow(lastAlphaS(),double(orderInAlphaS()+addAlphaS));
   }
   if ( orderInAlphaEW() > 0 && !hasRunningAlphaEW() ) {
     fac *= pow(lastAlphaEM()/SM().alphaEMMZ(),double(orderInAlphaEW()));
     couplings *= pow(lastAlphaEM(),double(orderInAlphaEW()));
   }
   lastMECouplings(couplings);
 
   if ( !hasInitialAverage() ) {
     if ( mePartonData()[0]->iColour() == PDT::Colour3 || 
 	 mePartonData()[0]->iColour() == PDT::Colour3bar )
       fac /= SM().Nc();
     else if ( mePartonData()[0]->iColour() == PDT::Colour8 )
       fac /= (SM().Nc()*SM().Nc()-1.);
 
     if ( mePartonData()[1]->iColour() == PDT::Colour3 || 
 	 mePartonData()[1]->iColour() == PDT::Colour3bar )
       fac /= SM().Nc();
     else if ( mePartonData()[1]->iColour() == PDT::Colour8 )
       fac /= (SM().Nc()*SM().Nc()-1.);
   }
 
   return !hasFinalStateSymmetry() ? finalStateSymmetry()*fac : fac;
 
 }
 
 CrossSection MatchboxMEBase::dSigHatDR() const {
 
   getPDFWeight();
 
   if ( !lastXCombPtr()->willPassCuts() ) {
     lastMECrossSection(ZERO);
     return lastMECrossSection();
   }
 
   double xme2 = me2();
   
   if (factory()->verboseDia()){
     double diagweightsum = 0.0;
     for ( vector<Ptr<DiagramBase>::ptr>::const_iterator d = diagrams().begin();
         d != diagrams().end(); ++d ) {
         diagweightsum += phasespace()->diagramWeight(dynamic_cast<const Tree2toNDiagram&>(**d));
     }
     double piWeight = pow(2.*Constants::pi,(int)(3*(meMomenta().size()-2)-4));
     double units = pow(lastSHat() / GeV2, mePartonData().size() - 4.);
     bookMEoverDiaWeight(log(xme2/(diagweightsum*piWeight*units)));//
   }
   
   if ( xme2 == 0. && !oneLoopNoBorn() ) {
     lastMECrossSection(ZERO);
     return lastMECrossSection();
   }
 
   double vme2 = 0.;
   if ( oneLoop() && !oneLoopNoLoops() )
     vme2 = oneLoopInterference();
 
   CrossSection res = ZERO;
 
   if ( !oneLoopNoBorn() )
     res += 
       (sqr(hbarc)/(2.*lastSHat())) *
       jacobian()* lastMEPDFWeight() * xme2;
 
   if ( oneLoop() && !oneLoopNoLoops() )
     res += 
       (sqr(hbarc)/(2.*lastSHat())) *
       jacobian()* lastMEPDFWeight() * vme2;
 
   if ( !onlyOneLoop() ) {
     for ( vector<Ptr<MatchboxInsertionOperator>::ptr>::const_iterator v =
 	    virtuals().begin(); v != virtuals().end(); ++v ) {
       (**v).setXComb(lastXCombPtr());
       res += (**v).dSigHatDR();
     }
     if ( checkPoles() && oneLoop() )
       logPoles();
   }
 
   double weight = 0.0;
   bool applied = false;
   for ( vector<Ptr<MatchboxReweightBase>::ptr>::const_iterator rw =
 	  theReweights.begin(); rw != theReweights.end(); ++rw ) {
     (**rw).setXComb(lastXCombPtr());
     if ( !(**rw).apply() )
       continue;
     weight += (**rw).evaluate();
     applied = true;
   }
   if ( applied )
     res *= weight;
   lastMECrossSection(res);
 
   return lastMECrossSection();
 
 }
 
 double MatchboxMEBase::oneLoopInterference() const {
 
   if ( matchboxAmplitude() ) {
 
     if ( matchboxAmplitude()->oneLoopAmplitudes() )
       matchboxAmplitude()->prepareOneLoopAmplitudes(this);
 
     double res = 
       matchboxAmplitude()->oneLoopInterference()*
       me2Norm(1);
 
     return res;
 
   }
 
   throw Exception()
     << "MatchboxMEBase::oneLoopInterference() expects a MatchboxAmplitude object.\n"
     << "Please check your setup." << Exception::runerror;
   return 0.;
 
 }
 
 MatchboxMEBase::AccuracyHistogram::AccuracyHistogram(double low,
 						     double up,
 						     unsigned int nbins) 
   : lower(low), upper(up), 
     sameSign(0), oppositeSign(0), nans(0),
     overflow(0), underflow(0) {
 
   double step = (up-low)/nbins;
 
   for ( unsigned int k = 1; k <= nbins; ++k )
     bins[lower + k*step] = 0.0;
 
 }
 
 void MatchboxMEBase::AccuracyHistogram::book(double a, double b) {
   if ( isnan(a) || isnan(b) ||
        isinf(a) || isinf(b) ) {
     ++nans;
     return;
   }
   if ( a*b >= 0. )
     ++sameSign;
   if ( a*b < 0. )
     ++oppositeSign;
   double r = 1.;
   if ( abs(a) != 0.0 )
     r = abs(1.-abs(b/a));
   else if ( abs(b) != 0.0 )
     r = abs(b);
   if ( log10(r) < lower || r == 0.0 ) {
     ++underflow;
     return;
   }
   if ( log10(r) > upper ) {
     ++overflow;
     return;
   }
   map<double,double>::iterator bin =
     bins.upper_bound(log10(r));
   if ( bin == bins.end() )
     return;
   bin->second += 1.;
 }
 
 void MatchboxMEBase::AccuracyHistogram::dump(const std::string& folder, const std::string& prefix,
 					     const cPDVector& proc) const {
   ostringstream fname("");
   for ( cPDVector::const_iterator p = proc.begin();
 	p != proc.end(); ++p )
     fname << (**p).PDGName();
   ofstream out((folder+"/"+prefix+fname.str()+".dat").c_str());
   out << "# same sign : " << sameSign << " opposite sign : "
       << oppositeSign << " nans : " << nans 
       << " overflow : " << overflow
       << " underflow : " << underflow << "\n";
   for ( map<double,double>::const_iterator b = bins.begin();
 	b != bins.end(); ++b ) {
     map<double,double>::const_iterator bp = b; --bp;
     if ( b->second != 0. ) {
       if ( b != bins.begin() )
 	out << bp->first;
       else
 	out << lower;
       out << " " << b->first
 	  << " " << b->second
 	  << "\n" << flush;
     }
   }
   ofstream gpout((folder+"/"+prefix+fname.str()+".gp").c_str());
   gpout << "set terminal png\n"
       << "set xlabel 'accuracy of pole cancellation [decimal places]'\n"
       << "set ylabel 'counts\n"
       << "set xrange [-20:0]\n"
       << "set output '" << prefix << fname.str() << ".png'\n"
       << "plot '" << prefix << fname.str() << ".dat' using (0.5*($1+$2)):3 with linespoints pt 7 ps 1 not";
 }
 
 void MatchboxMEBase::AccuracyHistogram::persistentOutput(PersistentOStream& os) const {
   os << lower << upper << bins
      << sameSign << oppositeSign << nans
      << overflow << underflow;
 }
 
 void MatchboxMEBase::AccuracyHistogram::persistentInput(PersistentIStream& is) {
   is >> lower >> upper >> bins
      >> sameSign >> oppositeSign >> nans
      >> overflow >> underflow;
 }
 
 void MatchboxMEBase::logPoles() const {
   double res2me = oneLoopDoublePole();
   double res1me = oneLoopSinglePole();
   double res2i = 0.;
   double res1i = 0.;
   for ( vector<Ptr<MatchboxInsertionOperator>::ptr>::const_iterator v =
 	  virtuals().begin(); v != virtuals().end(); ++v ) {
     res2i += (**v).oneLoopDoublePole();
     res1i += (**v).oneLoopSinglePole();
   }
   if (res2me != 0.0 || res2i != 0.0) epsilonSquarePoleHistograms[mePartonData()].book(res2me,res2i);
   if (res1me != 0.0 || res1i != 0.0) epsilonPoleHistograms[mePartonData()].book(res1me,res1i);
 }
 
 bool MatchboxMEBase::haveOneLoop() const {
   if ( matchboxAmplitude() )
     return matchboxAmplitude()->haveOneLoop();
   return false;
 }
 
 bool MatchboxMEBase::onlyOneLoop() const {
   if ( matchboxAmplitude() )
     return matchboxAmplitude()->onlyOneLoop();
   return false;
 }
 
 bool MatchboxMEBase::isDRbar() const {
   if ( matchboxAmplitude() )
     return matchboxAmplitude()->isDRbar();
   return false;
 }
 
 bool MatchboxMEBase::isDR() const {
   if ( matchboxAmplitude() )
     return matchboxAmplitude()->isDR();
   return false;
 }
 
 bool MatchboxMEBase::isCS() const {
   if ( matchboxAmplitude() )
     return matchboxAmplitude()->isCS();
   return false;
 }
 
 bool MatchboxMEBase::isBDK() const {
   if ( matchboxAmplitude() )
     return matchboxAmplitude()->isBDK();
   return false;
 }
 
 bool MatchboxMEBase::isExpanded() const {
   if ( matchboxAmplitude() )
     return matchboxAmplitude()->isExpanded();
   return false;
 }
 
 Energy2 MatchboxMEBase::mu2() const {
   if ( matchboxAmplitude() )
     return matchboxAmplitude()->mu2();
   return 0*GeV2;
 }
 
 double MatchboxMEBase::oneLoopDoublePole() const {
 
   if ( matchboxAmplitude() ) {
 
     return
       matchboxAmplitude()->oneLoopDoublePole()*
       me2Norm(1);
 
   }
 
   return 0.;
 
 }
 
 double MatchboxMEBase::oneLoopSinglePole() const {
 
   if ( matchboxAmplitude() ) {
 
     return 
       matchboxAmplitude()->oneLoopSinglePole()*
       me2Norm(1);
 
   }
 
   return 0.;
 
 }
 
 vector<Ptr<SubtractionDipole>::ptr> 
 MatchboxMEBase::getDipoles(const vector<Ptr<SubtractionDipole>::ptr>& dipoles,
 			   const vector<Ptr<MatchboxMEBase>::ptr>& borns) const {
 
   vector<Ptr<SubtractionDipole>::ptr> res;
 
   // keep track of the dipoles we already did set up
   set<pair<pair<pair<int,int>,int>,pair<Ptr<MatchboxMEBase>::tptr,Ptr<SubtractionDipole>::tptr> > > done;
 
   cPDVector rep = diagrams().front()->partons();
   int nreal = rep.size();
 
   // now loop over configs
   for ( int emitter = 0; emitter < nreal; ++emitter ) {
 
     list<Ptr<SubtractionDipole>::ptr> matchDipoles;
     for ( vector<Ptr<SubtractionDipole>::ptr>::const_iterator d =
 	    dipoles.begin(); d != dipoles.end(); ++d ) {
       if ( !(**d).canHandleEmitter(rep,emitter) )
 	continue;
       matchDipoles.push_back(*d);
     }
     if ( matchDipoles.empty() )
       continue;
 
     for ( int emission = 2; emission < nreal; ++emission ) {
       if ( emission == emitter )
 	continue;
 
       list<Ptr<SubtractionDipole>::ptr> matchDipoles2;
       for ( list<Ptr<SubtractionDipole>::ptr>::const_iterator d =
 	      matchDipoles.begin(); d != matchDipoles.end(); ++d ) {
 	if ( !(**d).canHandleSplitting(rep,emitter,emission) )
 	  continue;
 	matchDipoles2.push_back(*d);
       }
       if ( matchDipoles2.empty() )
 	continue;
 
       map<Ptr<DiagramBase>::ptr,SubtractionDipole::MergeInfo> mergeInfo;
 
       for ( DiagramVector::const_iterator d = diagrams().begin(); d != diagrams().end(); ++d ) {
 
 	Ptr<Tree2toNDiagram>::ptr check =
 	  new_ptr(Tree2toNDiagram(*dynamic_ptr_cast<Ptr<Tree2toNDiagram>::ptr>(*d)));
 
 	map<int,int> theMergeLegs;
 
 	for ( unsigned int i = 0; i < check->external().size(); ++i )
 	  theMergeLegs[i] = -1;
 	int theEmitter = check->mergeEmission(emitter,emission,theMergeLegs);
 
 	// no underlying Born
 	if ( theEmitter == -1 )
 	  continue;
 
 	SubtractionDipole::MergeInfo info;
 	info.diagram = check;
 	info.emitter = theEmitter;
 	info.mergeLegs = theMergeLegs;
 	mergeInfo[*d] = info;
 
       }
 
       if ( mergeInfo.empty() )
 	continue;
 
       for ( int spectator = 0; spectator < nreal; ++spectator ) {
 	if ( spectator == emitter || spectator == emission )
 	  continue;
 
 	list<Ptr<SubtractionDipole>::ptr> matchDipoles3;
 	for ( list<Ptr<SubtractionDipole>::ptr>::const_iterator d =
 		matchDipoles2.begin(); d != matchDipoles2.end(); ++d ) {
 	  if ( !(**d).canHandleSpectator(rep,spectator) )
 	    continue;
 	  matchDipoles3.push_back(*d);
 	}
 	if ( matchDipoles3.empty() )
 	  continue;
 
 	if ( noDipole(emitter,emission,spectator) )
 	  continue;
 
 	for ( list<Ptr<SubtractionDipole>::ptr>::const_iterator d =
 		matchDipoles3.begin(); d != matchDipoles3.end(); ++d ) {
 
 	  if ( !(**d).canHandle(rep,emitter,emission,spectator) )
 	    continue;
 
 	  for ( vector<Ptr<MatchboxMEBase>::ptr>::const_iterator b =
 		  borns.begin(); b != borns.end(); ++b ) {
 	    if ( (**b).onlyOneLoop() )
 	      continue;
 	    if ( done.find(make_pair(make_pair(make_pair(emitter,emission),spectator),make_pair(*b,*d))) 
 		 != done.end() )
 	      continue;
 	    // now get to work
 	    (**d).clearBookkeeping();
 	    (**d).factory(factory());
 	    (**d).realEmitter(emitter);
 	    (**d).realEmission(emission);
 	    (**d).realSpectator(spectator);
 	    (**d).realEmissionME(const_cast<MatchboxMEBase*>(this));
 	    (**d).underlyingBornME(*b);
 	    (**d).setupBookkeeping(mergeInfo);
 	    if ( !((**d).empty()) ) {
 	      res.push_back((**d).cloneMe());
 	      Ptr<SubtractionDipole>::tptr nDipole = res.back();
 	      done.insert(make_pair(make_pair(make_pair(emitter,emission),spectator),make_pair(*b,*d)));
 	      if ( nDipole->isSymmetric() )
 		done.insert(make_pair(make_pair(make_pair(emission,emitter),spectator),make_pair(*b,*d)));
 	      ostringstream dname;
 	      dname << fullName() << "." << (**b).name() << "."
 		    << (**d).name() << ".[(" 
 		    << emitter << "," << emission << ")," << spectator << "]";
 	      if ( ! (generator()->preinitRegister(nDipole,dname.str()) ) )
 		throw Exception() << "MatchboxMEBase::getDipoles(): Dipole " << dname.str() << " already existing." << Exception::runerror;
 	      if ( !factory()->reweighters().empty() ) {
 		for ( vector<ReweightPtr>::const_iterator rw = factory()->reweighters().begin();
 		      rw != factory()->reweighters().end(); ++rw )
 		  nDipole->addReweighter(*rw);
 	      }
 	      if ( !factory()->preweighters().empty() ) {
 		for ( vector<ReweightPtr>::const_iterator rw = factory()->preweighters().begin();
 		      rw != factory()->preweighters().end(); ++rw )
 		  nDipole->addPreweighter(*rw);
 	      }
 	      nDipole->cloneDependencies(dname.str());
 	    }
 	  }
 	}
       }
     }
   }
 
   vector<Ptr<SubtractionDipole>::tptr> partners;
   copy(res.begin(),res.end(),back_inserter(partners));
   for ( vector<Ptr<SubtractionDipole>::ptr>::iterator d = res.begin();
 	d != res.end(); ++d )
     (**d).partnerDipoles(partners);
 
   return res;
 
 }
 
 double MatchboxMEBase::colourCorrelatedME2(pair<int,int> ij) const {
 
   if ( matchboxAmplitude() ) {
 
     if ( matchboxAmplitude()->treeAmplitudes() )
       matchboxAmplitude()->prepareAmplitudes(this);
 
     double res = 
       matchboxAmplitude()->colourCorrelatedME2(ij)*
       me2Norm();
 
     return res;
 
   }
 
   throw Exception()
     << "MatchboxMEBase::colourCorrelatedME2() expects a MatchboxAmplitude object.\n"
     << "Please check your setup." << Exception::runerror;
   return 0.;
 
 }
 
 double MatchboxMEBase::largeNColourCorrelatedME2(pair<int,int> ij,
 						 Ptr<ColourBasis>::tptr largeNBasis) const {
 
   if ( matchboxAmplitude() ) {
 
     if ( matchboxAmplitude()->treeAmplitudes() ) {
       largeNBasis->prepare(mePartonData(),false);
       matchboxAmplitude()->prepareAmplitudes(this);
     }
 
     double res = 
       matchboxAmplitude()->largeNColourCorrelatedME2(ij,largeNBasis)*
       me2Norm();
 
     return res;
 
   }
 
   throw Exception()
     << "MatchboxMEBase::largeNColourCorrelatedME2() expects a MatchboxAmplitude object.\n"
     << "Please check your setup." << Exception::runerror;
   return 0.;
 
 }
 
 double MatchboxMEBase::spinColourCorrelatedME2(pair<int,int> ij,
 					       const SpinCorrelationTensor& c) const {
 
   if ( matchboxAmplitude() ) {
 
     if ( matchboxAmplitude()->treeAmplitudes() )
       matchboxAmplitude()->prepareAmplitudes(this);
 
     double res = 
       matchboxAmplitude()->spinColourCorrelatedME2(ij,c)*
       me2Norm();
 
     return res;
 
   }
 
   throw Exception()
     << "MatchboxMEBase::spinColourCorrelatedME2() expects a MatchboxAmplitude object.\n"
     << "Please check your setup." << Exception::runerror;
   return 0.;
 
 }
 
 double MatchboxMEBase::spinCorrelatedME2(pair<int,int> ij,
 					 const SpinCorrelationTensor& c) const {
 
   if ( matchboxAmplitude() ) {
 
     if ( matchboxAmplitude()->treeAmplitudes() )
       matchboxAmplitude()->prepareAmplitudes(this);
 
     double res = 
       matchboxAmplitude()->spinCorrelatedME2(ij,c)*
       me2Norm();
 
     return res;
 
   }
 
   throw Exception()
     << "MatchboxMEBase::spinCorrelatedME2() expects a MatchboxAmplitude object.\n"
     << "Please check your setup." << Exception::runerror;
   return 0.;
 
 }
 
 
 void MatchboxMEBase::flushCaches() { 
   MEBase::flushCaches();
   if ( matchboxAmplitude() )
     matchboxAmplitude()->flushCaches();
   for ( vector<Ptr<MatchboxReweightBase>::ptr>::iterator r =
 	  reweights().begin(); r != reweights().end(); ++r ) {
     (**r).flushCaches();
   }
   for ( vector<Ptr<MatchboxInsertionOperator>::ptr>::const_iterator v =
 	  virtuals().begin(); v != virtuals().end(); ++v ) {
     (**v).flushCaches();
   }
 }
 
 void MatchboxMEBase::print(ostream& os) const {
 
   os << "--- MatchboxMEBase setup -------------------------------------------------------\n";
 
   os << " '" << name() << "' for subprocess:\n";
 
   os << "  ";
   for ( PDVector::const_iterator pp = subProcess().legs.begin();
 	pp != subProcess().legs.end(); ++pp ) {
     os << (**pp).PDGName() << " ";
     if ( pp == subProcess().legs.begin() + 1 )
       os << "-> ";
   }
   os << "\n";
 
   os << " including " << (oneLoop() ? "" : "no ") << "virtual corrections";
   if ( oneLoopNoBorn() )
     os << " without Born contributions";
   if ( oneLoopNoLoops() )
     os << " without loop contributions";
   os << "\n";
 
   if ( oneLoop() && !onlyOneLoop() ) {
     os << " using insertion operators\n";
     for ( vector<Ptr<MatchboxInsertionOperator>::ptr>::const_iterator v =
 	    virtuals().begin(); v != virtuals().end(); ++v ) {
       os << " '" << (**v).name() << "' with " 
 	 << ((**v).isDR() ? "" : "C") << "DR/";
       if ( (**v).isCS() )
 	os << "CS";
       if ( (**v).isBDK() )
 	os << "BDK";
       if ( (**v).isExpanded() )
 	os << "expanded";
       os << " conventions\n";
     }
   }
 
   os << "--------------------------------------------------------------------------------\n";
 
   os << flush;
 
 }
 
 void MatchboxMEBase::printLastEvent(ostream& os) const {
 
   os << "--- MatchboxMEBase last event information --------------------------------------\n";
 
   os << " for matrix element '" << name() << "'\n";
 
   os << " process considered:\n ";
 
   int in = 0;
   for ( cPDVector::const_iterator p = mePartonData().begin();
 	p != mePartonData().end(); ++p ) {
     os << (**p).PDGName() << " ";
     if ( ++in == 2 )
       os << " -> ";
   }
 
   os << " kinematic environment as set by the XComb " << lastXCombPtr() << ":\n"
      << " sqrt(shat)/GeV = " << sqrt(lastSHat()/GeV2)
      << " x1 = " << lastX1() << " x2 = " << lastX2() 
      << " alphaS = " << lastAlphaS() << "\n";
 
   os << " momenta/GeV generated from random numbers\n ";
   copy(lastXComb().lastRandomNumbers().begin(),
        lastXComb().lastRandomNumbers().end(),ostream_iterator<double>(os," "));
   os << ":\n ";
 
   for ( vector<Lorentz5Momentum>::const_iterator p = meMomenta().begin();
 	p != meMomenta().end(); ++p ) {
     os << (*p/GeV) << "\n ";
   }
 
   os << "last cross section/nb calculated was:\n "
      << (lastMECrossSection()/nanobarn) << " (pdf weight " << lastMEPDFWeight() << ")\n";
 
   os << "--------------------------------------------------------------------------------\n";
 
   os << flush;
 
 }
 
 void MatchboxMEBase::logGenerateKinematics(const double * r) const {
 
   if ( !verbose() )
     return;
 
   generator()->log() << "'" << name() << "' generated kinematics\nfrom "
 		     << nDim() << " random numbers:\n";
   copy(r,r+nDim(),ostream_iterator<double>(generator()->log()," "));
   generator()->log() << "\n";
 
   generator()->log() << "storing phase space information in XComb "
 		     << lastXCombPtr() << "\n";
 
   generator()->log() << "generated phase space point (in GeV):\n";
 
   vector<Lorentz5Momentum>::const_iterator pit = meMomenta().begin();
   cPDVector::const_iterator dit = mePartonData().begin();
 
   for ( ; pit != meMomenta().end() ; ++pit, ++dit )
     generator()->log() << (**dit).PDGName() << " : "
 		       << (*pit/GeV) << "\n";
 
   generator()->log() << "with x1 = " << lastX1() << " x2 = " << lastX2() << "\n"
 		     << "and Jacobian = " << jacobian() << " sHat/GeV2 = "
 		     << (lastSHat()/GeV2) << "\n" << flush;
 
 }
 
 void MatchboxMEBase::logSetScale() const {
 
   if ( !verbose() )
     return;
 
   generator()->log() << "'" << name() << "' set scales using XComb " << lastXCombPtr() << ":\n"
 		     << "scale/GeV2 = " << (scale()/GeV2) << " xi_R = "
 		     << renormalizationScaleFactor() << " xi_F = "
 		     << factorizationScaleFactor() << "\n"
 		     << "alpha_s = " << lastAlphaS() << "\n" << flush;
 
 }
 
 void MatchboxMEBase::logPDFWeight() const {
 
   if ( !verbose() )
     return;
 
   generator()->log() << "'" << name() << "' calculated pdf weight = "
 		     << lastMEPDFWeight() << " from XComb "
 		     << lastXCombPtr() << "\n"
 		     << "x1 = " << lastX1() << " (" << (mePartonData()[0]->coloured() ? "" : "not ") << "used) "
 		     << "x2 = " << lastX2() << " (" << (mePartonData()[1]->coloured() ? "" : "not ") << "used)\n"
 		     << flush;
 
 }
 
 void MatchboxMEBase::logME2() const {
 
   if ( !verbose() )
     return;
 
   generator()->log() << "'" << name() << "' evaluated me2 using XComb "
 		     << lastXCombPtr() << "\n"
 		     << "and phase space point (in GeV):\n";
 
   vector<Lorentz5Momentum>::const_iterator pit = meMomenta().begin();
   cPDVector::const_iterator dit = mePartonData().begin();
 
   for ( ; pit != meMomenta().end() ; ++pit, ++dit )
     generator()->log() << (**dit).PDGName() << " : "
 		       << (*pit/GeV) << "\n";
 
   generator()->log() << "with x1 = " << lastX1() << " x2 = " << lastX2() << "\n"
 		     << "sHat/GeV2 = " << (lastSHat()/GeV2) << "\n" << flush;
 
 }
 
 void MatchboxMEBase::logDSigHatDR() const {
 
   if ( !verbose() )
     return;
 
   generator()->log() << "'" << name() << "' evaluated cross section using XComb "
 		     << lastXCombPtr() << "\n"
 		     << "Jacobian = " << jacobian() << " sHat/GeV2 = "
 		     << (lastSHat()/GeV2) << " dsig/nb = "
 		     << (lastMECrossSection()/nanobarn) << "\n" << flush;
 
 }
 
 void MatchboxMEBase::cloneDependencies(const std::string& prefix) {
 
   if ( phasespace() ) {
     Ptr<MatchboxPhasespace>::ptr myPhasespace = phasespace()->cloneMe();
     ostringstream pname;
     pname << (prefix == "" ? fullName() : prefix) << "/" << myPhasespace->name();
     if ( ! (generator()->preinitRegister(myPhasespace,pname.str()) ) )
       throw Exception() << "MatchboxMEBase::cloneDependencies(): Phasespace generator " << pname.str() << " already existing." << Exception::runerror;
     myPhasespace->cloneDependencies(pname.str());
     phasespace(myPhasespace);
   }
 
   theAmplitude = dynamic_ptr_cast<Ptr<MatchboxAmplitude>::ptr>(amplitude());
 
   if ( matchboxAmplitude() ) {
     Ptr<MatchboxAmplitude>::ptr myAmplitude = matchboxAmplitude()->cloneMe();
     ostringstream pname;
     pname << (prefix == "" ? fullName() : prefix) << "/" << myAmplitude->name();
     if ( ! (generator()->preinitRegister(myAmplitude,pname.str()) ) )
       throw Exception() << "MatchboxMEBase::cloneDependencies(): Amplitude " << pname.str() << " already existing." << Exception::runerror;
     myAmplitude->cloneDependencies(pname.str());
     matchboxAmplitude(myAmplitude);
     amplitude(myAmplitude);
     matchboxAmplitude()->orderInGs(orderInAlphaS());
     matchboxAmplitude()->orderInGem(orderInAlphaEW());
   }
 
   if ( scaleChoice() ) {
     Ptr<MatchboxScaleChoice>::ptr myScaleChoice = scaleChoice()->cloneMe();
     ostringstream pname;
     pname << (prefix == "" ? fullName() : prefix) << "/" << myScaleChoice->name();
     if ( ! (generator()->preinitRegister(myScaleChoice,pname.str()) ) )
       throw Exception() << "MatchboxMEBase::cloneDependencies(): Scale choice " << pname.str() << " already existing." << Exception::runerror;
     scaleChoice(myScaleChoice);
   }
 
   for ( vector<Ptr<MatchboxReweightBase>::ptr>::iterator rw =
 	  theReweights.begin(); rw != theReweights.end(); ++rw ) {
     Ptr<MatchboxReweightBase>::ptr myReweight = (**rw).cloneMe();
     ostringstream pname;
     pname << (prefix == "" ? fullName() : prefix) << "/" << (**rw).name();
     if ( ! (generator()->preinitRegister(myReweight,pname.str()) ) )
       throw Exception() << "MatchboxMEBase::cloneDependencies(): Reweight " << pname.str() << " already existing." << Exception::runerror;
     myReweight->cloneDependencies(pname.str());
     *rw = myReweight;
   }
 
   for ( vector<Ptr<MatchboxInsertionOperator>::ptr>::iterator v =
 	  virtuals().begin(); v != virtuals().end(); ++v ) {
     Ptr<MatchboxInsertionOperator>::ptr myIOP = (**v).cloneMe();
     ostringstream pname;
     pname << (prefix == "" ? fullName() : prefix) << "/" << (**v).name();
     if ( ! (generator()->preinitRegister(myIOP,pname.str()) ) )
       throw Exception() << "MatchboxMEBase::cloneDependencies(): Insertion operator " << pname.str() << " already existing." << Exception::runerror;
     *v = myIOP;
   }
 
 }
 
 void MatchboxMEBase::prepareXComb(MatchboxXCombData& xc) const {
 
   // fixme We need to pass on the partons from the xcmob here, not
   // assuming one subprocess per matrix element
 
   if ( phasespace() )
     xc.nDimPhasespace(phasespace()->nDim(diagrams().front()->partons()));
 
   if ( matchboxAmplitude() ) {
     xc.nDimAmplitude(matchboxAmplitude()->nDimAdditional());
     if ( matchboxAmplitude()->colourBasis() ) {
       size_t cdim = 
  	matchboxAmplitude()->colourBasis()->prepare(diagrams(),noCorrelations());
       xc.colourBasisDim(cdim);
     }
     if ( matchboxAmplitude()->isExternal() ) {
       xc.externalId(matchboxAmplitude()->externalId(diagrams().front()->partons()));
     }
   }
 
   int insertionAdd = 0;
   for ( vector<Ptr<MatchboxInsertionOperator>::ptr>::const_iterator v =
 	  virtuals().begin(); v != virtuals().end(); ++v ) {
     insertionAdd = max(insertionAdd,(**v).nDimAdditional());
   }
   xc.nDimInsertions(insertionAdd);
 
   xc.nLight(getNLight());
 
   for (size_t inlv=0; inlv<getNLightJetVec().size(); ++inlv)
     xc.nLightJetVec(getNLightJetVec()[inlv]);
 
   for (size_t inhv=0; inhv<getNHeavyJetVec().size(); ++inhv)
     xc.nHeavyJetVec(getNHeavyJetVec()[inhv]);
 
   for (size_t inlpv=0; inlpv<getNLightProtonVec().size(); ++inlpv)
     xc.nLightProtonVec(getNLightProtonVec()[inlpv]);
 
   xc.olpId(olpProcess());
 
   if ( initVerbose() ) {
     ostringstream fname_strm;
     // only allow alphanumeric, / and _ in filename
     BOOST_FOREACH (const char c, name()) {
         switch (c) {
           case '+' : fname_strm << "+"; break;
           case '-' : fname_strm << "-"; break;
           case '~' : fname_strm << "_tilde"; break;
           case ']' : break;
           case ',' : fname_strm << "__"; break;
           default  : fname_strm << (isalnum(c) ? c : '_'); break;
         }
     }
     fname_strm << ".diagrams";
     const string fname = fname_strm.str();
     ifstream test(fname.c_str());
     if ( !test ) {
       test.close();
       ofstream out(fname.c_str());
       for ( vector<Ptr<DiagramBase>::ptr>::const_iterator d = diagrams().begin();
 	    d != diagrams().end(); ++d ) {
 	DiagramDrawer::drawDiag(out,dynamic_cast<const Tree2toNDiagram&>(**d));
 	out << "\n";
       }
     }
   }
 
 }
 
 StdXCombPtr MatchboxMEBase::makeXComb(Energy newMaxEnergy, const cPDPair & inc,
 				      tEHPtr newEventHandler,tSubHdlPtr newSubProcessHandler,
 				      tPExtrPtr newExtractor,	tCascHdlPtr newCKKW,
 				      const PBPair & newPartonBins, tCutsPtr newCuts,
 				      const DiagramVector & newDiagrams, bool mir,
 				      const PartonPairVec&,
 				      tStdXCombPtr newHead,
 				      tMEPtr newME) {
 
   if ( !newME )
     newME = this;
 
   Ptr<MatchboxXComb>::ptr xc =
     new_ptr(MatchboxXComb(newMaxEnergy, inc,
 			  newEventHandler, newSubProcessHandler,
 			  newExtractor, newCKKW,
 			  newPartonBins, newCuts, newME,
 			  newDiagrams, mir,
 			  newHead));
 
   prepareXComb(*xc);
 
   return xc;
 
 }
 
 StdXCombPtr MatchboxMEBase::makeXComb(tStdXCombPtr newHead,
 				      const PBPair & newPartonBins,
 				      const DiagramVector & newDiagrams,
 				      tMEPtr newME) {
   if ( !newME )
     newME = this;
 
   Ptr<MatchboxXComb>::ptr xc = 
     new_ptr(MatchboxXComb(newHead, newPartonBins, newME, newDiagrams));
 
   prepareXComb(*xc);
 
   return xc;
 }
 
 void MatchboxMEBase::persistentOutput(PersistentOStream & os) const {
   os << theLastXComb << theFactory << thePhasespace 
      << theAmplitude << theScaleChoice << theVirtuals 
      << theReweights << theSubprocess << theOneLoop 
      << theOneLoopNoBorn << theOneLoopNoLoops
      << epsilonSquarePoleHistograms << epsilonPoleHistograms
      << theOLPProcess << theNoCorrelations
      << theHavePDFs << checkedPDFs<<theDiagramWeightVerboseDown<<theDiagramWeightVerboseUp;
 }
 
 void MatchboxMEBase::persistentInput(PersistentIStream & is, int) {
   is >> theLastXComb >> theFactory >> thePhasespace 
      >> theAmplitude >> theScaleChoice >> theVirtuals 
      >> theReweights >> theSubprocess >> theOneLoop 
      >> theOneLoopNoBorn >> theOneLoopNoLoops
      >> epsilonSquarePoleHistograms >> epsilonPoleHistograms
      >> theOLPProcess >> theNoCorrelations
      >> theHavePDFs >> checkedPDFs>>theDiagramWeightVerboseDown>>theDiagramWeightVerboseUp;
   lastMatchboxXComb(theLastXComb);
 }
 
 void MatchboxMEBase::Init() {
 
   static ClassDocumentation<MatchboxMEBase> documentation
     ("MatchboxMEBase is the base class for matrix elements "
      "in the context of the matchbox NLO interface.");
 
 }
 
 IBPtr MatchboxMEBase::clone() const {
   return new_ptr(*this);
 }
 
 IBPtr MatchboxMEBase::fullclone() const {
   return new_ptr(*this);
 }
 
 void MatchboxMEBase::doinit() {
   MEBase::doinit();
   if ( !theAmplitude )
     theAmplitude = dynamic_ptr_cast<Ptr<MatchboxAmplitude>::ptr>(amplitude());
   if ( matchboxAmplitude() )
     matchboxAmplitude()->init();
   if ( phasespace() ) {
     phasespace()->init();
     matchboxAmplitude()->checkReshuffling(phasespace());
   }
   if ( scaleChoice() ) {
     scaleChoice()->init();
   }
   for ( vector<Ptr<MatchboxReweightBase>::ptr>::iterator rw =
 	  theReweights.begin(); rw != theReweights.end(); ++rw ) {
     (**rw).init();
   }
   for ( vector<Ptr<MatchboxInsertionOperator>::ptr>::iterator v =
 	  virtuals().begin(); v != virtuals().end(); ++v ) {
     (**v).init();
   }
 }
 
 
 
  void MatchboxMEBase::bookMEoverDiaWeight(double x) const {
    
       if (MEoverDiaWeight.size()==0){
 	theDiagramWeightVerboseDown=min(theDiagramWeightVerboseDown,x*0.9);
 	theDiagramWeightVerboseUp=max(theDiagramWeightVerboseUp,x*1.1);     
       }
       
       map<double,double>::iterator bx =MEoverDiaWeight.upper_bound(x);
       if ( bx == MEoverDiaWeight.end() ) {
 	return;
       }
       bx->second += 1.;
       Nevents++;
       if (int(Nevents)%1000==0){
         ofstream out((RunDirectories::runStorage()+"/"+name()+"-MeoDiaW.dat").c_str());
 	int i=0;
 	double m=0.;
         for ( map<double,double>::const_iterator bx = MEoverDiaWeight.begin();bx != MEoverDiaWeight.end(); ++bx,i++ ) {
           out << " " << bx->first<<" "<<( bx->second/double(Nevents))<<"\n ";
 	  m=max(m,bx->second/double(Nevents));
         }
         out.close();
 	  ofstream gpout((RunDirectories::runStorage()+"/"+name()+"-MeoDiaW.gp").c_str());
   gpout << "set terminal epslatex color solid\n"
         << "set output '" << name()<<"-MeoDiaW"<< "-plot.tex'\n"
         << "#set logscale x\n"
         << "set xrange [" << theDiagramWeightVerboseDown << ":" << theDiagramWeightVerboseUp << "]\n"
         << "set yrange [0.:"<<(m*0.95)<<"]\n"
         << "set xlabel '$log(ME/\\sum DiaW)$'\n"
         << "set size 0.7,0.7\n"
         << "plot 1 w lines lc rgbcolor \"#DDDDDD\" notitle, '" << name()<<"-MeoDiaW"
         << ".dat' with histeps lc rgbcolor \"#00AACC\" t '$"<<name()<<"$'";
   
   gpout.close();
 	
 
   
     }
   
 }
 
 
 void MatchboxMEBase::doinitrun() {
   MEBase::doinitrun();
   if ( matchboxAmplitude() )
     matchboxAmplitude()->initrun();
   if ( phasespace() ) {
     phasespace()->initrun();
   }
   if ( scaleChoice() ) {
     scaleChoice()->initrun();
   }
   for ( vector<Ptr<MatchboxReweightBase>::ptr>::iterator rw =
 	  theReweights.begin(); rw != theReweights.end(); ++rw ) {
     (**rw).initrun();
   }
   for ( vector<Ptr<MatchboxInsertionOperator>::ptr>::iterator v =
 	  virtuals().begin(); v != virtuals().end(); ++v ) {
     (**v).initrun();
   }
 
   if ( factory()->verboseDia() ) {
   
     for (  int k = 0; k < factory()->diagramWeightVerboseNBins() ; ++k ) {
       MEoverDiaWeight[theDiagramWeightVerboseDown+
 		      double(k)*(theDiagramWeightVerboseUp-
 				 theDiagramWeightVerboseDown)
 		      /double(factory()->diagramWeightVerboseNBins()) ] = 0.;
 	   
     }
     Nevents=0.;
 
     ofstream out("DiagramWeights.sh");
     out<<"P=$(pwd)"
        <<"\ncd "<<RunDirectories::runStorage()
        <<"\nrm -f DiagramWeights.tex"
        <<"\n echo \"\\documentclass{article}\" >> DiagramWeights.tex"
        <<"\n echo \"\\usepackage{amsmath,amsfonts,amssymb,graphicx,color}\" >> DiagramWeights.tex"
        <<"\n echo \"\\usepackage[left=2cm,right=2cm,top=2cm,bottom=2cm]{geometry}\" >> DiagramWeights.tex"
        <<"\n echo \"\\begin{document}\" >> DiagramWeights.tex"
        <<"\n echo \"\\setlength{\\parindent}{0cm}\" >> DiagramWeights.tex"
      
        <<"\n\n for i in $(ls *.gp | sed s/'\\.gp'//g) ; "
        <<"\n do"
        <<"\n     echo \"\\input{\"\"$i\"-plot\"}\" >> DiagramWeights.tex"
        <<"\n done"
        <<"\n  echo \"\\end{document}\" >> DiagramWeights.tex  "
        <<"\n  for i in *.gp ; do "
        <<"\n  gnuplot $i   "
        <<"\n   done      "
        <<"\n  pdflatex DiagramWeights.tex  \ncp DiagramWeights.pdf $P";
     out.close();
 
   }
 
 }
   
 void MatchboxMEBase::dofinish() {
   MEBase::dofinish();
   for ( map<cPDVector,AccuracyHistogram>::const_iterator
 	  b = epsilonSquarePoleHistograms.begin();
 	b != epsilonSquarePoleHistograms.end(); ++b ) {
     b->second.dump(factory()->poleData(),"epsilonSquarePoles-",b->first);
   }
   for ( map<cPDVector,AccuracyHistogram>::const_iterator
 	  b = epsilonPoleHistograms.begin();
 	b != epsilonPoleHistograms.end(); ++b ) {
     b->second.dump(factory()->poleData(),"epsilonPoles-",b->first);
   }
 }
 
 // *** 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<MatchboxMEBase,MEBase>
 describeHerwigMatchboxMEBase("Herwig::MatchboxMEBase", "Herwig.so");
 
diff --git a/MatrixElement/Matchbox/Base/MatchboxMEBase.h b/MatrixElement/Matchbox/Base/MatchboxMEBase.h
--- a/MatrixElement/Matchbox/Base/MatchboxMEBase.h
+++ b/MatrixElement/Matchbox/Base/MatchboxMEBase.h
@@ -1,1137 +1,1142 @@
 // -*- C++ -*-
 //
 // MatchboxMEBase.h is a part of Herwig - A multi-purpose Monte Carlo event generator
 // Copyright (C) 2002-2012 The Herwig Collaboration
 //
 // Herwig is licenced under version 2 of the GPL, see COPYING for details.
 // Please respect the MCnet academic guidelines, see GUIDELINES for details.
 //
 #ifndef HERWIG_MatchboxMEBase_H
 #define HERWIG_MatchboxMEBase_H
 //
 // This is the declaration of the MatchboxMEBase class.
 //
 
 #include "ThePEG/MatrixElement/MEBase.h"
 #include "Herwig/MatrixElement/Matchbox/Utility/SpinCorrelationTensor.h"
 #include "Herwig/MatrixElement/Matchbox/Utility/Tree2toNGenerator.h"
 #include "Herwig/MatrixElement/Matchbox/Utility/MatchboxScaleChoice.h"
 #include "Herwig/MatrixElement/Matchbox/Utility/ProcessData.h"
 #include "Herwig/MatrixElement/Matchbox/Base/MatchboxAmplitude.h"
 #include "Herwig/MatrixElement/Matchbox/Base/MatchboxReweightBase.h"
 #include "Herwig/MatrixElement/Matchbox/Base/MatchboxMEBase.fh"
 #include "Herwig/MatrixElement/Matchbox/Dipoles/SubtractionDipole.fh"
 #include "Herwig/MatrixElement/Matchbox/InsertionOperators/MatchboxInsertionOperator.h"
 #include "Herwig/MatrixElement/Matchbox/MatchboxFactory.fh"
 #include "Herwig/MatrixElement/Matchbox/Utility/LastMatchboxXCombInfo.h"
 #include "Herwig/MatrixElement/Matchbox/Utility/MatchboxXComb.h"
 
 namespace Herwig {
 
 using namespace ThePEG;
 
 /**
  * \ingroup Matchbox
  * \author Simon Platzer
  *
  * \brief MatchboxMEBase is the base class for matrix elements
  * in the context of the matchbox NLO interface.
  *
  * @see \ref MatchboxMEBaseInterfaces "The interfaces"
  * defined for MatchboxMEBase.
  */
 class MatchboxMEBase: 
     public MEBase, public LastMatchboxXCombInfo {
 
 public:
 
   /** @name Standard constructors and destructors. */
   //@{
   /**
    * The default constructor.
    */
   MatchboxMEBase();
 
   /**
    * The destructor.
    */
   virtual ~MatchboxMEBase();
   //@}
 
 public:
 
   /**
    * Return the factory which produced this matrix element
    */
   Ptr<MatchboxFactory>::tptr factory() const;
 
   /**
    * Set the factory which produced this matrix element
    */
   void factory(Ptr<MatchboxFactory>::tptr f);
 
   /** @name Subprocess and diagram information. */
   //@{
 
   /**
    * Return the subprocess.
    */
   const Process& subProcess() const { return theSubprocess; }
 
   /**
    * Access the subprocess.
    */
   Process& subProcess() { return theSubprocess; }
 
   /**
    * Return the diagram generator.
    */
   Ptr<Tree2toNGenerator>::tptr diagramGenerator() const;
 
   /**
    * Return the process data.
    */
   Ptr<ProcessData>::tptr processData() const;
 
   /**
    * Return true, if this matrix element does not want to
    * make use of mirroring processes; in this case all
    * possible partonic subprocesses with a fixed assignment
    * of incoming particles need to be provided through the diagrams
    * added with the add(...) method.
    */
   virtual bool noMirror () const { return true; }
 
   /**
    * Add all possible diagrams with the add() function.
    */
   virtual void getDiagrams() const;
   using MEBase::getDiagrams;
 
   /**
    * With the information previously supplied with the
    * setKinematics(...) method, a derived class may optionally
    * override this method to weight the given diagrams with their
    * (although certainly not physical) relative probabilities.
    */
   virtual Selector<DiagramIndex> diagrams(const DiagramVector &) const;
   using MEBase::diagrams;
 
   /**
    * Return a Selector with possible colour geometries for the selected
    * diagram weighted by their relative probabilities.
    */
   virtual Selector<const ColourLines *>
   colourGeometries(tcDiagPtr diag) const;
 
   /**
    * Return true, if this amplitude is capable of consistently filling
    * the rho matrices for the spin correllations
    */
   virtual bool canFillRhoMatrix() const { 
     if ( matchboxAmplitude() )
       return matchboxAmplitude()->canFillRhoMatrix();
     return false;
   }
 
   /**
    * construct the spin information for the interaction
    */
   virtual void constructVertex(tSubProPtr) {}
 
   /**
    * construct the spin information for the interaction
    */
   virtual void constructVertex(tSubProPtr sub, const ColourLines* cl);
 
   /**
    * Return the order in \f$\alpha_S\f$ in which this matrix element
    * is given.
    */
   virtual unsigned int orderInAlphaS() const;
   using MEBase::orderInAlphaS;
 
   /**
    * Return the order in \f$\alpha_{EM}\f$ in which this matrix
    * element is given. Returns 0.
    */
   virtual unsigned int orderInAlphaEW() const;
   using MEBase::orderInAlphaEW;  
 
   /**
    * Return true, if this amplitude already includes averaging over
    * incoming parton's quantum numbers.
    */
   virtual bool hasInitialAverage() const { 
     return matchboxAmplitude() ? matchboxAmplitude()->hasInitialAverage() : false;
   }
 
   /**
    * Return true, if this amplitude already includes symmetry factors
    * for identical outgoing particles.
    */
   virtual bool hasFinalStateSymmetry() const { 
     return matchboxAmplitude() ? matchboxAmplitude()->hasFinalStateSymmetry() : false; 
   }
 
 
   /**
    * Return the number of light flavours, this matrix
    * element is calculated for.
    */
   virtual unsigned int getNLight() const;
 
   /**
    * Return the vector that contains the PDG ids of 
    * the light flavours, which are contained in the
    * jet particle group.
    */
   virtual vector<int> getNLightJetVec() const;
 
   /**
    * Return the vector that contains the PDG ids of 
    * the heavy flavours, which are contained in the
    * jet particle group.
    */
   virtual vector<int> getNHeavyJetVec() const;
 
   /**
    * Return the vector that contains the PDG ids of 
    * the light flavours, which are contained in the
    * proton particle group.
    */
   virtual vector<int> getNLightProtonVec() const;
 
   /**
    * Return true, if this matrix element is handled by a BLHA one-loop provider
    */
   virtual bool isOLPTree() const { 
     return matchboxAmplitude() ? matchboxAmplitude()->isOLPTree() : false;
   }
 
   /**
    * Return true, if this matrix element is handled by a BLHA one-loop provider
    */
   virtual bool isOLPLoop() const { 
     return matchboxAmplitude() ? matchboxAmplitude()->isOLPLoop() : false;
   }
 
   /**
    * Return true, if colour and spin correlated matrix elements should
    * be ordered from the OLP
    */
   virtual bool needsOLPCorrelators() const { 
     return matchboxAmplitude() ? matchboxAmplitude()->needsOLPCorrelators() : true;
   }
 
   /**
    * Return the process index, if this is an OLP handled matrix element
    */
   const vector<int>& olpProcess() const { return theOLPProcess; }
 
   /**
    * Set the process index, if this is an OLP handled matrix element
    */
   void olpProcess(int pType, int id) { 
     if ( theOLPProcess.empty() )
       theOLPProcess.resize(5,0);
     theOLPProcess[pType] = id;
   }
 
   /**
    * Return true, if this is a real emission matrix element which does
    * not require colour correlators.
    */
   bool noCorrelations() const {
     return theNoCorrelations;
   }
 
   /**
    * Indicate that this is a real emission matrix element which does
    * not require colour correlators.
    */
   void needsNoCorrelations() {
     theNoCorrelations = true;
   }
 
   /**
    * Indicate that this is a virtual matrix element which does
    * require colour correlators.
    */
   void needsCorrelations() {
     theNoCorrelations = false;
   }
 
   //@}
 
   /** @name Phasespace generation */
   //@{
 
   /**
    * Return the phase space generator to be used.
    */
   Ptr<MatchboxPhasespace>::tptr phasespace() const { return thePhasespace; }
 
   /**
    * Set the phase space generator to be used.
    */
   void phasespace(Ptr<MatchboxPhasespace>::ptr ps) { thePhasespace = ps; }
 
   /**
    * Set the XComb object to be used in the next call to
    * generateKinematics() and dSigHatDR().
    */
   virtual void setXComb(tStdXCombPtr xc);
 
   /**
    * Return true, if the XComb steering this matrix element
    * should keep track of the random numbers used to generate
    * the last phase space point
    */
   virtual bool keepRandomNumbers() const { return true; }
 
   /**
    * Generate incoming parton momenta. This default
    * implementation performs the standard mapping
    * from x1,x2 -> tau,y making 1/tau flat; incoming
    * parton momenta are stored in meMomenta()[0,1],
    * only massless partons are supported so far;
    * return the Jacobian of the mapping
    */
   double generateIncomingPartons(const double* r1, const double* r2);
 
   /**
    * Generate internal degrees of freedom given nDim() uniform random
    * numbers in the interval ]0,1[. To help the phase space generator,
    * the 'dSigHatDR' should be a smooth function of these numbers,
    * although this is not strictly necessary. The return value should
    * be true of the generation succeeded. If so the generated momenta
    * should be stored in the meMomenta() vector. Derived classes
    * must call this method once internal degrees of freedom are setup
    * and finally return the result of this method.
    */
   virtual bool generateKinematics(const double * r);
 
   /**
    * The number of internal degreed of freedom used in the matrix
    * element.
    */
   virtual int nDim() const;
 
   /**
    * The number of internal degrees of freedom used in the matrix
    * element for generating a Born phase space point
    */
   virtual int nDimBorn() const;
 
   /**
    * Return true, if this matrix element will generate momenta for the
    * incoming partons itself.  The matrix element is required to store
    * the incoming parton momenta in meMomenta()[0,1]. No mapping in
    * tau and y is performed by the PartonExtractor object, if a
    * derived class returns true here. The phase space jacobian is to
    * include a factor 1/(x1 x2).
    */
   virtual bool haveX1X2() const { 
     return 
       (phasespace() ? phasespace()->haveX1X2() : false) ||
       diagrams().front()->partons().size() == 3;
   }
 
   /**
    * Return true, if this matrix element expects
    * the incoming partons in their center-of-mass system
    */
   virtual bool wantCMS() const { 
     return 
       (phasespace() ? phasespace()->wantCMS() : true) &&
       diagrams().front()->partons().size() != 3; }
 
   /**
    * Return the meMomenta as generated at the last
    * phase space point.
    */
   const vector<Lorentz5Momentum>& lastMEMomenta() const { return meMomenta(); }
 
   /**
    * Access the meMomenta.
    */
   vector<Lorentz5Momentum>& lastMEMomenta() { return meMomenta(); }
 
   //@}
 
   /** @name Scale choices, couplings and PDFs */
   //@{
 
   /**
    * Set the scale choice object
    */
   void scaleChoice(Ptr<MatchboxScaleChoice>::ptr sc) { theScaleChoice = sc; }
 
   /**
    * Return the scale choice object
    */
   Ptr<MatchboxScaleChoice>::tptr scaleChoice() const { return theScaleChoice; }
 
   /**
    * Set scales and alphaS
    */
   void setScale() const;
 
   /**
    * Indicate that this matrix element is running alphas by itself.
    */
   virtual bool hasRunningAlphaS() const { 
     if ( matchboxAmplitude() )
       return matchboxAmplitude()->hasRunningAlphaS();
     return false;
   }
 
   /**
    * Indicate that this matrix element  is running alphaew by itself.
    */
   virtual bool hasRunningAlphaEW() const {
     if ( matchboxAmplitude() )
       return matchboxAmplitude()->hasRunningAlphaEW();
     return false;
   }
 
   /**
    * Return the scale associated with the phase space point provided
    * by the last call to setKinematics().
    */
   virtual Energy2 scale() const { return lastScale(); }
 
   /**
    * Return the renormalization scale for the last generated phasespace point.
    */
   virtual Energy2 factorizationScale() const;
 
   /**
    * Get the factorization scale factor
    */
   virtual double factorizationScaleFactor() const;
 
   /**
    * Return the (QCD) renormalization scale for the last generated phasespace point.
    */
   virtual Energy2 renormalizationScale() const;
 
   /**
    * Get the renormalization scale factor
    */
   virtual double renormalizationScaleFactor() const;
 
   /**
    * Return the QED renormalization scale for the last generated phasespace point.
    */
   virtual Energy2 renormalizationScaleQED() const;
 
   /**
+   * Return the shower scale for the last generated phasespace point.
+   */
+  virtual Energy2 showerScale() const;
+
+  /**
    * Set veto scales on the particles at the given
    * SubProcess which has been generated using this
    * matrix element.
    */
   virtual void setVetoScales(tSubProPtr) const;
 
   /**
    * Return true, if fixed couplings are used.
    */
   bool fixedCouplings() const;
 
   /**
    * Return true, if fixed couplings are used.
    */
   bool fixedQEDCouplings() const;
 
   /**
    * Return the value of \f$\alpha_S\f$ associated with the phase
    * space point provided by the last call to setKinematics(). This
    * versions returns SM().alphaS(scale()).
    */
   virtual double alphaS() const { return lastAlphaS(); }
 
   /**
    * Return the value of \f$\alpha_EM\f$ associated with the phase
    * space point provided by the last call to setKinematics(). This
    * versions returns SM().alphaEM(scale()).
    */
   virtual double alphaEM() const { return lastAlphaEM(); }
 
   /**
    * Return true, if this matrix element provides the PDF
    * weight for the first incoming parton itself.
    */
   virtual bool havePDFWeight1() const;
 
   /**
    * Return true, if this matrix element provides the PDF
    * weight for the second incoming parton itself.
    */
   virtual bool havePDFWeight2() const;
 
   /**
    * Set the PDF weight.
    */
   void getPDFWeight(Energy2 factorizationScale = ZERO) const;
 
   /**
    * Supply the PDF weight for the first incoming parton.
    */
   double pdf1(Energy2 factorizationScale = ZERO,
 	      double xEx = 1., double xFactor = 1.) const;
 
   /**
    * Supply the PDF weight for the second incoming parton.
    */
   double pdf2(Energy2 factorizationScale = ZERO,
 	      double xEx = 1., double xFactor = 1.) const;
 
   //@}
 
   /** @name Amplitude information and matrix element evaluation */
   //@{
 
   /**
    * Return the amplitude.
    */
   Ptr<MatchboxAmplitude>::tptr matchboxAmplitude() const { return theAmplitude; }
 
   /**
    * Set the amplitude.
    */
   void matchboxAmplitude(Ptr<MatchboxAmplitude>::ptr amp) { theAmplitude = amp; }
 
   /**
    * 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 for the kinematical configuation
    * previously provided by the last call to setKinematics(), suitably
    * scaled by sHat() to give a dimension-less number.
    */
   virtual double largeNME2(Ptr<ColourBasis>::tptr largeNBasis) const;
 
   /**
    * Return the symmetry factor for identical final state particles.
    */
   virtual double finalStateSymmetry() const;
 
   /**
    * Return the normalizing factor for the matrix element averaged
    * over quantum numbers and including running couplings.
    */
   double me2Norm(unsigned int addAlphaS = 0) const;
 
   /**
    * Return the matrix element squared differential in the variables
    * given by the last call to generateKinematics().
    */
   virtual CrossSection dSigHatDR() const;
 
   //@}
 
   /** @name One-loop corrections */
   //@{
 
   /**
    * Return the one-loop/tree interference.
    */
   virtual double oneLoopInterference() const;
 
   /**
    * Return true, if this matrix element is capable of calculating
    * one-loop (QCD) corrections.
    */
   virtual bool haveOneLoop() const;
 
   /**
    * Return true, if this matrix element only provides
    * one-loop (QCD) corrections.
    */
   virtual bool onlyOneLoop() const;
 
   /**
    * Return true, if the amplitude is DRbar renormalized, otherwise
    * MSbar is assumed.
    */
   virtual bool isDRbar() const;
 
   /**
    * Return true, if one loop corrections have been calculated in
    * dimensional reduction. Otherwise conventional dimensional
    * regularization is assumed. Note that renormalization is always
    * assumed to be MSbar.
    */
   virtual bool isDR() const;
 
   /**
    * Return true, if one loop corrections are given in the conventions
    * of the integrated dipoles.
    */
   virtual bool isCS() const;
 
   /**
    * Return true, if one loop corrections are given in the conventions
    * of BDK.
    */
   virtual bool isBDK() const;
 
   /**
    * Return true, if one loop corrections are given in the conventions
    * of everything expanded.
    */
   virtual bool isExpanded() const;
 
   /**
    * Return the value of the dimensional regularization
    * parameter. Note that renormalization scale dependence is fully
    * restored in DipoleIOperator.
    */
   virtual Energy2 mu2() const;
 
   /**
    * If defined, return the coefficient of the pole in epsilon^2
    */
   virtual double oneLoopDoublePole() const;
 
   /**
    * If defined, return the coefficient of the pole in epsilon
    */
   virtual double oneLoopSinglePole() const;
 
   /**
    * Return true, if cancellationn of epsilon poles should be checked.
    */
   bool checkPoles() const;
 
   /**
    * Simple histogram for accuracy checks
    */
   struct AccuracyHistogram {
 
     /**
      * The lower bound
      */
     double lower;
 
     /**
      * The upper bound
      */
     double upper;
 
     /**
      * The bins, indexed by upper bound.
      */
     map<double,double> bins;
 
     /**
      * The number of points of same sign
      */
     unsigned long sameSign;
 
     /**
      * The number of points of opposite sign
      */
     unsigned long oppositeSign;
 
     /**
      * The number of points being nan or inf
      */
     unsigned long nans;
 
     /**
      * The overflow
      */
     unsigned long overflow;
 
     /**
      * The underflow
      */
     unsigned long underflow;
 
     /**
      * Constructor
      */
     AccuracyHistogram(double low = -40.,
 		      double up = 0.,
 		      unsigned int nbins = 80);
 
     /**
      * Book two values to be checked for numerical compatibility
      */
     void book(double a, double b);
 
     /**
      * Write to file.
      */
     void dump(const std::string& folder, const std::string& prefix,
 	      const cPDVector& proc) const;
 
     /**
      * Write to persistent ostream
      */
     void persistentOutput(PersistentOStream&) const;
 
     /**
      * Read from persistent istream
      */
     void persistentInput(PersistentIStream&);
 
   };
 
   /**
    * Perform the check of epsilon pole cancellation.
    */
   void logPoles() const;
 
   /**
    * Return the virtual corrections
    */
   const vector<Ptr<MatchboxInsertionOperator>::ptr>& virtuals() const {
     return theVirtuals;
   }
 
   /**
    * Return the virtual corrections
    */
   vector<Ptr<MatchboxInsertionOperator>::ptr>& virtuals() {
     return theVirtuals;
   }
 
   /**
    * Instruct this matrix element to include one-loop corrections
    */
   void doOneLoop() { theOneLoop = true; }
 
   /**
    * Return true, if this matrix element includes one-loop corrections
    */
   bool oneLoop() const { return theOneLoop; }
 
   /**
    * Instruct this matrix element to include one-loop corrections but
    * no Born contributions
    */
   void doOneLoopNoBorn() { theOneLoop = true; theOneLoopNoBorn = true; }
 
   /**
    * Return true, if this matrix element includes one-loop corrections
    * but no Born contributions
    */
   bool oneLoopNoBorn() const { return theOneLoopNoBorn || onlyOneLoop(); }
 
   /**
    * Instruct this matrix element to include one-loop corrections but
    * no actual loop contributions
    */
   void doOneLoopNoLoops() { theOneLoop = true; theOneLoopNoLoops = true; }
 
   /**
    * Return true, if this matrix element includes one-loop corrections
    * but no actual loop contributions
    */
   bool oneLoopNoLoops() const { return theOneLoopNoLoops; }
 
   //@}
 
   /** @name Dipole subtraction */
   //@{
 
   /**
    * If this matrix element is considered a real
    * emission matrix element, return all subtraction
    * dipoles needed given a set of subtraction terms
    * and underlying Born matrix elements to choose
    * from.
    */
   vector<Ptr<SubtractionDipole>::ptr> 
   getDipoles(const vector<Ptr<SubtractionDipole>::ptr>&,
 	     const vector<Ptr<MatchboxMEBase>::ptr>&) const;
 
   /**
    * If this matrix element is considered a real emission matrix
    * element, but actually neglecting a subclass of the contributing
    * diagrams, return true if the given emitter-emission-spectator
    * configuration should not be considered when setting up
    * subtraction dipoles.
    */
   virtual bool noDipole(int,int,int) const { return false; }
 
   /**
    * If this matrix element is considered an underlying Born matrix
    * element in the context of a subtracted real emission, but
    * actually neglecting a subclass of the contributing diagrams,
    * return true if the given emitter-spectator configuration
    * should not be considered when setting up subtraction dipoles.
    */
   virtual bool noDipole(int,int) const { return false; }
 
   /**
    * Return the colour correlated matrix element squared with
    * respect to the given two partons as appearing in mePartonData(),
    * suitably scaled by sHat() to give a dimension-less number.
    */
   virtual double colourCorrelatedME2(pair<int,int>) const;
 
   /**
    * Return the colour correlated matrix element squared in the
    * large-N approximation with respect to the given two partons as
    * appearing in mePartonData(), suitably scaled by sHat() to give a
    * dimension-less number.
    */
   virtual double largeNColourCorrelatedME2(pair<int,int> ij,
 					   Ptr<ColourBasis>::tptr largeNBasis) const;
 
   /**
    * Return the colour and spin correlated matrix element squared for
    * the gluon indexed by the first argument using the given
    * correlation tensor.
    */
   virtual double spinColourCorrelatedME2(pair<int,int> emitterSpectator,
 					 const SpinCorrelationTensor& c) const;
 
   /**
    * Return the spin correlated matrix element squared for
    * the vector boson indexed by the first argument using the given
    * correlation tensor.
    */
   virtual double spinCorrelatedME2(pair<int,int> emitterSpectator,
 				   const SpinCorrelationTensor& c) const;
 
   //@}
 
   /** @name Caching and diagnostic information */
   //@{
 
   /**
    * Inform this matrix element that a new phase space
    * point is about to be generated, so all caches should
    * be flushed.
    */
   virtual void flushCaches();
 
   /**
    * Return true, if verbose
    */
   bool verbose() const;
 
   /**
    * Return true, if verbose
    */
   bool initVerbose() const;
 
   /**
    * Dump the setup to an ostream
    */
   void print(ostream&) const;
 
   /**
    * Print debug information on the last event
    */
   virtual void printLastEvent(ostream&) const;
 
   /**
    * Write out diagnostic information for
    * generateKinematics
    */
   void logGenerateKinematics(const double * r) const;
 
   /**
    * Write out diagnostic information for
    * setting scales
    */
   void logSetScale() const;
 
   /**
    * Write out diagnostic information for
    * pdf evaluation
    */
   void logPDFWeight() const;
 
   /**
    * Write out diagnostic information for
    * me2 evaluation
    */
   void logME2() const;
 
   /**
    * Write out diagnostic information
    * for dsigdr evaluation
    */
   void logDSigHatDR() const;
 
   //@}
 
   /** @name Reweight objects */
   //@{
 
   /**
    * Insert a reweight object
    */
   void addReweight(Ptr<MatchboxReweightBase>::ptr rw) { theReweights.push_back(rw); }
 
   /**
    * Return the reweights
    */
   const vector<Ptr<MatchboxReweightBase>::ptr>& reweights() const { return theReweights; }
 
   /**
    * Access the reweights
    */
   vector<Ptr<MatchboxReweightBase>::ptr>& reweights() { return theReweights; }
 
   //@}
 
   /** @name Methods used to setup MatchboxMEBase objects */
   //@{
 
   /**
    * 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; }
 
   /**
    * Clone this matrix element.
    */
   Ptr<MatchboxMEBase>::ptr cloneMe() const {
     return dynamic_ptr_cast<Ptr<MatchboxMEBase>::ptr>(clone());
   }
 
   /**
    * Clone the dependencies, using a given prefix.
    */
   void cloneDependencies(const std::string& prefix = "");
 
   /**
    * Prepare an xcomb
    */
   void prepareXComb(MatchboxXCombData&) const;
 
   /**
    * For the given event generation setup return a xcomb object
    * appropriate to this matrix element.
    */
   virtual StdXCombPtr makeXComb(Energy newMaxEnergy, const cPDPair & inc,
 				tEHPtr newEventHandler,tSubHdlPtr newSubProcessHandler,
 				tPExtrPtr newExtractor,	tCascHdlPtr newCKKW,
 				const PBPair & newPartonBins, tCutsPtr newCuts,
 				const DiagramVector & newDiagrams, bool mir,
 				const PartonPairVec& allPBins,
 				tStdXCombPtr newHead = tStdXCombPtr(),
 				tMEPtr newME = tMEPtr());
 
   /**
    * For the given event generation setup return a dependent xcomb object
    * appropriate to this matrix element.
    */
   virtual StdXCombPtr makeXComb(tStdXCombPtr newHead,
 				const PBPair & newPartonBins,
 				const DiagramVector & newDiagrams,
 				tMEPtr newME = tMEPtr());
 
   //@}
 
 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();
 
   /**
    * Finalize this object. Called in the run phase just after a
    * run has ended. Used eg. to write out statistics.
    */
   virtual void dofinish();
   //@}
 
 private:
 
   /**
    * The factory which produced this matrix element
    */
   Ptr<MatchboxFactory>::tptr theFactory;
 
   /**
    * The phase space generator to be used.
    */
   Ptr<MatchboxPhasespace>::ptr thePhasespace;
 
   /**
    * The amplitude to be used
    */
   Ptr<MatchboxAmplitude>::ptr theAmplitude;
 
   /**
    * The scale choice object
    */
   Ptr<MatchboxScaleChoice>::ptr theScaleChoice;
 
   /**
    * The virtual corrections.
    */
   vector<Ptr<MatchboxInsertionOperator>::ptr> theVirtuals;
 
   /**
    * A vector of reweight objects the sum of which
    * should be applied to reweight this matrix element
    */
   vector<Ptr<MatchboxReweightBase>::ptr> theReweights;
 
 private:
 
   /**
    * The subprocess to be considered.
    */
   Process theSubprocess;
 
   /**
    * True, if this matrix element includes one-loop corrections
    */
   bool theOneLoop;
 
   /**
    * True, if this matrix element includes one-loop corrections
    * but no Born contributions
    */
   bool theOneLoopNoBorn;
 
   /**
    * True, if this matrix element includes one-loop corrections
    * but no actual loop contributions (e.g. finite collinear terms)
    */
   bool theOneLoopNoLoops;
 
   /**
    * The process index, if this is an OLP handled matrix element
    */
   vector<int> theOLPProcess;
 
   /**
    * Histograms of epsilon^2 pole cancellation
    */
   mutable map<cPDVector,AccuracyHistogram> epsilonSquarePoleHistograms;
 
   /**
    * Histograms of epsilon pole cancellation
    */
   mutable map<cPDVector,AccuracyHistogram> epsilonPoleHistograms;
 
   /**
    * True, if this is a real emission matrix element which does
    * not require colour correlators.
    */
   bool theNoCorrelations;
 
   /**
    * Flag which pdfs should be included.
    */
   mutable pair<bool,bool> theHavePDFs;
 
   /**
    * True, if already checked for which PDFs to include.
    */
   mutable bool checkedPDFs;
   
   /**
   * Diagnostic Diagram for TreePhaseSpace
   */
   
   void bookMEoverDiaWeight(double x) const;
   
   mutable map<double,double > MEoverDiaWeight;
   
   mutable int Nevents;
   
   /**
    * Range of diagram weight verbosity
    */
   mutable double theDiagramWeightVerboseDown, theDiagramWeightVerboseUp;
   
 
 private:
 
   /**
    * The assignment operator is private and must never be called.
    * In fact, it should not even be implemented.
    */
   MatchboxMEBase & operator=(const MatchboxMEBase &);
 
 };
 
 inline PersistentOStream& operator<<(PersistentOStream& os,
 				     const MatchboxMEBase::AccuracyHistogram& h) {
   h.persistentOutput(os);
   return os;
 }
 
 inline PersistentIStream& operator>>(PersistentIStream& is,
 				     MatchboxMEBase::AccuracyHistogram& h) {
   h.persistentInput(is);
   return is;
 }
 
 }
 
 #endif /* HERWIG_MatchboxMEBase_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,685 +1,685 @@
 // -*- C++ -*-
 //
 // ShowerApproximation.cc is a part of Herwig - A multi-purpose Monte Carlo event generator
 // Copyright (C) 2002-2012 The Herwig Collaboration
 //
 // Herwig is licenced under version 2 of the GPL, see COPYING for details.
 // Please respect the MCnet academic guidelines, see GUIDELINES for details.
 //
 //
 // This is the implementation of the non-inlined, non-templated member
 // functions of the ShowerApproximation class.
 //
 
 #include "ShowerApproximation.h"
 #include "ThePEG/Interface/ClassDocumentation.h"
 #include "ThePEG/Interface/Switch.h"
 #include "ThePEG/Interface/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) {}
 
 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<SubtractionDipole>::tptr dip) { 
   theDipole = dip;
   setLargeNBasis();
 }
 
 Ptr<SubtractionDipole>::tptr ShowerApproximation::dipole() const { return theDipole; }
 
 Ptr<TildeKinematics>::tptr
 ShowerApproximation::showerTildeKinematics() const {
   return Ptr<TildeKinematics>::tptr();
 }
 
 Ptr<InvertedTildeKinematics>::tptr 
 ShowerApproximation::showerInvertedTildeKinematics() const {
   return Ptr<InvertedTildeKinematics>::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<Lorentz5Momentum>::const_iterator p = 
       bornCXComb()->meMomenta().begin() + 2;
     cPDVector::const_iterator pp = 
       bornCXComb()->mePartonData().begin() + 2;
     for ( ; p != bornCXComb()->meMomenta().end(); ++p, ++pp )
       if ( (**pp).coloured() )
 	maxPt = min(maxPt,p->mt());
     if ( maxPt == generator()->maximumCMEnergy() )
       maxPt = (bornCXComb()->meMomenta()[0] + bornCXComb()->meMomenta()[1]).m();
     maxPt *= hardScaleFactor();
     return maxPt;
   } else {
-    return hardScaleFactor()*sqrt(bornCXComb()->lastCentralScale());
+    return hardScaleFactor()*sqrt(bornCXComb()->lastShowerScale());
   }
 }
 
 bool ShowerApproximation::isInShowerPhasespace() const {
 
   if ( !dipole()->isAboveCutoff() )
     return false;
   if ( !restrictPhasespace() )
     return true;
 
   InvertedTildeKinematics& kinematics =
     const_cast<InvertedTildeKinematics&>(*dipole()->invertedTildeKinematics());
   tcStdXCombPtr tmpreal = kinematics.realXComb();
   tcStdXCombPtr tmpborn = kinematics.bornXComb();
   Ptr<SubtractionDipole>::tptr tmpdip = kinematics.dipole();
 
   Energy hard = dipole()->showerHardScale();
   Energy pt = dipole()->lastPt();
   double z = dipole()->lastZ();
 
   pair<double,double> zbounds(0.,1.);
 
   kinematics.dipole(const_ptr_cast<Ptr<SubtractionDipole>::tptr>(theDipole));
   kinematics.prepare(realCXComb(),bornCXComb());
 
   if ( pt > hard ) {
     kinematics.dipole(tmpdip);
     kinematics.prepare(tmpreal,tmpborn);
     return false;
   }
 
   try {
     zbounds = kinematics.zBounds(pt,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 ( bornPDF < 1e-8 )
     bornPDF = 0.0;
 
   if ( emissionPDF < 1e-8 )
     emissionPDF = 0.0;
 
   if ( emissionPDF == 0.0 || bornPDF == 0.0 )
     return 0.0;
 
   return
     emissionAlpha * emissionPDF *
     couplingFactor / bornPDF;
     
 }
 
 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<Ptr<SubtractionDipole>::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::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;
 }
 
 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;
 }
 
 // *** Attention *** The following static variable is needed for the type
 // description system in ThePEG. Please check that the template arguments
 // are correct (the class and its base class), and that the constructor
 // arguments are correct (the class name and the name of the dynamically
 // loadable library where the class implementation can be found).
 DescribeAbstractClass<ShowerApproximation,HandlerBase>
   describeHerwigShowerApproximation("Herwig::ShowerApproximation", "Herwig.so");
 
 void ShowerApproximation::Init() {
 
   static ClassDocumentation<ShowerApproximation> documentation
     ("ShowerApproximation describes the shower emission to be used "
      "in NLO matching.");
 
   static Parameter<ShowerApproximation,Energy> interfaceFFPtCut
     ("FFPtCut",
      "Set the pt infrared cutoff",
      &ShowerApproximation::theFFPtCut, GeV, 1.0*GeV, 0.0*GeV, 0*GeV,
      false, false, Interface::lowerlim);
 
   static Parameter<ShowerApproximation,Energy> interfaceFIPtCut
     ("FIPtCut",
      "Set the pt infrared cutoff",
      &ShowerApproximation::theFIPtCut, GeV, 1.0*GeV, 0.0*GeV, 0*GeV,
      false, false, Interface::lowerlim);
 
   static Parameter<ShowerApproximation,Energy> interfaceIIPtCut
     ("IIPtCut",
      "Set the pt infrared cutoff",
      &ShowerApproximation::theIIPtCut, GeV, 1.0*GeV, 0.0*GeV, 0*GeV,
      false, false, Interface::lowerlim);
     
   static Parameter<ShowerApproximation,Energy> 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<ShowerApproximation,Energy> interfaceFFScreeningScale
     ("FFScreeningScale",
      "Set the screening scale",
      &ShowerApproximation::theFFScreeningScale, GeV, 0.0*GeV, 0.0*GeV, 0*GeV,
      false, false, Interface::lowerlim);
 
   static Parameter<ShowerApproximation,Energy> interfaceFIScreeningScale
     ("FIScreeningScale",
      "Set the screening scale",
      &ShowerApproximation::theFIScreeningScale, GeV, 0.0*GeV, 0.0*GeV, 0*GeV,
      false, false, Interface::lowerlim);
 
   static Parameter<ShowerApproximation,Energy> interfaceIIScreeningScale
     ("IIScreeningScale",
      "Set the screening scale",
      &ShowerApproximation::theIIScreeningScale, GeV, 0.0*GeV, 0.0*GeV, 0*GeV,
      false, false, Interface::lowerlim);
 
   static Switch<ShowerApproximation,bool> interfaceRestrictPhasespace
     ("RestrictPhasespace",
      "Switch on or off phasespace restrictions",
      &ShowerApproximation::theRestrictPhasespace, true, false, false);
   static SwitchOption interfaceRestrictPhasespaceOn
     (interfaceRestrictPhasespace,
      "On",
      "Perform phasespace restrictions",
      true);
   static SwitchOption interfaceRestrictPhasespaceOff
     (interfaceRestrictPhasespace,
      "Off",
      "Do not perform phasespace restrictions",
      false);
 
   static Parameter<ShowerApproximation,double> interfaceHardScaleFactor
     ("HardScaleFactor",
      "The hard scale factor.",
      &ShowerApproximation::theHardScaleFactor, 1.0, 0.0, 0,
      false, false, Interface::lowerlim);
 
   static Parameter<ShowerApproximation,double> interfaceRenormalizationScaleFactor
     ("RenormalizationScaleFactor",
      "The hard scale factor.",
      &ShowerApproximation::theRenormalizationScaleFactor, 1.0, 0.0, 0,
      false, false, Interface::lowerlim);
 
   static Parameter<ShowerApproximation,double> interfaceFactorizationScaleFactor
     ("FactorizationScaleFactor",
      "The hard scale factor.",
      &ShowerApproximation::theFactorizationScaleFactor, 1.0, 0.0, 0,
      false, false, Interface::lowerlim);
 
   static Parameter<ShowerApproximation,double> interfaceExtrapolationX
     ("ExtrapolationX",
      "The x from which on extrapolation should be performed.",
      &ShowerApproximation::theExtrapolationX, 1.0, 0.0, 1.0,
      false, false, Interface::limited);
 
   static Switch<ShowerApproximation,int> interfaceRealEmissionScaleInSubtraction
     ("RealEmissionScaleInSubtraction",
      "Set the scale choice for the real emission cross section in the matching subtraction.",
      &ShowerApproximation::theRealEmissionScaleInSubtraction, showerScale, false, false);
   static SwitchOption interfaceRealEmissionScaleInSubtractionRealScale
     (interfaceRealEmissionScaleInSubtraction,
      "RealScale",
      "Use the real emission scale.",
      realScale);
   static SwitchOption interfaceRealEmissionScaleInSubtractionBornScale
     (interfaceRealEmissionScaleInSubtraction,
      "BornScale",
      "Use the Born scale.",
      bornScale);
   static SwitchOption interfaceRealEmissionScaleInSubtractionShowerScale
     (interfaceRealEmissionScaleInSubtraction,
      "ShowerScale",
      "Use the shower scale",
      showerScale);
 
   static Switch<ShowerApproximation,int> interfaceBornScaleInSubtraction
     ("BornScaleInSubtraction",
      "Set the scale choice for the Born cross section in the matching subtraction.",
      &ShowerApproximation::theBornScaleInSubtraction, showerScale, false, false);
   static SwitchOption interfaceBornScaleInSubtractionRealScale
     (interfaceBornScaleInSubtraction,
      "RealScale",
      "Use the real emission scale.",
      realScale);
   static SwitchOption interfaceBornScaleInSubtractionBornScale
     (interfaceBornScaleInSubtraction,
      "BornScale",
      "Use the Born scale.",
      bornScale);
   static SwitchOption interfaceBornScaleInSubtractionShowerScale
     (interfaceBornScaleInSubtraction,
      "ShowerScale",
      "Use the shower scale",
      showerScale);
 
   static Switch<ShowerApproximation,int> interfaceEmissionScaleInSubtraction
     ("EmissionScaleInSubtraction",
      "Set the scale choice for the emission in the matching subtraction.",
      &ShowerApproximation::theEmissionScaleInSubtraction, showerScale, false, false);
   static SwitchOption interfaceEmissionScaleInSubtractionRealScale
     (interfaceEmissionScaleInSubtraction,
      "RealScale",
      "Use the real emission scale.",
      realScale);
   static SwitchOption interfaceEmissionScaleInSubtractionEmissionScale
     (interfaceEmissionScaleInSubtraction,
      "BornScale",
      "Use the Born scale.",
      bornScale);
   static SwitchOption interfaceEmissionScaleInSubtractionShowerScale
     (interfaceEmissionScaleInSubtraction,
      "ShowerScale",
      "Use the shower scale",
      showerScale);
 
   static Switch<ShowerApproximation,int> interfaceRealEmissionScaleInSplitting
     ("RealEmissionScaleInSplitting",
      "Set the scale choice for the real emission cross section in the splitting.",
      &ShowerApproximation::theRealEmissionScaleInSplitting, showerScale, false, false);
   static SwitchOption interfaceRealEmissionScaleInSplittingRealScale
     (interfaceRealEmissionScaleInSplitting,
      "RealScale",
      "Use the real emission scale.",
      realScale);
   static SwitchOption interfaceRealEmissionScaleInSplittingBornScale
     (interfaceRealEmissionScaleInSplitting,
      "BornScale",
      "Use the Born scale.",
      bornScale);
   static SwitchOption interfaceRealEmissionScaleInSplittingShowerScale
     (interfaceRealEmissionScaleInSplitting,
      "ShowerScale",
      "Use the shower scale",
      showerScale);
 
   static Switch<ShowerApproximation,int> interfaceBornScaleInSplitting
     ("BornScaleInSplitting",
      "Set the scale choice for the Born cross section in the splitting.",
      &ShowerApproximation::theBornScaleInSplitting, showerScale, false, false);
   static SwitchOption interfaceBornScaleInSplittingRealScale
     (interfaceBornScaleInSplitting,
      "RealScale",
      "Use the real emission scale.",
      realScale);
   static SwitchOption interfaceBornScaleInSplittingBornScale
     (interfaceBornScaleInSplitting,
      "BornScale",
      "Use the Born scale.",
      bornScale);
   static SwitchOption interfaceBornScaleInSplittingShowerScale
     (interfaceBornScaleInSplitting,
      "ShowerScale",
      "Use the shower scale",
      showerScale);
 
   static Switch<ShowerApproximation,int> interfaceEmissionScaleInSplitting
     ("EmissionScaleInSplitting",
      "Set the scale choice for the emission in the splitting.",
      &ShowerApproximation::theEmissionScaleInSplitting, showerScale, false, false);
   static SwitchOption interfaceEmissionScaleInSplittingRealScale
     (interfaceEmissionScaleInSplitting,
      "RealScale",
      "Use the real emission scale.",
      realScale);
   static SwitchOption interfaceEmissionScaleInSplittingEmissionScale
     (interfaceEmissionScaleInSplitting,
      "BornScale",
      "Use the Born scale.",
      bornScale);
   static SwitchOption interfaceEmissionScaleInSplittingShowerScale
     (interfaceEmissionScaleInSplitting,
      "ShowerScale",
      "Use the shower scale",
      showerScale);
 
   static Parameter<ShowerApproximation,Energy> interfaceRenormalizationScaleFreeze
     ("RenormalizationScaleFreeze",
      "The freezing scale for the renormalization scale.",
      &ShowerApproximation::theRenormalizationScaleFreeze, GeV, 1.0*GeV, 0.0*GeV, 0*GeV,
      false, false, Interface::lowerlim);
 
   static Parameter<ShowerApproximation,Energy> interfaceFactorizationScaleFreeze
     ("FactorizationScaleFreeze",
      "The freezing scale for the factorization scale.",
      &ShowerApproximation::theFactorizationScaleFreeze, GeV, 1.0*GeV, 0.0*GeV, 0*GeV,
      false, false, Interface::lowerlim);
 
   static Reference<ShowerApproximation,HardScaleProfile> interfaceHardScaleProfile
     ("HardScaleProfile",
      "The hard scale profile to use.",
      &ShowerApproximation::theHardScaleProfile, false, false, true, true, false);
 
   static Reference<ShowerApproximation,ColourBasis> interfaceLargeNBasis
     ("LargeNBasis",
      "Set the large-N colour basis implementation.",
      &ShowerApproximation::theLargeNBasis, false, false, true, true, false);
 
   static Switch<ShowerApproximation,bool> 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/ShowerApproximationGenerator.cc b/MatrixElement/Matchbox/Matching/ShowerApproximationGenerator.cc
--- a/MatrixElement/Matchbox/Matching/ShowerApproximationGenerator.cc
+++ b/MatrixElement/Matchbox/Matching/ShowerApproximationGenerator.cc
@@ -1,533 +1,533 @@
 // -*- C++ -*-
 //
 // ShowerApproximationGenerator.cc is a part of Herwig - A multi-purpose Monte Carlo event generator
 // Copyright (C) 2002-2012 The Herwig Collaboration
 //
 // Herwig is licenced under version 2 of the GPL, see COPYING for details.
 // Please respect the MCnet academic guidelines, see GUIDELINES for details.
 //
 //
 // This is the implementation of the non-inlined, non-templated member
 // functions of the ShowerApproximationGenerator class.
 //
 
 #include <config.h>
 #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<double>& 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 &) {
   theFactory->setHardTreeEmitter(-1);
   theFactory->setHardTreeSpectator(-1);
   theFactory->setHardTreeSubprocess(SubProPtr());
 
 
   lastIncomingXComb = dynamic_ptr_cast<tStdXCombPtr>(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<cPDVector,set<Ptr<ShowerApproximationKernel>::ptr> >::const_iterator
     kernelit = theKernelMap.find(xc.mePartonData());
 
   if ( kernelit == theKernelMap.end() ) {
     list<MatchboxFactory::SplittingChannel> channels =
       theFactory->getSplittingChannels(lastIncomingXComb);
     set<Ptr<ShowerApproximationKernel>::ptr> newKernels;
     for ( list<MatchboxFactory::SplittingChannel>::const_iterator c =
 	    channels.begin(); c != channels.end(); ++c ) {
       Ptr<ShowerApproximationKernel>::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<ShowerApproximationKernel>::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()?"true":"false")
                       << ") and shower approximation phasespace ("
                       << (thePhasespace->wantCMS()?"true":"false") << ")"
                       << Exception::abortnow;
   }
   theLastBornME->phasespace(thePhasespace);
   theLastBornXComb = (**kernels.begin()).bornXComb();
 
   if ( !prepare(didproject) )
     return;
 
   Energy winnerPt = ZERO;
   Ptr<ShowerApproximationKernel>::ptr winnerKernel;
 
   try {
     for ( set<Ptr<ShowerApproximationKernel>::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()->lastCentralScale(sqr(winnerPt));
-  winnerKernel->bornXComb()->lastCentralScale(sqr(winnerPt));
-  lastIncomingXComb->lastCentralScale(sqr(winnerPt));
+  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{
     theFactory->setHardTreeSubprocess(newSub);
     theFactory->setHardTreeEmitter(winnerKernel->dipole()->bornEmitter()); 
     theFactory->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 << theFactory 
      << 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 >> theFactory 
      >> 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<ShowerApproximationGenerator,StepHandler>
   describeHerwigShowerApproximationGenerator("Herwig::ShowerApproximationGenerator", "Herwig.so");
 
 void ShowerApproximationGenerator::Init() {
 
   static ClassDocumentation<ShowerApproximationGenerator> documentation
     ("ShowerApproximationGenerator generates emissions according to a "
      "shower approximation entering a NLO matching.");
 
 
   static Reference<ShowerApproximationGenerator,ShowerApproximation> interfaceShowerApproximation
     ("ShowerApproximation",
      "Set the shower approximation to sample.",
      &ShowerApproximationGenerator::theShowerApproximation, false, false, true, false, false);
 
 
   static Reference<ShowerApproximationGenerator,MatchboxPhasespace> interfacePhasespace
     ("Phasespace",
      "The phase space generator to use.",
      &ShowerApproximationGenerator::thePhasespace, false, false, true, false, false);
 
 
   static Reference<ShowerApproximationGenerator,MatchboxFactory> interfaceFactory
     ("Factory",
      "The factory object to use.",
      &ShowerApproximationGenerator::theFactory, false, false, true, false, false);
 
   static Parameter<ShowerApproximationGenerator,unsigned long> interfacePresamplingPoints
     ("PresamplingPoints",
      "Set the number of presampling points.",
      &ShowerApproximationGenerator::thePresamplingPoints, 2000, 1, 0,
      false, false, Interface::lowerlim);
 
   static Parameter<ShowerApproximationGenerator,unsigned long> interfaceMaxTry
     ("MaxTry",
      "Set the number of maximum attempts.",
      &ShowerApproximationGenerator::theMaxTry, 100000, 1, 0,
      false, false, Interface::lowerlim);
 
   static Parameter<ShowerApproximationGenerator,unsigned long> interfaceFreezeGrid
     ("FreezeGrid",
      "",
      &ShowerApproximationGenerator::theFreezeGrid, 500000, 1, 0,
      false, false, Interface::lowerlim);
 
   static Switch<ShowerApproximationGenerator,bool> interfaceDoCompensate
     ("DoCompensate",
      "",
      &ShowerApproximationGenerator::theDoCompensate, false, false, false);
   static SwitchOption interfaceDoCompensateYes
     (interfaceDoCompensate,
      "Yes",
      "",
      true);
   static SwitchOption interfaceDoCompensateNo
     (interfaceDoCompensate,
      "No",
      "",
      false);
 
 }
 
diff --git a/MatrixElement/Matchbox/Phasespace/InvertedTildeKinematics.cc b/MatrixElement/Matchbox/Phasespace/InvertedTildeKinematics.cc
--- a/MatrixElement/Matchbox/Phasespace/InvertedTildeKinematics.cc
+++ b/MatrixElement/Matchbox/Phasespace/InvertedTildeKinematics.cc
@@ -1,213 +1,214 @@
 // -*- C++ -*-
 //
 // InvertedTildeKinematics.cc is a part of Herwig - A multi-purpose Monte Carlo event generator
 // Copyright (C) 2002-2012 The Herwig Collaboration
 //
 // Herwig is licenced under version 2 of the GPL, see COPYING for details.
 // Please respect the MCnet academic guidelines, see GUIDELINES for details.
 //
 //
 // This is the implementation of the non-inlined, non-templated member
 // functions of the InvertedTildeKinematics class.
 //
 
 #include <limits>
 
 #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<Energy,double> InvertedTildeKinematics::generatePtZ(double& jac, const double * r,
 							 double pow) const {
 
   double kappaMin = 
     ptCut() != ZERO ?
     sqr(ptCut()/ptMax()) :
     sqr(0.1*GeV/GeV);
 
   double kappa;
 
   using namespace RandomHelpers;
 
   if ( ptCut() > ZERO ) {
     pair<double,double> 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<double,double> 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<double,double> zLims = zBounds(pt);
 
   pair<double,double> 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<InvertedTildeKinematics> 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<InvertedTildeKinematics,HandlerBase>
 describeInvertedTildeKinematics("Herwig::InvertedTildeKinematics", "Herwig.so");
diff --git a/MatrixElement/Matchbox/Utility/MatchboxScaleChoice.h b/MatrixElement/Matchbox/Utility/MatchboxScaleChoice.h
--- a/MatrixElement/Matchbox/Utility/MatchboxScaleChoice.h
+++ b/MatrixElement/Matchbox/Utility/MatchboxScaleChoice.h
@@ -1,161 +1,169 @@
 // -*- C++ -*-
 //
 // MatchboxScaleChoice.h is a part of Herwig - A multi-purpose Monte Carlo event generator
 // Copyright (C) 2002-2012 The Herwig Collaboration
 //
 // Herwig is licenced under version 2 of the GPL, see COPYING for details.
 // Please respect the MCnet academic guidelines, see GUIDELINES for details.
 //
 #ifndef Herwig_MatchboxScaleChoice_H
 #define Herwig_MatchboxScaleChoice_H
 //
 // This is the declaration of the MatchboxScaleChoice class.
 //
 
 #include "ThePEG/Handlers/HandlerBase.h"
 #include "ThePEG/Handlers/StandardXComb.h"
 #include "ThePEG/Handlers/LastXCombInfo.h"
 
 namespace Herwig {
 
 using namespace ThePEG;
 
 /**
  * \ingroup Matchbox
  * \author Simon Platzer
  *
  * \brief MatchboxScaleChoice is the base class for scale choices
  * within Matchbox.
  *
  */
 class MatchboxScaleChoice: public HandlerBase, public LastXCombInfo<StandardXComb> {
 
 public:
 
   /** @name Standard constructors and destructors. */
   //@{
   /**
    * The default constructor.
    */
   MatchboxScaleChoice();
 
   /**
    * The destructor.
    */
   virtual ~MatchboxScaleChoice();
   //@}
 
 public:
 
   /**
    * Clone this scale choice.
    */
   Ptr<MatchboxScaleChoice>::ptr cloneMe() const {
     return dynamic_ptr_cast<Ptr<MatchboxScaleChoice>::ptr>(clone());
   }
 
   /**
    * Set the XComb object.
    */
   virtual void setXComb(tStdXCombPtr xc) { 
     theLastXComb = xc;
   }
 
   /**
    * Return the renormalization scale. This default version returns
    * shat.
    */
   virtual Energy2 renormalizationScale() const { 
     return theFixedScale == ZERO ? lastSHat() : sqr(theFixedScale); 
   }
 
   /**
    * Return the factorization scale. This default version returns
    * shat.
    */
   virtual Energy2 factorizationScale() const { 
     return theFixedScale == ZERO ? lastSHat() : sqr(theFixedScale);
   }
 
   /**
    * Return the QED renormalization scale. This default version returns
    * the Z mass squared.
    */
   virtual Energy2 renormalizationScaleQED() const { 
     if ( theFixedQEDScale != ZERO )
       return sqr(theFixedQEDScale);
     Energy mZ = getParticleData(ParticleID::Z0)->hardProcessMass();
     return mZ*mZ; 
   }
 
+  /**
+   * Return the shower hard scale. This default implementation returns the
+   * factorization scale.
+   */
+  virtual Energy2 showerScale() const {
+    return factorizationScale();
+  }
+
 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:
 
   /**
    * A fixed scale choice. If zero, shat will be used.
    */
   Energy theFixedScale;
 
   /**
    * A fixed QED scale choice. If zero, shat will be used.
    */
   Energy theFixedQEDScale;
 
   /**
    * The assignment operator is private and must never be called.
    * In fact, it should not even be implemented.
    */
   MatchboxScaleChoice & operator=(const MatchboxScaleChoice &);
 
 };
 
 }
 
 #endif /* Herwig_MatchboxScaleChoice_H */
diff --git a/MatrixElement/Powheg/MEPP2GammaGammaPowheg.cc b/MatrixElement/Powheg/MEPP2GammaGammaPowheg.cc
new file mode 100644
--- /dev/null
+++ b/MatrixElement/Powheg/MEPP2GammaGammaPowheg.cc
@@ -0,0 +1,2200 @@
+// -*- C++ -*-
+//
+// This is the implementation of the non-inlined, non-templated member
+// functions of the MEPP2GammaGammaPowheg class.
+//
+
+#include "MEPP2GammaGammaPowheg.h"
+#include "ThePEG/Interface/ClassDocumentation.h"
+#include "ThePEG/Interface/Switch.h"
+#include "ThePEG/Interface/Parameter.h"
+#include "ThePEG/Interface/Reference.h"
+#include "ThePEG/Persistency/PersistentOStream.h"
+#include "ThePEG/Persistency/PersistentIStream.h"
+#include "ThePEG/PDT/EnumParticles.h"
+#include "ThePEG/MatrixElement/Tree2toNDiagram.h"
+#include "ThePEG/Cuts/Cuts.h"
+#include "ThePEG/Utilities/SimplePhaseSpace.h"
+#include "Herwig/Models/StandardModel/StandardModel.h"
+#include "Herwig/Utilities/Maths.h"
+#include "Herwig/Shower/Base/ShowerTree.h"
+#include "Herwig/Shower/Base/ShowerProgenitor.h"
+#include "Herwig/Shower/Base/ShowerParticle.h"
+#include "Herwig/Shower/Base/Branching.h"
+#include "Herwig/Shower/Base/HardTree.h"
+#include "ThePEG/Utilities/DescribeClass.h"
+
+using namespace Herwig;
+
+// The following static variable is needed for the type
+// description system in ThePEG.
+DescribeClass<MEPP2GammaGammaPowheg,Herwig::HwMEBase>
+describeMEPP2GammaGammaPowheg("Herwig::MEPP2GammaGammaPowheg",
+			      "HwMEHadron.so HwPowhegMEHadron.so");
+
+unsigned int MEPP2GammaGammaPowheg::orderInAlphaS() const {
+  return 0;
+}
+
+unsigned int MEPP2GammaGammaPowheg::orderInAlphaEW() const {
+  return 2;
+}
+
+IBPtr MEPP2GammaGammaPowheg::clone() const {
+  return new_ptr(*this);
+}
+
+IBPtr MEPP2GammaGammaPowheg::fullclone() const {
+  return new_ptr(*this);
+}
+
+MEPP2GammaGammaPowheg::MEPP2GammaGammaPowheg() 
+  : contrib_(1), power_(0.1), process_(0), threeBodyProcess_(0),
+    maxflavour_(5), alphaS_(0.), fixedAlphaS_(false),
+    supressionFunction_(0), supressionScale_(0), lambda_(20.*GeV),
+    preQCDqqbarq_(5.), preQCDqqbarqbar_(0.5), preQCDqg_(50.), preQCDgqbar_(50.),
+    preQEDqqbarq_(40.), preQEDqqbarqbar_(0.5), preQEDqgq_(1.), preQEDgqbarqbar_(1.),
+    minpT_(2.*GeV), scaleChoice_(0), scalePreFactor_(1.)
+{}
+
+void MEPP2GammaGammaPowheg::getDiagrams() const {
+  tcPDPtr gamma  = getParticleData(ParticleID::gamma);
+  tcPDPtr g      = getParticleData(ParticleID::g);
+  for(int ix=1;ix<=maxflavour_;++ix) {
+    tcPDPtr qk = getParticleData(ix);
+    tcPDPtr qb = qk->CC();
+    // gamma gamma
+    if(process_==0 || process_ == 1) {
+      add(new_ptr((Tree2toNDiagram(3), qk, qk, qb, 1, gamma, 2, gamma, -1)));
+      add(new_ptr((Tree2toNDiagram(3), qk, qk, qb, 2, gamma, 1, gamma, -2)));
+    }
+    // gamma +jet
+    if(process_==0 || process_ == 2) {
+      add(new_ptr((Tree2toNDiagram(3), qk, qb, qb, 1,    gamma,
+		   2, g, -4)));
+      add(new_ptr((Tree2toNDiagram(3), qk, qk, qb, 2,    gamma,
+		   1, g, -5)));
+      add(new_ptr((Tree2toNDiagram(3), qk, qk, g,    1,    gamma,
+		   2, qk, -6)));
+      add(new_ptr((Tree2toNDiagram(2), qk, g, 1, qk, 3,    gamma,
+		   3, qk, -7)));
+      add(new_ptr((Tree2toNDiagram(3), g, qb, qb,     2,    gamma,
+		   1, qb, -8)));
+      add(new_ptr((Tree2toNDiagram(2), g, qb,  1, qb, 3,    gamma,
+		   3, qb, -9)));
+    }
+    // gamma + jet + gamma
+    if((process_==0 && contrib_==1) || process_ == 3) {
+      // gamma + g + gamma
+      if(threeBodyProcess_==0 || threeBodyProcess_==1) {
+	add(new_ptr((Tree2toNDiagram(4), qk, qk, qk, qb, 1,    gamma,
+		     2, gamma, 3, g, -10)));
+	add(new_ptr((Tree2toNDiagram(4), qk, qk, qk, qb, 3,    gamma,
+		     2, gamma, 1, g, -12)));
+      }
+      // Z + q + gamma
+      if(threeBodyProcess_==0 || threeBodyProcess_==2) {
+	add(new_ptr((Tree2toNDiagram(4),qk,qk,qk,g,1,gamma,2,gamma,3,qk, -20)));
+	add(new_ptr((Tree2toNDiagram(4),qk,qk,qk,g,2,gamma,1,gamma,3,qk, -21)));
+	add(new_ptr((Tree2toNDiagram(3),qk,qk,g,1,gamma,2,qk,5,gamma,5,qk,-22)));
+      }
+      // Z + qbar + gamma
+      if(threeBodyProcess_==0 || threeBodyProcess_==3) {
+	add(new_ptr((Tree2toNDiagram(4),g,qb,qb,qb,3,gamma,2,gamma,1,qb     ,-30)));
+	add(new_ptr((Tree2toNDiagram(4),g,qb,qb,qb,2,gamma,3,gamma,1,qb     ,-31)));
+	add(new_ptr((Tree2toNDiagram(3),g,qb,qb   ,2,gamma,1,qb,5,gamma,5,qb,-32)));
+      }
+    }
+  }
+}
+
+Energy2 MEPP2GammaGammaPowheg::scale() const {
+  Energy2 scale;
+  if(scaleChoice_==0) {
+    Energy pt;
+    if(meMomenta()[2].perp(meMomenta()[0].vect())>=
+       meMomenta()[3].perp(meMomenta()[0].vect())){
+      pt = meMomenta()[2].perp(meMomenta()[0].vect());
+    } else {
+      pt = meMomenta()[3].perp(meMomenta()[0].vect());
+    }
+    scale = sqr(pt);
+  }
+  else if(scaleChoice_==1) {
+    scale = sHat();
+  }
+  return scalePreFactor_*scale;
+}
+
+int MEPP2GammaGammaPowheg::nDim() const {
+  return HwMEBase::nDim() + ( contrib_>=1 ? 3 : 0 );
+}
+
+bool MEPP2GammaGammaPowheg::generateKinematics(const double * r) {
+  // radiative variables
+  if(contrib_>=1) {
+    zTilde_ = r[nDim()-1];
+    vTilde_ = r[nDim()-2];
+    phi_    = Constants::twopi*r[nDim()-3];
+  }
+  // set the jacobian
+  jacobian(1.0);
+  // set up the momenta
+  for ( int i = 2, N = meMomenta().size(); i < N; ++i )
+    meMomenta()[i] = Lorentz5Momentum(ZERO);
+  // generate sHat
+  Energy2 shat(sHat());
+  if(mePartonData().size()==5) {
+    double eps = sqr(meMomenta()[2].mass())/shat;
+    jacobian(jacobian()*(1.-eps));
+    shat *= eps+zTilde_*(1.-eps);
+  }
+  // momenta of the core process
+  double ctmin = -1.0, ctmax = 1.0;
+  Energy q = ZERO;
+  try {
+    q = SimplePhaseSpace::
+      getMagnitude(shat, meMomenta()[2].mass(), ZERO);
+  } 
+  catch ( ImpossibleKinematics ) {
+    return false;
+  }
+  Energy e = 0.5*sqrt(shat);
+  Energy2 m22 = meMomenta()[2].mass2();
+  Energy2 e0e2 = 2.0*e*sqrt(sqr(q) + m22);
+  Energy2 e1e2 = 2.0*e*sqrt(sqr(q) + m22);
+  Energy2 e0e3 = 2.0*e*sqrt(sqr(q));
+  Energy2 e1e3 = 2.0*e*sqrt(sqr(q));
+  Energy2 pq = 2.0*e*q;
+  if(mePartonData().size()==4) {
+    Energy2 thmin = lastCuts().minTij(mePartonData()[0], mePartonData()[2]);
+    if ( thmin > ZERO ) ctmax = min(ctmax, (e0e2 - m22 - thmin)/pq);
+    thmin = lastCuts().minTij(mePartonData()[1], mePartonData()[2]);
+    if ( thmin > ZERO ) ctmin = max(ctmin, (thmin + m22 - e1e2)/pq);
+    thmin = lastCuts().minTij(mePartonData()[1], mePartonData()[3]);
+    if ( thmin > ZERO ) ctmax = min(ctmax, (e1e3 - thmin)/pq);
+    thmin = lastCuts().minTij(mePartonData()[0], mePartonData()[3]);
+    if ( thmin > ZERO ) ctmin = max(ctmin, (thmin - e0e3)/pq);
+    Energy ptmin = max(lastCuts().minKT(mePartonData()[2]),
+		       lastCuts().minKT(mePartonData()[3]));
+    if ( ptmin > ZERO ) {
+      double ctm = 1.0 - sqr(ptmin/q);
+      if ( ctm <= 0.0 ) return false;
+      ctmin = max(ctmin, -sqrt(ctm));
+      ctmax = min(ctmax, sqrt(ctm));
+    }
+    double ymin2 = lastCuts().minYStar(mePartonData()[2]);
+    double ymax2 = lastCuts().maxYStar(mePartonData()[2]);
+    double ymin3 = lastCuts().minYStar(mePartonData()[3]);
+    double ymax3 = lastCuts().maxYStar(mePartonData()[3]);
+    double ytot = lastCuts().Y() + lastCuts().currentYHat();
+    if ( ymin2 + ytot > -0.9*Constants::MaxRapidity )
+      ctmin = max(ctmin, sqrt(sqr(q) +  m22)*tanh(ymin2)/q);
+    if ( ymax2 + ytot < 0.9*Constants::MaxRapidity )
+      ctmax = min(ctmax, sqrt(sqr(q) +  m22)*tanh(ymax2)/q);
+    if ( ymin3 + ytot > -0.9*Constants::MaxRapidity )
+      ctmax = min(ctmax,                     tanh(-ymin3));
+    if ( ymax3 + ytot < 0.9*Constants::MaxRapidity )
+      ctmin = max(ctmin,                     tanh(-ymax3));
+    if ( ctmin >= ctmax ) return false;
+  }
+  double cth = getCosTheta(ctmin, ctmax, r[0]);
+  Energy pt = q*sqrt(1.0-sqr(cth));
+  phi(rnd(2.0*Constants::pi));
+  meMomenta()[2].setVect(Momentum3( pt*sin(phi()),  pt*cos(phi()),  q*cth));
+  meMomenta()[3].setVect(Momentum3(-pt*sin(phi()), -pt*cos(phi()), -q*cth));
+  meMomenta()[2].rescaleEnergy();
+  meMomenta()[3].rescaleEnergy();
+  // jacobian
+  tHat(pq*cth + m22 - e0e2);
+  uHat(m22 - shat - tHat());
+  jacobian(pq/shat*Constants::pi*jacobian());
+  // end for 2->2 processes
+  if(mePartonData().size()==4) {
+    vector<LorentzMomentum> out(2);
+    out[0] = meMomenta()[2];
+    out[1] = meMomenta()[3];
+    tcPDVector tout(2);
+    tout[0] = mePartonData()[2];
+    tout[1] = mePartonData()[3];
+    if ( !lastCuts().passCuts(tout, out, mePartonData()[0], mePartonData()[1]) )
+      return false;
+    return true;
+  }
+  // special for 2-3 processes
+  pair<double,double> x = make_pair(lastX1(),lastX2());
+  // partons
+  pair<tcPDPtr,tcPDPtr> partons = make_pair(mePartonData()[0],mePartonData()[1]);
+  // If necessary swap the particle data objects so that 
+  // first beam gives the incoming quark
+  if(lastPartons().first ->dataPtr()!=partons.first) {
+    swap(x.first,x.second);
+  }
+  // use vTilde to select the dipole for emission
+  // gamma gamma g processes
+  if(mePartonData()[4]->id()==ParticleID::g) {
+    if(vTilde_<=0.5) {
+      dipole_ = IIQCD1;
+      vTilde_ = 4.*vTilde_;
+    }
+    else {
+      dipole_ = IIQCD2;
+      vTilde_ = 4.*(vTilde_-0.25);
+    }
+    jacobian(2.*jacobian());
+  }
+  // gamma gamma q processes
+  else if(mePartonData()[4]->id()>0&&mePartonData()[4]->id()<6) {
+    if(vTilde_<=1./3.) {
+      dipole_ = IIQCD2;
+      vTilde_ = 3.*vTilde_;
+    }
+    else if(vTilde_<=2./3.) {
+      dipole_ = IFQED1;
+      vTilde_ = 3.*vTilde_-1.;
+    }
+    else {
+      dipole_ = FIQED1;
+      vTilde_ = 3.*vTilde_-2.;
+    }
+    jacobian(3.*jacobian());
+  }
+  // gamma gamma qbar processes
+  else if(mePartonData()[4]->id()<0&&mePartonData()[4]->id()>-6) {
+    if(vTilde_<=1./3.) {
+      dipole_ = IIQCD1;
+      vTilde_ = 3.*vTilde_;
+    }
+    else if(vTilde_<=2./3.) {
+      dipole_ = IFQED2;
+      vTilde_ = 3.*vTilde_-1.;
+    }
+    else {
+      dipole_ = FIQED2;
+      vTilde_ = 3.*vTilde_-2.;
+    }
+    jacobian(3.*jacobian());
+  }
+  else {
+    assert(false);
+  }
+  // initial-initial dipoles
+  if(dipole_<=4) {
+    double z    = shat/sHat();
+    double vt   = vTilde_*(1.-z);
+    double vJac = 1.-z;
+    Energy pT   = sqrt(shat*vt*(1.-vt-z)/z);
+    if(pT<MeV) return false;
+    double rapidity;
+    Energy rs=sqrt(lastS());
+    Lorentz5Momentum pcmf;
+    // emission from first beam
+    if(dipole_<=2) {
+      rapidity = -log(x.second*sqrt(lastS())/pT*vt);
+      pcmf = Lorentz5Momentum(ZERO,ZERO,
+			      0.5*rs*(x.first*z-x.second),
+			      0.5*rs*(x.first*z+x.second));
+    }
+    // emission from second beam
+    else {
+      rapidity =  log(x.first *sqrt(lastS())/pT*vt);
+      pcmf = Lorentz5Momentum(ZERO,ZERO,
+			      0.5*rs*(x.first-x.second*z),
+			      0.5*rs*(x.first+x.second*z));
+    }
+    pcmf.rescaleMass();
+    Boost blab(pcmf.boostVector());
+    // emission from the quark radiation
+    vector<Lorentz5Momentum> pnew(5);
+    pnew [0] = Lorentz5Momentum(ZERO,ZERO,0.5*rs*x.first,
+				0.5*rs*x.first,ZERO);
+    pnew [1] = Lorentz5Momentum(ZERO,ZERO,-0.5*rs*x.second,
+				0.5*rs*x.second,ZERO) ;
+    pnew [2] = meMomenta()[2];
+    pnew [3] = meMomenta()[3];
+    pnew [4] = Lorentz5Momentum(pT*cos(phi_),pT*sin(phi_),
+				pT*sinh(rapidity),
+				pT*cosh(rapidity), ZERO);
+    pnew[4].rescaleEnergy();
+    Lorentz5Momentum K  = pnew [0]+pnew [1]-pnew [4]; 
+    Lorentz5Momentum Kt = pcmf;
+    Lorentz5Momentum Ksum = K+Kt;
+    Energy2 K2 = K.m2();
+    Energy2 Ksum2 = Ksum.m2();
+    for(unsigned int ix=2;ix<4;++ix) {
+      pnew [ix].boost(blab);
+      pnew [ix] = pnew [ix] - 2.*Ksum*(Ksum*pnew [ix])/Ksum2
+	+2*K*(Kt*pnew [ix])/K2;
+      pnew[ix].rescaleEnergy();
+    }
+    pcmf = Lorentz5Momentum(ZERO,ZERO,
+			    0.5*rs*(x.first-x.second),
+			    0.5*rs*(x.first+x.second));
+    pcmf.rescaleMass();
+    blab = pcmf.boostVector();
+    for(unsigned int ix=0;ix<pnew.size();++ix)
+      pnew[ix].boost(-blab);
+    // phase-space prefactors
+    jacobian(jacobian()*vJac);
+    if(dipole_%2!=0) swap(pnew[3],pnew[4]);
+    for(unsigned int ix=2;ix<meMomenta().size();++ix)
+      meMomenta()[ix] = pnew[ix];
+  }
+  else if(dipole_<=8) {
+    double x  = shat/sHat();
+    double z = vTilde_;
+    double x1 = -1./x;
+    double x3 = 1.-z/x;
+    double x2 = 2.+x1-x3;
+    double xT = sqrt(4.*(1-x)*(1-z)*z/x);
+    // rotate the momenta into the Breit-frame
+    Lorentz5Momentum pin,pcmf;
+    if(dipole_<=6) {
+      pin = x*meMomenta()[0];
+      pcmf = pin+meMomenta()[1];
+    }
+    else {
+      pin = x*meMomenta()[1];
+      pcmf = pin+meMomenta()[0];
+    }
+    Boost bv = pcmf.boostVector();
+    meMomenta()[2].boost(bv);
+    meMomenta()[3].boost(bv);
+    Lorentz5Momentum q = meMomenta()[3]-pin;
+    Axis axis(q.vect().unit());
+    LorentzRotation rot;
+    double sinth(sqrt(sqr(axis.x())+sqr(axis.y())));
+    rot = LorentzRotation();
+    if(axis.perp2()>1e-20) {
+      rot.setRotate(-acos(axis.z()),Axis(-axis.y()/sinth,axis.x()/sinth,0.));
+      rot.rotateX(Constants::pi);
+    }
+    if(abs(1.-q.e()/q.vect().mag())>1e-6) 
+      rot.boostZ(q.e()/q.vect().mag());
+    pin *= rot;
+    if(pin.perp2()/GeV2>1e-20) {
+      Boost trans = -1./pin.e()*pin.vect();
+      trans.setZ(0.);
+      rot.boost(trans);
+    }
+    rot.invert();
+    Energy Q = sqrt(-q.m2());
+    meMomenta()[4] = rot*Lorentz5Momentum( 0.5*Q*xT*cos(phi_), 0.5*Q*xT*sin(phi_),
+					  -0.5*Q*x2,0.5*Q*sqrt(sqr(x2)+sqr(xT)));
+    meMomenta()[3] = rot*Lorentz5Momentum(-0.5*Q*xT*cos(phi_),-0.5*Q*xT*sin(phi_),
+					  -0.5*Q*x3,0.5*Q*sqrt(sqr(x3)+sqr(xT)));
+
+    double ratio;
+    if(dipole_<=6) {
+      ratio =  2.*((meMomenta()[3]+meMomenta()[4])*meMomenta()[0])/sHat();
+    }
+    else {
+      ratio =  2.*((meMomenta()[3]+meMomenta()[4])*meMomenta()[1])/sHat();
+    }
+    jacobian(jacobian()*ratio);
+  }
+  else {
+    assert(false);
+  }
+  vector<LorentzMomentum> out(3);
+  tcPDVector tout(3);
+  for(unsigned int ix=0;ix<3;++ix) {
+    out[ix]  = meMomenta()   [2+ix];
+    tout[ix] = mePartonData()[2+ix];
+  }
+  return lastCuts().passCuts(tout, out, mePartonData()[0], mePartonData()[1]);
+}
+
+double MEPP2GammaGammaPowheg::me2() const {
+  // Born configurations
+  if(mePartonData().size()==4) {
+    // gamma gamma core process
+    if(mePartonData()[3]->id()==ParticleID::gamma) {
+      return 2.*Constants::twopi*alphaEM_*
+	loGammaGammaME(mePartonData(),meMomenta(),true);
+    }
+    // V jet core process
+    else if(mePartonData()[3]->id()==ParticleID::g) {
+      return 2.*Constants::twopi*alphaS_*
+	loGammagME(mePartonData(),meMomenta(),true);
+    }
+    else if(mePartonData()[3]->id()>0) {
+      return 2.*Constants::twopi*alphaS_*
+	loGammaqME(mePartonData(),meMomenta(),true);
+    }
+    else if(mePartonData()[3]->id()<0) {
+      return 2.*Constants::twopi*alphaS_*
+	loGammaqbarME(mePartonData(),meMomenta(),true);
+    }
+    else
+      assert(false);
+  }
+  // hard emission configurations
+  else {
+    if(mePartonData()[4]->id()==ParticleID::g)
+      return sHat()*realGammaGammagME   (mePartonData(),meMomenta(),dipole_,Hard,true);
+    else if(mePartonData()[4]->id()>0&&mePartonData()[4]->id()<6)
+      return sHat()*realGammaGammaqME   (mePartonData(),meMomenta(),dipole_,Hard,true);
+    else if(mePartonData()[4]->id()<0&&mePartonData()[4]->id()>-6)
+      return sHat()*realGammaGammaqbarME(mePartonData(),meMomenta(),dipole_,Hard,true);
+    else
+      assert(false);
+  }
+}
+
+CrossSection MEPP2GammaGammaPowheg::dSigHatDR() const {
+  // couplings
+  if(!fixedAlphaS_) alphaS_ = SM().alphaS(scale());
+  alphaEM_ = SM().alphaEM();
+    // cross section
+  CrossSection preFactor = 
+    jacobian()/(16.0*sqr(Constants::pi)*sHat())*sqr(hbarc);
+  loME_ = me2();
+ 
+  if( contrib_== 0 || mePartonData().size()==5 || 
+      (mePartonData().size()==4&& mePartonData()[3]->coloured())) 
+    return loME_*preFactor;
+  else
+    return NLOWeight()*preFactor;
+}
+
+
+Selector<MEBase::DiagramIndex>
+MEPP2GammaGammaPowheg::diagrams(const DiagramVector & diags) const {
+  if(mePartonData().size()==4) {
+    if(mePartonData()[3]->id()==ParticleID::gamma) {
+ 
+      Selector<DiagramIndex> sel;
+      for ( DiagramIndex i = 0; i < diags.size(); ++i ){
+	sel.insert(meInfo()[abs(diags[i]->id())], i);
+      }
+      return sel;
+    }
+    else {
+      Selector<DiagramIndex> sel;
+      for ( DiagramIndex i = 0; i < diags.size(); ++i ){ 
+	sel.insert(meInfo()[abs(diags[i]->id())%2], i);
+      }
+      return sel;
+    }
+  }
+  else {
+    Selector<DiagramIndex> sel;
+    for ( DiagramIndex i = 0; i < diags.size(); ++i ) { 
+      if(abs(diags[i]->id()) == 10 && dipole_ == IIQCD2 ) 
+	sel.insert(1., i);
+      else if(abs(diags[i]->id()) == 12 && dipole_ == IIQCD1 ) 
+	sel.insert(1., i);
+      else if(abs(diags[i]->id()) == 20 && dipole_ == IIQCD2 ) 
+      sel.insert(1., i);
+      else if(abs(diags[i]->id()) == 21 && dipole_ == IFQED1 ) 
+	sel.insert(1., i);
+      else if(abs(diags[i]->id()) == 22 && dipole_ == FIQED1 ) 
+	sel.insert(1., i);
+      else 
+	sel.insert(0., i);
+    }
+    return sel;
+  }
+}
+
+Selector<const ColourLines *>
+MEPP2GammaGammaPowheg::colourGeometries(tcDiagPtr diag) const {
+  // colour lines for V gamma
+  static ColourLines cs("1 -2");
+  static ColourLines ct("1 2 -3");
+  // colour lines for q qbar -> V g
+  static const ColourLines cqqbar[2]={ColourLines("1 -2 5,-3 -5"),
+				      ColourLines("1 5,-5 2 -3")};
+  // colour lines for q g -> V q
+  static const ColourLines cqg   [2]={ColourLines("1 2 -3,3 5"),
+				      ColourLines("1 -2,2 3 5")};
+  // colour lines for g qbar -> V qbar
+  static const ColourLines cgqbar[2]={ColourLines("-3 -2 1,-1 -5"),
+				      ColourLines("-2 1,-1 -3 -5")};
+  // colour lines for q qbar -> V gamma g
+  static const ColourLines cqqbarg[4]={ColourLines("1 2 3 7,-4 -7"),
+				       ColourLines("1 2 7,-4 3 -7"),
+				       ColourLines("1 7,-4 3 2 -7"),
+				       ColourLines("1 2 7,-4 3 -7")};
+  // colour lines for q g -> V gamma q
+  static const ColourLines cqgq  [3]={ColourLines("1 2 3 -4,4 7"),
+				      ColourLines("1 2 3 -4,4 7"),
+				      ColourLines("1 2 -3,3 5 7")};
+  // colour lines for gbar -> V gamma qbar
+  static const ColourLines cqbargqbar[3]={ColourLines("1 -2 -3 -4,-1 -7"),
+					  ColourLines("1 -2 -3 -4,-1 -7"),
+					  ColourLines("1 -2 -3,-1 -5 -7")};
+  Selector<const ColourLines *> sel;
+  switch(abs(diag->id())) {
+  case 1 :case 2 :
+    sel.insert(1.0, &ct); 
+    break;
+  case 3 : 
+    sel.insert(1.0, &cs);
+    break;
+  case 4 : 
+    sel.insert(1.0, &cqqbar[0]);
+    break;
+  case 5:
+    sel.insert(1.0, &cqqbar[1]);
+    break;
+  case 6: 
+    sel.insert(1.0, &cqg[0]);
+    break;
+  case 7:
+    sel.insert(1.0, &cqg[1]);
+    break;
+  case 8: 
+    sel.insert(1.0, &cgqbar[0]);
+    break;
+  case 9:
+    sel.insert(1.0, &cgqbar[1]);
+    break;
+  case 10: case 11: case 12: case 13:
+    sel.insert(1.0, &cqqbarg[abs(diag->id())-10]);
+    break;
+  case 20: case 21: case 22:
+    sel.insert(1.0, &cqgq[abs(diag->id())-20]);
+    break;
+  case 30: case 31: case 32:
+    sel.insert(1.0, &cqbargqbar[abs(diag->id())-30]);
+    break;
+  default:
+    assert(false);
+  }
+  return sel;
+}
+
+void MEPP2GammaGammaPowheg::persistentOutput(PersistentOStream & os) const {
+  os << FFPvertex_ << FFGvertex_ 
+     << contrib_ << power_ << gluon_ << prefactor_
+     << process_ << threeBodyProcess_<< maxflavour_ 
+     << alphaS_ << fixedAlphaS_
+     << supressionFunction_ << supressionScale_ << ounit(lambda_,GeV)
+     << alphaQCD_ << alphaQED_ << ounit(minpT_,GeV)
+     << preQCDqqbarq_ << preQCDqqbarqbar_ << preQCDqg_ << preQCDgqbar_
+     << preQEDqqbarq_ << preQEDqqbarqbar_ << preQEDqgq_ << preQEDgqbarqbar_
+     << scaleChoice_ << scalePreFactor_;
+}
+
+void MEPP2GammaGammaPowheg::persistentInput(PersistentIStream & is, int) {
+  is >> FFPvertex_ >> FFGvertex_ 
+     >> contrib_ >> power_ >> gluon_ >> prefactor_
+     >> process_ >> threeBodyProcess_ >> maxflavour_ 
+     >> alphaS_ >> fixedAlphaS_
+     >> supressionFunction_ >> supressionScale_ >> iunit(lambda_,GeV)
+     >> alphaQCD_ >> alphaQED_ >> iunit(minpT_,GeV)
+     >> preQCDqqbarq_ >> preQCDqqbarqbar_ >> preQCDqg_ >> preQCDgqbar_
+     >> preQEDqqbarq_ >> preQEDqqbarqbar_ >> preQEDqgq_ >> preQEDgqbarqbar_
+     >> scaleChoice_ >> scalePreFactor_;
+}
+
+void MEPP2GammaGammaPowheg::Init() {
+
+  static ClassDocumentation<MEPP2GammaGammaPowheg> documentation
+    ("TheMEPP2GammaGammaPowheg class implements gamma gamma production at NLO");
+
+  static Switch<MEPP2GammaGammaPowheg,unsigned int> interfaceProcess
+    ("Process",
+     "Which processes to include",
+     &MEPP2GammaGammaPowheg::process_, 0, false, false);
+  static SwitchOption interfaceProcessAll
+    (interfaceProcess,
+     "All",
+     "Include all the processes",
+     0);
+  static SwitchOption interfaceProcessGammaGamma
+    (interfaceProcess,
+     "GammaGamma",
+     "Only include gamma gamma",
+     1);
+  static SwitchOption interfaceProcessVJet
+    (interfaceProcess,
+     "VJet",
+     "Only include gamma + jet",
+     2);
+  static SwitchOption interfaceProcessHard
+    (interfaceProcess,
+     "Hard",
+     "Only include hard radiation contributions",
+     3);
+
+  static Switch<MEPP2GammaGammaPowheg,unsigned int> interfaceThreeBodyProcess
+    ("ThreeBodyProcess",
+     "The possible three body processes to include",
+     &MEPP2GammaGammaPowheg::threeBodyProcess_, 0, false, false);
+  static SwitchOption interfaceThreeBodyProcessAll
+    (interfaceThreeBodyProcess,
+     "All",
+     "Include all processes",
+     0);
+  static SwitchOption interfaceThreeBodyProcessqqbar
+    (interfaceThreeBodyProcess,
+     "qqbar",
+     "Only include q qbar -> gamma gamma g processes",
+     1);
+  static SwitchOption interfaceThreeBodyProcessqg
+    (interfaceThreeBodyProcess,
+     "qg",
+     "Only include q g -> gamma gamma q processes",
+     2);
+  static SwitchOption interfaceThreeBodyProcessgqbar
+    (interfaceThreeBodyProcess,
+     "gqbar",
+     "Only include g qbar -> gamma gamma qbar processes",
+     3);
+
+   static Switch<MEPP2GammaGammaPowheg,unsigned int> interfaceContribution
+    ("Contribution",
+     "Which contributions to the cross section to include",
+     &MEPP2GammaGammaPowheg::contrib_, 1, false, false);
+  static SwitchOption interfaceContributionLeadingOrder
+    (interfaceContribution,
+     "LeadingOrder",
+     "Just generate the leading order cross section",
+     0);
+  static SwitchOption interfaceContributionPositiveNLO
+    (interfaceContribution,
+     "PositiveNLO",
+     "Generate the positive contribution to the full NLO cross section",
+     1);
+  static SwitchOption interfaceContributionNegativeNLO
+    (interfaceContribution,
+     "NegativeNLO",
+     "Generate the negative contribution to the full NLO cross section",
+     2);
+
+  static Parameter<MEPP2GammaGammaPowheg,int> interfaceMaximumFlavour
+    ("MaximumFlavour",
+     "The maximum flavour allowed for the incoming quarks",
+     &MEPP2GammaGammaPowheg::maxflavour_, 5, 1, 5,
+     false, false, Interface::limited);
+
+  static Parameter<MEPP2GammaGammaPowheg,double> interfaceAlphaS
+    ("AlphaS",
+     "The value of alphaS to use if using a fixed alphaS",
+     &MEPP2GammaGammaPowheg::alphaS_, 0.118, 0.0, 0.2,
+     false, false, Interface::limited);
+
+  static Switch<MEPP2GammaGammaPowheg,bool> interfaceFixedAlphaS
+    ("FixedAlphaS",
+     "Use a fixed value of alphaS",
+     &MEPP2GammaGammaPowheg::fixedAlphaS_, false, false, false);
+  static SwitchOption interfaceFixedAlphaSYes
+    (interfaceFixedAlphaS,
+     "Yes",
+     "Use a fixed alphaS",
+     true);
+  static SwitchOption interfaceFixedAlphaSNo
+    (interfaceFixedAlphaS,
+     "No",
+     "Use a running alphaS",
+     false);
+
+  static Switch<MEPP2GammaGammaPowheg,unsigned int> interfaceSupressionFunction
+    ("SupressionFunction",
+     "Choice of the supression function",
+     &MEPP2GammaGammaPowheg::supressionFunction_, 0, false, false);
+  static SwitchOption interfaceSupressionFunctionNone
+    (interfaceSupressionFunction,
+     "None",
+     "Default POWHEG approach",
+     0);
+  static SwitchOption interfaceSupressionFunctionThetaFunction
+    (interfaceSupressionFunction,
+     "ThetaFunction",
+     "Use theta functions at scale Lambda",
+     1);
+  static SwitchOption interfaceSupressionFunctionSmooth
+    (interfaceSupressionFunction,
+     "Smooth",
+     "Supress high pT by pt^2/(pt^2+lambda^2)",
+     2);
+
+  static Parameter<MEPP2GammaGammaPowheg,Energy> interfaceSupressionScale
+    ("SupressionScale",
+     "The square of the scale for the supression function",
+     &MEPP2GammaGammaPowheg::lambda_, GeV, 20.0*GeV, 0.0*GeV, 0*GeV,
+     false, false, Interface::lowerlim);
+
+  static Switch<MEPP2GammaGammaPowheg,unsigned int> interfaceSupressionScaleChoice
+    ("SupressionScaleChoice",
+     "Choice of the supression scale",
+     &MEPP2GammaGammaPowheg::supressionScale_, 0, false, false);
+  static SwitchOption interfaceSupressionScaleChoiceFixed
+    (interfaceSupressionScaleChoice,
+     "Fixed",
+     "Use a fixed scale",
+     0);
+  static SwitchOption interfaceSupressionScaleChoiceVariable
+    (interfaceSupressionScaleChoice,
+     "Variable",
+     "Use the pT of the hard process as the scale",
+     1);
+
+  static Reference<MEPP2GammaGammaPowheg,ShowerAlpha> interfaceShowerAlphaQCD
+    ("ShowerAlphaQCD",
+     "Reference to the object calculating the QCD coupling for the shower",
+     &MEPP2GammaGammaPowheg::alphaQCD_, false, false, true, false, false);
+
+  static Reference<MEPP2GammaGammaPowheg,ShowerAlpha> interfaceShowerAlphaQED
+    ("ShowerAlphaQED",
+     "Reference to the object calculating the QED coupling for the shower",
+     &MEPP2GammaGammaPowheg::alphaQED_, false, false, true, false, false);
+
+  static Parameter<MEPP2GammaGammaPowheg,double> interfacepreQCDqqbarq
+    ("preQCDqqbarq",
+     "The constant for the Sudakov overestimate for the "
+     "q qbar -> V Gamma +g with emission from the q",
+     &MEPP2GammaGammaPowheg::preQCDqqbarq_, 23.0, 0.0, 1000.0,
+     false, false, Interface::limited);
+
+  static Parameter<MEPP2GammaGammaPowheg,double> interfacepreQCDqqbarqbar
+    ("preQCDqqbarqbar",
+     "The constant for the Sudakov overestimate for the "
+     "q qbar -> V Gamma +g with emission from the qbar",
+     &MEPP2GammaGammaPowheg::preQCDqqbarqbar_, 23.0, 0.0, 1000.0,
+     false, false, Interface::limited);
+
+  static Switch<MEPP2GammaGammaPowheg,unsigned int> interfaceScaleChoice
+    ("ScaleChoice",
+     "The scale choice to use",
+     &MEPP2GammaGammaPowheg::scaleChoice_, 0, false, false);
+  static SwitchOption interfaceScaleChoicepT
+    (interfaceScaleChoice,
+     "pT",
+     "Use the pT of the photons",
+     0);
+  static SwitchOption interfaceScaleChoiceMGammaGamma
+    (interfaceScaleChoice,
+     "MGammaGamma",
+     "Use the mass of the photon pair",
+     1);
+
+  static Parameter<MEPP2GammaGammaPowheg,double> interfaceScalePreFactor
+    ("ScalePreFactor",
+     "Prefactor to change factorization/renormalisation scale",
+     &MEPP2GammaGammaPowheg::scalePreFactor_, 1.0, 0.1, 10.0,
+     false, false, Interface::limited);
+
+
+//   prefactor_.push_back(preQCDqg_);
+//   prefactor_.push_back(preQCDgqbar_);
+//   prefactor_.push_back(preQEDqqbarq_);
+//   prefactor_.push_back(preQEDqqbarqbar_);
+//   prefactor_.push_back(preQEDqgq_);
+//   prefactor_.push_back(preQEDgqbarqbar_);
+}
+
+double MEPP2GammaGammaPowheg::NLOWeight() const {
+  // if leading-order return 
+  if(contrib_==0) return loME_;
+  // prefactors
+  CFfact_ = 4./3.*alphaS_/Constants::twopi;
+  TRfact_ = 1./2.*alphaS_/Constants::twopi;
+  // scale
+  Energy2 mu2 = scale();
+  // virtual pieces
+  double virt = CFfact_*subtractedVirtual();
+  // extract the partons and stuff for the real emission
+  //  and collinear counter terms
+  // hadrons
+  pair<tcBeamPtr,tcBeamPtr> hadrons= 
+    make_pair(dynamic_ptr_cast<tcBeamPtr>(lastParticles().first->dataPtr() ),
+	      dynamic_ptr_cast<tcBeamPtr>(lastParticles().second->dataPtr()));
+  // momentum fractions
+  pair<double,double> x = make_pair(lastX1(),lastX2());
+  // partons
+  pair<tcPDPtr,tcPDPtr> partons = make_pair(mePartonData()[0],mePartonData()[1]);
+  // If necessary swap the particle data objects so that 
+  // first beam gives the incoming quark
+  if(lastPartons().first ->dataPtr()!=partons.first) {
+    swap(x.first,x.second);
+    swap(hadrons.first,hadrons.second);
+  }
+  // convert the values of z tilde to z
+  pair<double,double> z;
+  pair<double,double> zJac;
+  double rhomax(pow(1.-x.first,1.-power_));
+  double rho = zTilde_*rhomax;
+  z.first = 1.-pow(rho,1./(1.-power_));
+  zJac.first = rhomax*pow(1.-z.first,power_)/(1.-power_);
+  rhomax = pow(1.-x.second,1.-power_);
+  rho = zTilde_*rhomax; 
+  z.second = 1.-pow(rho,1./(1.-power_));
+  zJac.second = rhomax*pow(1.-z.second,power_)/(1.-power_);
+  // calculate the PDFs
+  pair<double,double> oldqPDF = 
+    make_pair(hadrons.first ->pdf()->xfx(hadrons.first ,partons.first ,scale(),
+					 x.first )/x.first ,
+	      hadrons.second->pdf()->xfx(hadrons.second,partons.second,scale(),
+					 x.second)/x.second);
+  // real/coll q/qbar
+  pair<double,double> newqPDF = 
+    make_pair(hadrons.first ->pdf()->xfx(hadrons.first ,partons.first ,scale(),
+					 x.first /z.first )*z.first /x.first ,
+	      hadrons.second->pdf()->xfx(hadrons.second,partons.second,scale(),
+					 x.second/z.second)*z.second/x.second);
+  // real/coll gluon
+  pair<double,double> newgPDF =  
+    make_pair(hadrons.first ->pdf()->xfx(hadrons.first ,gluon_,scale(),
+					 x.first /z.first )*z.first /x.first ,
+	      hadrons.second->pdf()->xfx(hadrons.second,gluon_,scale(),
+					 x.second/z.second)*z.second/x.second);
+  // coll terms
+  // g -> q
+  double collGQ    = collinearGluon(mu2,zJac.first,z.first,
+				    oldqPDF.first,newgPDF.first);
+  // g -> qbar
+  double collGQbar = collinearGluon(mu2,zJac.second,z.second,
+				    oldqPDF.second,newgPDF.second);
+  // q -> q
+  double collQQ       = collinearQuark(x.first ,mu2,zJac.first ,z.first ,
+				       oldqPDF.first ,newqPDF.first );
+  // qbar -> qbar
+  double collQbarQbar = collinearQuark(x.second,mu2,zJac.second,z.second,
+				       oldqPDF.second,newqPDF.second);
+  // collinear remnants 
+  double coll = collQQ+collQbarQbar+collGQ+collGQbar;
+  // real emission contribution
+  double real1 = subtractedReal(x,z. first,zJac. first,oldqPDF. first,
+				newqPDF. first,newgPDF. first, true);
+  double real2 = subtractedReal(x,z.second,zJac.second,oldqPDF.second,
+				newqPDF.second,newgPDF.second,false);
+  // the total weight
+  double wgt = loME_ + loME_*virt + loME_*coll + real1 + real2;
+  return contrib_ == 1 ? max(0.,wgt) : max(0.,-wgt);
+}
+
+double MEPP2GammaGammaPowheg::loGammaGammaME(const cPDVector & particles,
+					     const vector<Lorentz5Momentum> & momenta,
+					     bool first) const {
+  double output(0.);
+  // analytic formula for speed
+  if(!first) {
+    Energy2 th = (momenta[0]-momenta[2]).m2();
+    Energy2 uh = (momenta[0]-momenta[3]).m2();
+    output = 4./3.*Constants::pi*SM().alphaEM(ZERO)*(th/uh+uh/th)*
+      pow(double(particles[0]->iCharge())/3.,4);
+  }
+  // HE code result
+  else {
+    // wavefunctions for the incoming fermions
+    SpinorWaveFunction    em_in( momenta[0],particles[0],incoming);
+    SpinorBarWaveFunction ep_in( momenta[1],particles[1],incoming);
+    // wavefunctions for the outgoing bosons
+    VectorWaveFunction v1_out(momenta[2],particles[2],outgoing);
+    VectorWaveFunction v2_out(momenta[3],particles[3],outgoing);
+    vector<SpinorWaveFunction> f1;
+    vector<SpinorBarWaveFunction> a1;
+    vector<VectorWaveFunction> v1,v2;
+    // calculate the wavefunctions
+    for(unsigned int ix=0;ix<2;++ix) {
+      em_in.reset(ix);
+      f1.push_back(em_in);
+      ep_in.reset(ix);
+      a1.push_back(ep_in);
+      v1_out.reset(2*ix);
+      v1.push_back(v1_out);
+      v2_out.reset(2*ix);
+      v2.push_back(v2_out);
+    }
+    vector<double> me(4,0.0);
+    me_.reset(ProductionMatrixElement(PDT::Spin1Half,PDT::Spin1Half,
+				      PDT::Spin1,PDT::Spin1));
+    vector<Complex> diag(2,0.0);
+    SpinorWaveFunction inter;
+    for(unsigned int ihel1=0;ihel1<2;++ihel1) {
+      for(unsigned int ihel2=0;ihel2<2;++ihel2) {
+	for(unsigned int ohel1=0;ohel1<2;++ohel1) {
+	  for(unsigned int ohel2=0;ohel2<2;++ohel2) {
+	    inter   = FFPvertex_->evaluate(ZERO,5,f1[ihel1].particle(),
+					   f1[ihel1],v1[ohel1]);
+	    diag[0] = FFPvertex_->evaluate(ZERO,inter,a1[ihel2],v2[ohel2]);
+	    inter   = FFPvertex_->evaluate(ZERO,5,f1[ihel1].particle(),
+					   f1[ihel1] ,v2[ohel2]);
+	    diag[1] = FFPvertex_->evaluate(ZERO,inter,a1[ihel2],v1[ohel1]);
+	    // individual diagrams
+	    for (size_t ii=0; ii<2; ++ii) me[ii] += std::norm(diag[ii]);
+	    // full matrix element
+	    diag[0] += diag[1];
+	    output += std::norm(diag[0]);
+	    // storage of the matrix element for spin correlations
+	    me_(ihel1,ihel2,2*ohel1,2*ohel2) = diag[0];
+	  }
+	}
+      }
+    }
+    // store diagram info, etc.
+    DVector save(3);
+    for (size_t i = 0; i < 3; ++i) save[i] = 0.25 * me[i];
+    meInfo(save);
+    // spin and colour factors
+    output *= 0.125/3./norm(FFPvertex_->norm());
+  }
+  return output;
+}
+
+double MEPP2GammaGammaPowheg::loGammaqME(const cPDVector & particles,
+					 const vector<Lorentz5Momentum> & momenta,
+					 bool first) const {
+  double output(0.);
+  // analytic formula for speed
+  if(!first) {
+    Energy2 sh = (momenta[0]+momenta[1]).m2();
+    Energy2 th = (momenta[0]-momenta[2]).m2();
+    Energy2 uh = (momenta[0]-momenta[3]).m2();
+    output = -1./3./sh/th*(sh*sh+th*th+2.*uh*(sh+th+uh))*
+      4.*Constants::pi*SM().alphaEM(ZERO)*
+      sqr(particles[0]->iCharge()/3.);
+  }
+  // HE result
+  else {
+    vector<SpinorWaveFunction> fin;
+    vector<VectorWaveFunction> gin;
+    vector<SpinorBarWaveFunction> fout;
+    vector<VectorWaveFunction> vout;
+    SpinorWaveFunction    qin (momenta[0],particles[0],incoming);
+    VectorWaveFunction    glin(momenta[1],particles[1],incoming);
+    VectorWaveFunction    wout(momenta[2],particles[2],outgoing);
+    SpinorBarWaveFunction qout(momenta[3],particles[3],outgoing);
+    // polarization states for the particles
+    for(unsigned int ix=0;ix<2;++ix) {
+      qin.reset(ix) ;
+      fin.push_back(qin);
+      qout.reset(ix);
+      fout.push_back(qout);
+      glin.reset(2*ix);
+      gin.push_back(glin);
+      wout.reset(2*ix);
+      vout.push_back(wout);
+    }
+    me_.reset(ProductionMatrixElement(PDT::Spin1Half,PDT::Spin1,
+				      PDT::Spin1,PDT::Spin1Half));
+    // compute the matrix elements
+    double me[3]={0.,0.,0.};
+    Complex diag[2];
+    SpinorWaveFunction inters;
+    SpinorBarWaveFunction interb;
+    for(unsigned int ihel1=0;ihel1<2;++ihel1) {
+      for(unsigned int ihel2=0;ihel2<2;++ihel2) {
+	for(unsigned int ohel1=0;ohel1<2;++ohel1) {
+	  // intermediates for the diagrams
+	  interb= FFGvertex_->evaluate(scale(),5,particles[3],
+				       fout[ohel1],gin[ihel2]);
+	  inters= FFGvertex_->evaluate(scale(),5,particles[0],
+				       fin[ihel1],gin[ihel2]);
+	  for(unsigned int vhel=0;vhel<2;++vhel) {
+	    diag[0] = FFPvertex_->evaluate(ZERO,fin[ihel1],interb,vout[vhel]);
+	    diag[1] = FFPvertex_->evaluate(ZERO,inters,fout[ohel1],vout[vhel]);
+	    // diagram contributions
+	    me[1] += norm(diag[0]);
+	    me[2] += norm(diag[1]);
+	    // total
+	    diag[0] += diag[1];
+	    me[0]   += norm(diag[0]);
+	    me_(ihel1,2*ihel2,2*vhel,ohel1) = diag[0];
+	  }
+	}
+      }
+    }
+    // results
+    // initial state spin and colour average
+    double colspin = 1./24./4.;
+    // and C_F N_c from matrix element
+    colspin *= 4.;
+    DVector save;
+    for(unsigned int ix=0;ix<3;++ix) {
+      me[ix] *= colspin;
+      if(ix>0) save.push_back(me[ix]);
+    }
+    meInfo(save);
+    output = me[0]/norm(FFGvertex_->norm());
+  }
+  return output;
+}
+
+double MEPP2GammaGammaPowheg::loGammaqbarME(const cPDVector & particles,
+					    const vector<Lorentz5Momentum> & momenta,
+					    bool first) const {
+  double output(0.);
+  // analytic formula for speed
+  if(!first) {
+    Energy2 sh = (momenta[0]+momenta[1]).m2();
+    Energy2 uh = (momenta[0]-momenta[2]).m2();
+    Energy2 th = (momenta[0]-momenta[3]).m2();
+    output = -1./3./sh/th*(sh*sh+th*th+2.*uh*(sh+th+uh))*
+      4.*Constants::pi*SM().alphaEM()*
+      sqr(particles[1]->iCharge()/3.);
+  }
+  // HE result
+  else {
+    vector<SpinorBarWaveFunction>  ain;
+    vector<VectorWaveFunction> gin;
+    vector<SpinorWaveFunction> aout;
+    vector<VectorWaveFunction> vout;
+    VectorWaveFunction    glin (momenta[0],particles[0],incoming);
+    SpinorBarWaveFunction qbin (momenta[1],particles[1],incoming);
+    VectorWaveFunction    wout (momenta[2],particles[2],outgoing);
+    SpinorWaveFunction    qbout(momenta[3],particles[3],outgoing);
+    // polarization states for the particles
+    for(unsigned int ix=0;ix<2;++ix) {
+      qbin .reset(ix  );
+      ain .push_back(qbin );
+      qbout.reset(ix  );
+      aout.push_back(qbout);
+      glin.reset(2*ix);
+      gin.push_back(glin);
+      wout.reset(2*ix);
+      vout.push_back(wout);
+    }
+    // if calculation spin corrections construct the me
+    me_.reset(ProductionMatrixElement(PDT::Spin1,PDT::Spin1Half,
+				      PDT::Spin1,PDT::Spin1Half));
+    // compute the matrix elements
+    double me[3]={0.,0.,0.};
+    Complex diag[2];
+    SpinorWaveFunction inters;
+    SpinorBarWaveFunction interb;
+    for(unsigned int ihel1=0;ihel1<2;++ihel1) {
+      for(unsigned int ihel2=0;ihel2<2;++ihel2) {
+	for(unsigned int ohel1=0;ohel1<2;++ohel1) {
+	  // intermediates for the diagrams
+	  inters= FFGvertex_->evaluate(scale(),5,particles[3],
+				       aout[ohel1],gin[ihel1]);
+	  interb= FFGvertex_->evaluate(scale(),5,particles[1],
+				       ain[ihel2],gin[ihel1]);
+	  for(unsigned int vhel=0;vhel<2;++vhel) {
+	    diag[0]= FFPvertex_->evaluate(ZERO,inters,ain[ihel2],vout[vhel]);
+	    diag[1]= FFPvertex_->evaluate(ZERO,aout[ohel1],interb,vout[vhel]);
+	    // diagram contributions
+	    me[1] += norm(diag[0]);
+	    me[2] += norm(diag[1]);
+	    // total
+	    diag[0] += diag[1];
+	    me[0]   += norm(diag[0]);
+	    me_(2*ihel1,ihel2,2*vhel,ohel1) = diag[0];
+	  }
+	}
+      }
+    }
+    // results
+    // initial state spin and colour average
+    double colspin = 1./24./4.;
+    // and C_F N_c from matrix element
+    colspin *= 4.;
+    DVector save;
+    for(unsigned int ix=0;ix<3;++ix) {
+      me[ix] *= colspin;
+      if(ix>0) save.push_back(me[ix]);
+    }
+    meInfo(save);
+    output = me[0]/norm(FFGvertex_->norm());
+  }
+  return output;
+}  
+
+double MEPP2GammaGammaPowheg::loGammagME(const cPDVector & particles,
+					 const vector<Lorentz5Momentum> & momenta,
+					 bool first) const {
+  double output(0.);
+  // analytic formula for speed
+  if(!first) {
+    Energy2 uh = (momenta[0]-momenta[2]).m2();
+    Energy2 th = (momenta[0]-momenta[3]).m2();
+   output = 8./9.*double((th*th+uh*uh)/uh/th)*
+     4.*Constants::pi*SM().alphaEM(ZERO)*
+     sqr(particles[0]->iCharge()/3.);
+  }
+  else {
+    vector<SpinorWaveFunction>     fin;
+    vector<SpinorBarWaveFunction>  ain;
+    vector<VectorWaveFunction> gout;
+    vector<VectorWaveFunction> vout;
+    SpinorWaveFunction    qin (momenta[0],particles[0],incoming);
+    SpinorBarWaveFunction qbin(momenta[1],particles[1],incoming);
+    VectorWaveFunction    wout(momenta[2],particles[2],outgoing);
+    VectorWaveFunction   glout(momenta[3],particles[3],outgoing);
+    // polarization states for the particles
+    for(unsigned int ix=0;ix<2;++ix) {
+      qin.reset(ix)  ;
+      fin.push_back(qin);
+      qbin.reset(ix) ;
+      ain.push_back(qbin);
+      glout.reset(2*ix);
+      gout.push_back(glout);
+      wout.reset(2*ix);
+      vout.push_back(wout);
+    }
+    // if calculation spin corrections construct the me
+    if(first) me_.reset(ProductionMatrixElement(PDT::Spin1Half,PDT::Spin1Half,
+						PDT::Spin1,PDT::Spin1));
+    // compute the matrix elements
+    double me[3]={0.,0.,0.};
+    Complex diag[2];
+    SpinorWaveFunction inters;
+    SpinorBarWaveFunction interb;
+    for(unsigned int ihel1=0;ihel1<2;++ihel1) {
+      for(unsigned int ihel2=0;ihel2<2;++ihel2) {
+	for(unsigned int ohel1=0;ohel1<2;++ohel1) {
+	  // intermediates for the diagrams
+	  inters= FFGvertex_->evaluate(scale(),5,particles[0],
+				       fin[ihel1],gout[ohel1]);
+	  interb= FFGvertex_->evaluate(scale(),5,particles[1],
+				       ain[ihel2],gout[ohel1]);
+	  for(unsigned int vhel=0;vhel<2;++vhel) {
+	    diag[0]= FFPvertex_->evaluate(ZERO,fin[ihel1],interb,vout[vhel]);
+	    diag[1]= FFPvertex_->evaluate(ZERO,inters,ain[ihel2],vout[vhel]);
+	    // diagram contributions
+	    me[1] += norm(diag[0]);
+	    me[2] += norm(diag[1]);
+	    // total
+	    diag[0] += diag[1];
+	    me[0]   += norm(diag[0]);
+	    if(first) me_(ihel1,ihel2,vhel,2*ohel1) = diag[0];
+	  }
+	}
+      }
+    }
+    // results
+    // initial state spin and colour average
+    double colspin = 1./9./4.;
+    // and C_F N_c from matrix element
+    colspin *= 4.;
+    DVector save;
+    for(unsigned int ix=0;ix<3;++ix) {
+      me[ix] *= colspin;
+      if(ix>0) save.push_back(me[ix]);
+    }
+    meInfo(save);
+    output = me[0]/norm(FFGvertex_->norm());
+  }
+  return output;
+}
+
+InvEnergy2 MEPP2GammaGammaPowheg::
+realGammaGammagME(const cPDVector & particles,
+		  const vector<Lorentz5Momentum> & momenta,
+		  DipoleType dipole, RadiationType rad,
+		  bool ) const {
+  // matrix element
+  double sum = realME(particles,momenta);
+  // loop over the QCD and QCD dipoles
+  InvEnergy2 dipoles[2];
+  pair<double,double> supress[2];
+  // compute the two dipole terms
+  unsigned int iemit = 4, ihard = 3;
+  double x = (momenta[0]*momenta[1]-momenta[iemit]*momenta[1]-
+	      momenta[iemit]*momenta[0])/(momenta[0]*momenta[1]);
+  Lorentz5Momentum Kt = momenta[0]+momenta[1]-momenta[iemit];
+  vector<Lorentz5Momentum> pa(4),pb(4);
+  // momenta for q -> q g/gamma emission
+  pa[0] = x*momenta[0];
+  pa[1] =   momenta[1];
+  Lorentz5Momentum K = pa[0]+pa[1];
+  Lorentz5Momentum Ksum = K+Kt;
+  Energy2 K2 = K.m2();
+  Energy2 Ksum2 = Ksum.m2();
+  pa[2] = momenta[2]-2.*Ksum*(Ksum*momenta[2])/Ksum2+2*K*(Kt*momenta[2])/K2;
+  pa[2].setMass(momenta[2].mass());
+  pa[3] = momenta[ihard]
+    -2.*Ksum*(Ksum*momenta[ihard])/Ksum2+2*K*(Kt*momenta[ihard])/K2;
+  pa[3].setMass(ZERO);
+  cPDVector part(particles.begin(),--particles.end());
+  part[3] = particles[ihard];
+  // first leading-order matrix element
+  double lo1 = loGammaGammaME(part,pa);
+  // first dipole
+  dipoles[0] = 1./(momenta[0]*momenta[iemit])/x*(2./(1.-x)-(1.+x))*lo1;
+  supress[0] = supressionFunction(momenta[iemit].perp(),pa[3].perp());
+  // momenta for qbar -> qbar g/gamma emission
+  pb[0] =   momenta[0];
+  pb[1] = x*momenta[1];
+  K = pb[0]+pb[1];
+  Ksum = K+Kt;
+  K2 = K.m2();
+  Ksum2 = Ksum.m2();
+  pb[2] = momenta[2]-2.*Ksum*(Ksum*momenta[2])/Ksum2+2*K*(Kt*momenta[2])/K2;
+  pb[2].setMass(momenta[2].mass());
+  pb[3] = momenta[ihard]
+    -2.*Ksum*(Ksum*momenta[ihard])/Ksum2+2*K*(Kt*momenta[ihard])/K2;
+  pb[3].setMass(ZERO);
+  // second LO matrix element
+  double lo2 = loGammaGammaME(part,pb);
+  // second dipole
+  dipoles[1] = 1./(momenta[1]*momenta[iemit])/x*(2./(1.-x)-(1.+x))*lo2;
+  supress[1] = supressionFunction(momenta[iemit].perp(),pb[3].perp());
+  for(unsigned int ix=0;ix<2;++ix) dipoles[ix] *= 4./3.;
+  // denominator for the matrix element
+  InvEnergy2 denom = abs(dipoles[0]) + abs(dipoles[1]);
+  // contribution
+  if( denom==ZERO || dipoles[(dipole-1)/2]==ZERO ) return ZERO;
+  sum *= abs(dipoles[(dipole-1)/2])/denom;
+  // final coupling factors
+  InvEnergy2 output;
+  if(rad==Subtraction) {
+    output = alphaS_*alphaEM_*
+      (sum*UnitRemoval::InvE2*supress[(dipole-1)/2].first 
+       - dipoles[(dipole-1)/2]);
+  }
+  else {
+    output = alphaS_*alphaEM_*sum*UnitRemoval::InvE2;
+    if(rad==Hard)        output *=supress[(dipole-1)/2].second;
+    else if(rad==Shower) output *=supress[(dipole-1)/2].first ;
+  }
+  return output;
+}
+
+InvEnergy2 MEPP2GammaGammaPowheg::realGammaGammaqME(const cPDVector & particles,
+						const vector<Lorentz5Momentum> & momenta,
+						DipoleType dipole, RadiationType rad,
+						bool ) const {
+  double sum = realME(particles,momenta);
+  // initial-state QCD dipole
+  double x = (momenta[0]*momenta[1]-momenta[4]*momenta[1]-
+	      momenta[4]*momenta[0])/(momenta[0]*momenta[1]);
+  Lorentz5Momentum Kt = momenta[0]+momenta[1]-momenta[4];
+  vector<Lorentz5Momentum> pa(4);
+  pa[0] =   momenta[0];
+  pa[1] = x*momenta[1];
+  Lorentz5Momentum K = pa[0]+pa[1];
+  Lorentz5Momentum Ksum = K+Kt;
+  Energy2 K2 = K.m2();
+  Energy2 Ksum2 = Ksum.m2();
+  pa[2] = momenta[2]-2.*Ksum*(Ksum*momenta[2])/Ksum2+2*K*(Kt*momenta[2])/K2;
+  pa[2].setMass(momenta[2].mass());
+  pa[3] = momenta[3]
+    -2.*Ksum*(Ksum*momenta[3])/Ksum2+2*K*(Kt*momenta[3])/K2;
+  pa[3].setMass(ZERO);
+  cPDVector part(particles.begin(),--particles.end());
+  part[1] = particles[4]->CC();
+  double lo1 = loGammaGammaME(part,pa);
+  InvEnergy2 D1 = 0.5/(momenta[1]*momenta[4])/x*(1.-2.*x*(1.-x))*lo1;
+  // initial-final QED dipole
+  vector<Lorentz5Momentum> pb(4);
+  x = 1.-(momenta[3]*momenta[4])/(momenta[4]*momenta[0]+momenta[0]*momenta[3]);
+  pb[3] = momenta[4]+momenta[3]-(1.-x)*momenta[0];
+  pb[0] = x*momenta[0];
+  pb[1] = momenta[1];
+  pb[2] = momenta[2];
+  double z = momenta[0]*momenta[3]/(momenta[0]*momenta[3]+momenta[0]*momenta[4]);
+  part[1] = particles[1];
+  part[3] = particles[4];
+  double lo2 = loGammaqME(part,pb);
+  Energy pT = sqrt(-(pb[0]-pb[3]).m2()*(1.-x)*(1.-z)*z/x);
+  InvEnergy2 DF = 1./(momenta[4]*momenta[3])/x*(1./(1.-x+z)-2.+z)*lo2;
+  InvEnergy2 DI = 1./(momenta[0]*momenta[3])/x*(1./(1.-x+z)-1.-x)*lo2;
+  DI *= sqr(double(particles[0]->iCharge())/3.);  
+  DF *= sqr(double(particles[0]->iCharge())/3.);
+  InvEnergy2 denom = abs(D1)+abs(DI)+abs(DF);
+  pair<double,double> supress;
+  InvEnergy2 term;
+  if     ( dipole == IFQED1 ) {
+    term  = DI;
+    supress = supressionFunction(pT,pb[3].perp());
+  }
+  else if( dipole == FIQED1 ) {
+    term  = DF;
+    supress = supressionFunction(pT,pb[3].perp());
+  }
+  else                        {
+    term  = D1;
+    supress = supressionFunction(momenta[4].perp(),pa[3].perp()); 
+  }
+  if( denom==ZERO || term == ZERO ) return ZERO;
+  sum *= abs(term)/denom;
+  // final coupling factors
+  InvEnergy2 output;
+  if(rad==Subtraction) {
+    output = alphaS_*alphaEM_*
+      (sum*UnitRemoval::InvE2*supress.first - term);
+  }
+  else {
+    output = alphaS_*alphaEM_*sum*UnitRemoval::InvE2;
+    if(rad==Hard)        output *= supress.second;
+    else if(rad==Shower) output *= supress.first ;
+  }
+  // final coupling factors
+  return output;
+}
+
+InvEnergy2 MEPP2GammaGammaPowheg::
+realGammaGammaqbarME(const cPDVector & particles,
+		     const vector<Lorentz5Momentum> & momenta,
+		     DipoleType dipole, RadiationType rad,
+		     bool) const {
+  double sum = realME(particles,momenta);
+  // initial-state QCD dipole
+  double x = (momenta[0]*momenta[1]-momenta[4]*momenta[1]-momenta[4]*momenta[0])/
+    (momenta[0]*momenta[1]);
+  Lorentz5Momentum Kt = momenta[0]+momenta[1]-momenta[4];
+  vector<Lorentz5Momentum> pa(4);
+  pa[0] = x*momenta[0];
+  pa[1] =   momenta[1];
+  Lorentz5Momentum K = pa[0]+pa[1];
+  Lorentz5Momentum Ksum = K+Kt;
+  Energy2 K2 = K.m2();
+  Energy2 Ksum2 = Ksum.m2();
+  pa[2] = momenta[2]-2.*Ksum*(Ksum*momenta[2])/Ksum2+2*K*(Kt*momenta[2])/K2;
+  pa[2].setMass(momenta[2].mass());
+  pa[3] = momenta[3]
+    -2.*Ksum*(Ksum*momenta[3])/Ksum2+2*K*(Kt*momenta[3])/K2;
+  pa[3].setMass(ZERO);
+  cPDVector part(particles.begin(),--particles.end());
+  part[0] = particles[4]->CC();
+  double lo1 = loGammaGammaME(part,pa);
+  InvEnergy2 D1 = 0.5/(momenta[0]*momenta[4])/x*(1.-2.*x*(1.-x))*lo1;
+  // initial-final QED dipole
+  vector<Lorentz5Momentum> pb(4);
+  x = 1.-(momenta[3]*momenta[4])/(momenta[4]*momenta[1]+momenta[1]*momenta[3]);
+  pb[3] = momenta[4]+momenta[3]-(1.-x)*momenta[1];
+  pb[0] = momenta[0];
+  pb[1] = x*momenta[1];
+  pb[2] = momenta[2];
+  double z = momenta[1]*momenta[3]/(momenta[1]*momenta[3]+momenta[1]*momenta[4]);
+  part[0] = particles[0];
+  part[3] = particles[4];
+  double lo2 = loGammaqbarME(part,pb);
+  Energy pT = sqrt(-(pb[1]-pb[3]).m2()*(1.-x)*(1.-z)*z/x);
+  InvEnergy2 DF = 1./(momenta[4]*momenta[3])/x*(2./(1.-x+z)-2.+z)*lo2;
+  InvEnergy2 DI = 1./(momenta[0]*momenta[3])/x*(2./(1.-x+z)-1.-x)*lo2;
+  InvEnergy2 term;
+  DI *= sqr(double(particles[1]->iCharge())/3.);
+  DF *= sqr(double(particles[1]->iCharge())/3.);
+  InvEnergy2 denom = abs(D1)+abs(DI)+abs(DF);
+  pair<double,double> supress;
+  if     ( dipole == IFQED2 ) {
+    term  = DI;
+    supress = supressionFunction(pT,pb[3].perp());
+  }
+  else if( dipole == FIQED2 ) {
+    term  = DF;
+    supress = supressionFunction(pT,pb[3].perp());
+  }
+  else                        {
+    term  = D1;
+    supress = supressionFunction(momenta[4].perp(),pa[3].perp()); 
+  }
+  if( denom==ZERO || dipole==ZERO ) return ZERO;
+  sum *= abs(term)/denom;
+  // final coupling factors
+  InvEnergy2 output;
+  if(rad==Subtraction) {
+    output = alphaS_*alphaEM_*
+      (sum*UnitRemoval::InvE2*supress.first - term);
+  }
+  else {
+    output = alphaS_*alphaEM_*sum*UnitRemoval::InvE2;
+    if(rad==Hard)        output *= supress.second;
+    else if(rad==Shower) output *= supress.first ;
+  }
+  // final coupling factors
+  return output;
+}
+
+double MEPP2GammaGammaPowheg::
+realME(const cPDVector & particles,
+       const vector<Lorentz5Momentum> & momenta) const {
+  vector<SpinorWaveFunction> qin;
+  vector<SpinorBarWaveFunction> qbarin;
+  vector<VectorWaveFunction> wout,pout,gout;
+  SpinorWaveFunction    q_in;  
+  SpinorBarWaveFunction qbar_in;
+  VectorWaveFunction    g_out;  
+  VectorWaveFunction    v_out  (momenta[2],particles[2],outgoing);
+  VectorWaveFunction    p_out  (momenta[3],particles[3],outgoing);
+  // q qbar -> gamma gamma g
+  if(particles[4]->id()==ParticleID::g) {
+    q_in    = SpinorWaveFunction    (momenta[0],particles[0],incoming);
+    qbar_in = SpinorBarWaveFunction (momenta[1],particles[1],incoming);
+    g_out   = VectorWaveFunction    (momenta[4],particles[4],outgoing);
+  }
+  // q g -> gamma gamma q
+  else if(particles[4]->id()>0) {
+    q_in    = SpinorWaveFunction    (momenta[0],particles[0],incoming);
+    qbar_in = SpinorBarWaveFunction (momenta[4],particles[4],outgoing);
+    g_out   = VectorWaveFunction    (momenta[1],particles[1],incoming);
+  }
+  else if(particles[4]->id()<0) {
+    q_in    = SpinorWaveFunction    (momenta[4],particles[4],outgoing);
+    qbar_in = SpinorBarWaveFunction (momenta[1],particles[1],incoming);
+    g_out   = VectorWaveFunction    (momenta[0],particles[0],incoming);
+  }
+  else assert(false);
+  for(unsigned int ix=0;ix<2;++ix) {
+    q_in.reset(ix);
+    qin.push_back(q_in);
+    qbar_in.reset(ix);
+    qbarin.push_back(qbar_in);
+    g_out.reset(2*ix);
+    gout.push_back(g_out);
+    p_out.reset(2*ix);
+    pout.push_back(p_out);
+    v_out.reset(2*ix);
+    wout.push_back(v_out);
+  }
+  vector<Complex> diag(6 , 0.);
+  Energy2 mu2 = scale();
+  double sum(0.);
+  for(unsigned int ihel1=0;ihel1<2;++ihel1) {
+    for(unsigned int ihel2=0;ihel2<2;++ihel2) {
+      for(unsigned int whel=0;whel<2;++whel) {
+	for(unsigned int phel=0;phel<2;++phel) {
+	  for(unsigned int ghel=0;ghel<2;++ghel) {
+	    // first diagram
+	    SpinorWaveFunction inters1 = 
+	      FFPvertex_->evaluate(ZERO,5,qin[ihel1].particle(),qin[ihel1],pout[phel]);
+	    SpinorBarWaveFunction inters2 = 
+	      FFPvertex_->evaluate(ZERO,5,qin[ihel1].particle()->CC(),
+			       qbarin[ihel2],wout[whel]);
+	    diag[0] = FFGvertex_->evaluate(mu2,inters1,inters2,gout[ghel]);
+	    // second diagram
+	    SpinorWaveFunction inters3 = 
+	      FFGvertex_->evaluate(mu2,5,qin[ihel1].particle(),qin[ihel1],gout[ghel]);
+	    SpinorBarWaveFunction inters4 = 
+	      FFPvertex_->evaluate(ZERO,5,qbarin[ihel2].particle(),
+				   qbarin[ihel2],pout[phel]);
+	    diag[1] = FFPvertex_->evaluate(ZERO,inters3,inters4,wout[whel]);
+	    // fourth diagram
+	    diag[2] = FFPvertex_->evaluate(ZERO,inters3,inters2,pout[phel]);
+	    // fifth diagram
+	    SpinorBarWaveFunction inters5 = 
+	      FFGvertex_->evaluate(mu2,5,qbarin[ihel2].particle(),
+				   qbarin[ihel2],gout[ghel]);
+	    diag[3] = 
+	      FFPvertex_->evaluate(ZERO,inters1,inters5,wout[whel]);
+	    // sixth diagram
+	    SpinorWaveFunction inters6 = 
+	      FFPvertex_->evaluate(ZERO,5,qbarin[ihel2].particle()->CC(),
+			       qin[ihel1],wout[whel]);
+	    diag[4] = FFGvertex_->evaluate(mu2,inters6,inters4,gout[ghel]);
+	    // eighth diagram
+	    diag[5] = FFPvertex_->evaluate(ZERO,inters6,inters5,pout[phel]);
+	    // sum
+	    Complex dsum = std::accumulate(diag.begin(),diag.end(),Complex(0.));
+	    sum += norm(dsum);
+	  }
+	}
+      }
+    }
+  }
+  // divide out the em and strong couplings
+  sum /= norm(FFGvertex_->norm()*FFPvertex_->norm());
+  // final spin and colour factors spin = 1/4 colour = 4/9
+  if(particles[4]->id()==ParticleID::g) sum /= 9.;
+  // final spin and colour factors spin = 1/4 colour = 4/(3*8)
+  else                                  sum /= 24.;
+  // finally identical particle factor
+  return 0.5*sum;
+}
+
+double MEPP2GammaGammaPowheg::subtractedVirtual() const {
+  double v = 1+tHat()/sHat();
+  double born = (1-v)/v+v/(1-v);
+  double finite_term = born*
+    (2./3.*sqr(Constants::pi)-3.+sqr(log(v))+sqr(log(1-v))+3.*log(1-v))+
+    2.+2.*log(v)+2.*log(1-v)+3.*(1-v)/v*(log(v)-log(1-v))+
+    (2.+v/(1-v))*sqr(log(v))+(2.+(1-v)/v)*sqr(log(1-v));
+
+  double virt = ((6.-(2./3.)*sqr(Constants::pi))*
+		 born-2.+finite_term);
+
+    return virt/born;
+}
+
+double MEPP2GammaGammaPowheg::subtractedReal(pair<double,double> x, double z,
+					     double zJac, double oldqPDF, double newqPDF,
+					     double newgPDF,bool order) const {
+  double vt   = vTilde_*(1.-z);
+  double vJac = 1.-z;
+  Energy pT   = sqrt(sHat()*vt*(1.-vt-z)/z);
+  // rapidities
+  double rapidity;
+  if(order) {
+    rapidity = -log(x.second*sqrt(lastS())/pT*vt);
+  }
+  else {
+    rapidity =  log(x.first *sqrt(lastS())/pT*vt);
+  }
+  // CMS system
+  Energy rs=sqrt(lastS());
+  Lorentz5Momentum pcmf = Lorentz5Momentum(ZERO,ZERO,0.5*rs*(x.first-x.second),
+					   0.5*rs*(x.first+x.second));
+  pcmf.rescaleMass();
+  Boost blab(pcmf.boostVector());
+  // emission from the quark radiation
+  vector<Lorentz5Momentum> pnew(5);
+  if(order) {
+    pnew [0] = Lorentz5Momentum(ZERO,ZERO,0.5*rs*x.first/z,
+				0.5*rs*x.first/z,ZERO);
+    pnew [1] = Lorentz5Momentum(ZERO,ZERO,-0.5*rs*x.second,
+				0.5*rs*x.second,ZERO) ;
+  }
+  else {
+    pnew[0] = Lorentz5Momentum(ZERO,ZERO,0.5*rs*x.first,
+			       0.5*rs*x.first,ZERO);
+    pnew[1] = Lorentz5Momentum(ZERO,ZERO,-0.5*rs*x.second/z,
+			       0.5*rs*x.second/z,ZERO) ;
+  }
+  pnew [2] = meMomenta()[2];
+  pnew [3] = meMomenta()[3];
+  pnew [4] = Lorentz5Momentum(pT*cos(phi_),pT*sin(phi_),
+			      pT*sinh(rapidity),
+			      pT*cosh(rapidity), ZERO);
+  Lorentz5Momentum K  = pnew [0]+pnew [1]-pnew [4];
+  Lorentz5Momentum Kt = pcmf;
+  Lorentz5Momentum Ksum = K+Kt;
+  Energy2 K2 = K.m2();
+  Energy2 Ksum2 = Ksum.m2();
+  for(unsigned int ix=2;ix<4;++ix) {
+    pnew [ix].boost(blab);
+    pnew [ix] = pnew [ix] - 2.*Ksum*(Ksum*pnew [ix])/Ksum2
+      +2*K*(Kt*pnew [ix])/K2;
+  }
+  // phase-space prefactors
+  double phase = zJac*vJac/z;
+  // real emission q qbar
+  vector<double> output(4,0.);
+  double realQQ(0.),realGQ(0.);
+  if(!(zTilde_<1e-7 || vt<1e-7 || 1.-z-vt < 1e-7 )) {
+    cPDVector particles(mePartonData());
+    particles.push_back(gluon_);
+    // calculate the full 2->3 matrix element
+    realQQ = sHat()*phase*newqPDF/oldqPDF*
+      realGammaGammagME(particles,pnew,order ? IIQCD1 : IIQCD2,Subtraction,false);
+    if(order) {
+      particles[0] = gluon_;
+      particles[4] = mePartonData()[0]->CC();
+      realGQ = sHat()*phase*newgPDF/oldqPDF*
+	realGammaGammaqbarME(particles,pnew,IIQCD2,Subtraction,false);
+    }
+    else {
+      particles[1] = gluon_;
+      particles[4] = mePartonData()[1]->CC();
+      realGQ = sHat()*phase*newgPDF/oldqPDF*
+	realGammaGammaqME   (particles,pnew,IIQCD1,Subtraction,false);
+    }
+  }
+  // return the answer
+  return realQQ+realGQ;
+}
+
+double MEPP2GammaGammaPowheg::collinearQuark(double x, Energy2 mu2, double jac, double z,
+					     double oldPDF, double newPDF) const {
+  if(1.-z < 1.e-8) return 0.;
+  return CFfact_*(
+		  // this bit is multiplied by LO PDF
+		  sqr(Constants::pi)/3.-5.+2.*sqr(log(1.-x ))
+		  +(1.5+2.*log(1.-x ))*log(sHat()/mu2)
+		  // NLO PDF bit
+		  +jac /z * newPDF /oldPDF *
+		  (1.-z -(1.+z )*log(sqr(1.-z )/z )
+		   -(1.+z )*log(sHat()/mu2)-2.*log(z )/(1.-z ))
+		  // + function bit
+		  +jac /z *(newPDF /oldPDF -z )*
+		  2./(1.-z )*log(sHat()*sqr(1.-z )/mu2));
+}
+
+double MEPP2GammaGammaPowheg::collinearGluon(Energy2 mu2, double jac, double z,
+					     double oldPDF, double newPDF) const {
+  if(1.-z < 1.e-8) return 0.;
+  return TRfact_*jac/z*newPDF/oldPDF*
+    ((sqr(z)+sqr(1.-z))*log(sqr(1.-z)*sHat()/z/mu2)
+     +2.*z*(1.-z));
+}
+
+void MEPP2GammaGammaPowheg::doinit() {
+  HwMEBase::doinit();
+  vector<unsigned int> mopt(2,1);
+  massOption(mopt);
+  // get the vertices we need
+  // get a pointer to the standard model object in the run
+  static const tcHwSMPtr hwsm
+    = dynamic_ptr_cast<tcHwSMPtr>(standardModel());
+  if (!hwsm) throw InitException() << "hwsm pointer is null in"
+				   << " MEPP2GammaGamma::doinit()"
+				   << Exception::abortnow;
+  // get pointers to all required Vertex objects
+  FFPvertex_ = hwsm->vertexFFP();
+  FFGvertex_ = hwsm->vertexFFG();
+  gluon_ = getParticleData(ParticleID::g);
+  // sampling factors
+  prefactor_.push_back(preQCDqqbarq_);
+  prefactor_.push_back(preQCDqqbarqbar_);
+  prefactor_.push_back(preQCDqg_);
+  prefactor_.push_back(preQCDgqbar_);
+  prefactor_.push_back(preQEDqqbarq_);
+  prefactor_.push_back(preQEDqqbarqbar_);
+  prefactor_.push_back(preQEDqgq_);
+  prefactor_.push_back(preQEDgqbarqbar_);
+}
+
+HardTreePtr MEPP2GammaGammaPowheg::
+generateHardest(ShowerTreePtr tree,
+		vector<ShowerInteraction::Type> interactions) {
+  beams_.clear();
+  partons_.clear();
+  bool QCDAllowed(false),QEDAllowed(false);
+  for(unsigned int ix=0;ix<interactions.size();++ix) {
+    if(interactions[ix]==ShowerInteraction::QED)
+      QEDAllowed = true;
+    else if(interactions[ix]==ShowerInteraction::QCD)
+      QCDAllowed = true;
+    else if(interactions[ix]==ShowerInteraction::Both) {
+      QEDAllowed = true;
+      QCDAllowed = true;
+    }
+  }
+  // find the incoming particles
+  ShowerParticleVector incoming;
+  // get the particles to be showered
+  map<ShowerProgenitorPtr,ShowerParticlePtr>::const_iterator cit;
+  vector<ShowerProgenitorPtr> particlesToShower;
+  //progenitor particles are produced in z direction.
+  for( cit = tree->incomingLines().begin();
+       cit != tree->incomingLines().end(); ++cit ) {
+    incoming.push_back( cit->first->progenitor() );
+    beams_.push_back( cit->first->beam() );
+    partons_.push_back( cit->first->progenitor()->dataPtr() );
+    particlesToShower.push_back( cit->first );
+  }
+  // find the parton which should be first
+  if( ( particlesToShower[1]->progenitor()->id() > 0 &&
+        particlesToShower[0]->progenitor()->id() < 0 ) || 
+      ( particlesToShower[0]->progenitor()->id() == ParticleID::g &&
+	particlesToShower[1]->progenitor()->id() < 6 && 
+	particlesToShower[1]->progenitor()->id() > 0 ) )
+    swap(particlesToShower[0],particlesToShower[1]);
+  // check that quark is along +ve z direction
+  quarkplus_ = particlesToShower[0]->progenitor()->momentum().z() > ZERO;
+  if( partons_[0]->id() < 0 || 
+      (partons_[0]->id()==ParticleID::g && partons_[1]->id()>0)) {
+    swap(partons_[0],partons_[1]);
+    swap(beams_  [0],beams_  [1]);
+  }
+  // outgoing partons
+  for( map<ShowerProgenitorPtr,tShowerParticlePtr>::const_iterator 
+	 cjt= tree->outgoingLines().begin();
+       cjt != tree->outgoingLines().end();++cjt ) {
+    particlesToShower.push_back( cjt->first );
+  }
+  if(particlesToShower.size()!=4) return HardTreePtr();
+  if(particlesToShower[2]->id()!=ParticleID::gamma)
+    swap(particlesToShower[2],particlesToShower[3]);
+  if(particlesToShower[3]->progenitor()->id()==ParticleID::gamma) {
+    if(QCDAllowed) return hardQCDEmission(particlesToShower);
+  }
+  else {
+    if(QEDAllowed) return hardQEDEmission(particlesToShower);
+  }
+  return HardTreePtr();
+}
+
+HardTreePtr MEPP2GammaGammaPowheg::
+hardQCDEmission(vector<ShowerProgenitorPtr> particlesToShower) {
+  Energy rootS = sqrt(lastS());
+  // limits on the rapidity of the jet
+  double minyj = -8.0,maxyj = 8.0;
+  // generate the hard emission
+  pair<double,double> x = make_pair(particlesToShower[0]->progenitor()->x(),
+				    particlesToShower[1]->progenitor()->x());
+  vector<Energy> pT;
+  Energy pTmax(-GeV);
+  cPDVector selectedParticles;
+  vector<Lorentz5Momentum> selectedMomenta;
+  int iemit(-1);
+  for(unsigned int ix=0;ix<4;++ix) {
+    pT.push_back(0.5*generator()->maximumCMEnergy());
+    double a = alphaQCD_->overestimateValue()/Constants::twopi*
+      prefactor_[ix]*(maxyj-minyj);
+    cPDVector particles;
+    for(unsigned int iy=0;iy<particlesToShower.size();++iy) 
+      particles.push_back(particlesToShower[iy]->progenitor()->dataPtr());
+    if(ix<2) particles.push_back(gluon_);
+    else if(ix==2) {
+      particles.push_back(particles[0]->CC());
+      particles[0] = gluon_;
+    }
+    else {
+      particles.push_back(particles[1]->CC());
+      particles[1] = gluon_;
+    }
+    vector<Lorentz5Momentum> momenta(5);
+    do {
+      pT[ix] *= pow(UseRandom::rnd(),1./a);
+      double y = UseRandom::rnd()*(maxyj-minyj)+ minyj;
+      double vt,z;
+      if(ix%2==0) {
+	vt = pT[ix]*exp(-y)/rootS/x.second;
+	z  = (1.-pT[ix]*exp(-y)/rootS/x.second)/(1.+pT[ix]*exp( y)/rootS/x.first );
+	if(z>1.||z<x.first) continue;
+      }
+      else {
+	vt = pT[ix]*exp( y)/rootS/x.first ;
+	z  = (1.-pT[ix]*exp( y)/rootS/x.first )/(1.+pT[ix]*exp(-y)/rootS/x.second );
+	if(z>1.||z<x.second) continue;
+      }
+      if(vt>1.-z || vt<0.) continue;
+      if(ix%2==0) {
+	momenta[0] = particlesToShower[0]->progenitor()->momentum()/z;
+	momenta[1] = particlesToShower[1]->progenitor()->momentum();
+      }
+      else {
+	momenta[0] = particlesToShower[0]->progenitor()->momentum();
+	momenta[1] = particlesToShower[1]->progenitor()->momentum()/z;
+      }
+      double phi = Constants::twopi*UseRandom::rnd();
+      momenta[2] = particlesToShower[2]->progenitor()->momentum();
+      momenta[3] = particlesToShower[3]->progenitor()->momentum();
+      if(!quarkplus_) y *= -1.;
+      momenta[4] = Lorentz5Momentum(pT[ix]*cos(phi),pT[ix]*sin(phi),
+				    pT[ix]*sinh(y),pT[ix]*cosh(y), ZERO);
+      Lorentz5Momentum K = momenta[0] + momenta[1] - momenta[4]; 
+      Lorentz5Momentum Kt = momenta[2]+momenta[3];
+      Lorentz5Momentum Ksum = K+Kt;
+      Energy2 K2 = K.m2(), Ksum2 = Ksum.m2();
+      for(unsigned int iy=2;iy<4;++iy) {
+	momenta [iy] = momenta [iy] - 2.*Ksum*(Ksum*momenta [iy])/Ksum2
+	  +2*K*(Kt*momenta [iy])/K2;
+      }
+      // matrix element piece
+      double wgt = alphaQCD_->ratio(sqr(pT[ix]))*z/(1.-vt)/prefactor_[ix]/loME_;
+      if(ix==0)
+	wgt *= sqr(pT[ix])*realGammaGammagME(particles,momenta,IIQCD1,Shower,false);
+      else if(ix==1)
+	wgt *= sqr(pT[ix])*realGammaGammagME(particles,momenta,IIQCD2,Shower,false);
+      else if(ix==2)
+	wgt *= sqr(pT[ix])*realGammaGammaqbarME(particles,momenta,IIQCD1,Shower,false);
+      else if(ix==3)
+	wgt *= sqr(pT[ix])*realGammaGammaqME(particles,momenta,IIQCD2,Shower,false);
+      wgt *= 4.*Constants::pi/alphaS_;
+      // pdf piece
+      double pdf[2];
+      if(ix%2==0) {
+	pdf[0] = beams_[0]->pdf()->xfx(beams_[0],partons_ [0],
+				       scale(),            x.first   )  /x.first;
+	pdf[1] = beams_[0]->pdf()->xfx(beams_[0],particles[0],
+				       scale()+sqr(pT[ix]),x.first /z)*z/x.first;
+      }
+      else {
+	pdf[0] = beams_[1]->pdf()->xfx(beams_[1],partons_ [1],
+				       scale()            ,x.second  )  /x.second;
+	pdf[1] = beams_[1]->pdf()->xfx(beams_[1],particles[1],
+				       scale()+sqr(pT[ix]),x.second/z)*z/x.second;
+      }
+      if(pdf[0]<=0.||pdf[1]<=0.) continue;
+      wgt *= pdf[1]/pdf[0];
+      if(wgt>1.) generator()->log() << "Weight greater than one in "
+				    << "MEPP2GammaGammaPowheg::hardQCDEmission() "
+				    << "for channel " << ix 
+				    << " Weight = " << wgt << "\n";
+      if(UseRandom::rnd()<wgt) break;
+    }
+    while(pT[ix]>minpT_);
+    if(pT[ix]>minpT_ && pT[ix]>pTmax) {
+      pTmax = pT[ix];
+      selectedParticles = particles;
+      selectedMomenta = momenta;
+      iemit=ix;
+    }
+  }
+  // if no emission
+  if(pTmax<ZERO) {
+    for(unsigned int ix=0;ix<particlesToShower.size();++ix)
+      particlesToShower[ix]->maximumpT(minpT_,ShowerInteraction::QCD);
+    return HardTreePtr();
+  }
+  // construct the HardTree object needed to perform the showers
+  // create the partons
+  ShowerParticleVector newparticles;
+  newparticles.push_back(new_ptr(ShowerParticle(selectedParticles[0],false)));
+  newparticles.push_back(new_ptr(ShowerParticle(selectedParticles[1],false)));
+  newparticles.push_back(new_ptr(ShowerParticle(selectedParticles[4], true)));
+  // set the momenta
+  for(unsigned int ix=0;ix<2;++ix) 
+    newparticles[ix]->set5Momentum(selectedMomenta[ix]);
+  newparticles[2]->set5Momentum(selectedMomenta[4]);
+  // create the off-shell particle
+  Lorentz5Momentum poff = selectedMomenta[iemit%2] - selectedMomenta[4];
+  poff.rescaleMass();
+  newparticles.push_back(new_ptr(ShowerParticle(partons_[iemit%2],false)));
+  newparticles.back()->set5Momentum(poff);
+  for(unsigned int ix=2;ix<particlesToShower.size();++ix) {
+    newparticles.push_back(new_ptr(ShowerParticle(particlesToShower[ix]->
+						  progenitor()->dataPtr(),true)));
+    newparticles.back()->set5Momentum(selectedMomenta[ix]);
+  }
+  vector<HardBranchingPtr> inBranch,hardBranch;
+  // create the branchings for the incoming particles
+  inBranch.push_back(new_ptr(HardBranching(newparticles[0],SudakovPtr(),
+					  HardBranchingPtr(),HardBranching::Incoming)));
+  inBranch.push_back(new_ptr(HardBranching(newparticles[1],SudakovPtr(),
+					  HardBranchingPtr(),HardBranching::Incoming)));
+  // intermediate IS particle
+  hardBranch.push_back(new_ptr(HardBranching(newparticles[3],SudakovPtr(),
+					     inBranch[iemit%2],HardBranching::Incoming)));
+  inBranch[iemit%2]->addChild(hardBranch.back());
+  if(newparticles[3]->id()>0)
+    inBranch[iemit%2]->type(ShowerPartnerType::QCDColourLine    );
+  else
+    inBranch[iemit%2]->type(ShowerPartnerType::QCDAntiColourLine);
+  // create the branching for the emitted jet
+  inBranch[iemit%2]->addChild(new_ptr(HardBranching(newparticles[2],SudakovPtr(),
+						   inBranch[iemit%2],
+						   HardBranching::Outgoing)));
+  // set the colour partners
+  hardBranch.back()->colourPartner(inBranch[iemit%2==0 ? 1 : 0]);
+  inBranch[iemit%2==0 ? 1 : 0]->colourPartner(hardBranch.back());
+  // add other particle
+  hardBranch.push_back(inBranch[iemit%2==0 ? 1 : 0]);
+  // outgoing particles
+  for(unsigned int ix=4;ix<newparticles.size();++ix) {
+    hardBranch.push_back(new_ptr(HardBranching(newparticles[ix],SudakovPtr(),
+					      HardBranchingPtr(),
+					      HardBranching::Outgoing)));
+  }
+  // make the tree
+  HardTreePtr hardtree=new_ptr(HardTree(hardBranch,inBranch,ShowerInteraction::QCD));
+  // connect the ShowerParticles with the branchings
+  // and set the maximum pt for the radiation
+  set<HardBranchingPtr> hard=hardtree->branchings();
+  for(unsigned int ix=0;ix<particlesToShower.size();++ix) {
+    particlesToShower[ix]->maximumpT(pTmax,ShowerInteraction::QCD);
+    for(set<HardBranchingPtr>::const_iterator mit=hard.begin();
+	mit!=hard.end();++mit) {
+      if(particlesToShower[ix]->progenitor()->id()==(*mit)->branchingParticle()->id()&&
+	 (( particlesToShower[ix]->progenitor()->isFinalState()&&
+	    (**mit).status()==HardBranching::Outgoing)||
+	  (!particlesToShower[ix]->progenitor()->isFinalState()&&
+	   (**mit).status()==HardBranching::Incoming))) {
+	hardtree->connect(particlesToShower[ix]->progenitor(),*mit);
+	if((**mit).status()==HardBranching::Incoming) {
+	  (*mit)->beam(particlesToShower[ix]->original()->parents()[0]);
+	}
+	HardBranchingPtr parent=(*mit)->parent();
+	while(parent) {
+	  parent->beam(particlesToShower[ix]->original()->parents()[0]);
+	  parent=parent->parent();
+	};
+      }
+    }
+  }
+  ColinePtr newline=new_ptr(ColourLine());
+  for(set<HardBranchingPtr>::const_iterator cit=hardtree->branchings().begin();
+      cit!=hardtree->branchings().end();++cit) {
+    if((**cit).branchingParticle()->dataPtr()->iColour()==PDT::Colour3)
+      newline->addColoured((**cit).branchingParticle());
+    else if((**cit).branchingParticle()->dataPtr()->iColour()==PDT::Colour3bar)
+      newline->addAntiColoured((**cit).branchingParticle());
+  }
+  // return the tree
+  return hardtree;
+}
+
+HardTreePtr MEPP2GammaGammaPowheg::
+hardQEDEmission(vector<ShowerProgenitorPtr> particlesToShower) {
+  // return if not emission from quark
+  if(particlesToShower[0]->progenitor()->id()!=ParticleID::g &&
+     particlesToShower[1]->progenitor()->id()!=ParticleID::g )
+    return HardTreePtr();
+  // generate the hard emission
+  pair<double,double> x = make_pair(particlesToShower[0]->progenitor()->x(),
+				    particlesToShower[1]->progenitor()->x());
+  vector<Energy> pT;
+  Energy pTmax(-GeV);
+  cPDVector selectedParticles;
+  vector<Lorentz5Momentum> selectedMomenta;
+  int iemit(-1);
+  pair<double,double> mewgt(make_pair(0.,0.));
+  for(unsigned int ix=0;ix<particlesToShower.size();++ix) {
+    selectedParticles.push_back(particlesToShower[ix]->progenitor()->dataPtr());
+    selectedMomenta.push_back(particlesToShower[ix]->progenitor()->momentum());
+  }
+  selectedParticles.push_back(getParticleData(ParticleID::gamma));
+  swap(selectedParticles[3],selectedParticles[4]);
+  selectedMomenta.push_back(Lorentz5Momentum());
+  swap(selectedMomenta[3],selectedMomenta[4]);
+  Lorentz5Momentum pin,pout;
+  double xB;
+  unsigned int iloc;
+  if(particlesToShower[0]->progenitor()->dataPtr()->charged()) {
+    pin = particlesToShower[0]->progenitor()->momentum();
+    xB = x.first;
+    iloc = 6;
+  }
+  else {
+    pin = particlesToShower[1]->progenitor()->momentum();
+    xB = x.second;
+    iloc = 7;
+  }
+  pout = particlesToShower[3]->progenitor()->momentum();
+  Lorentz5Momentum q = pout-pin;
+  Axis axis(q.vect().unit());
+  LorentzRotation rot;
+  double sinth(sqrt(sqr(axis.x())+sqr(axis.y())));
+  rot = LorentzRotation();
+  if(axis.perp2()>1e-20) {
+    rot.setRotate(-acos(axis.z()),Axis(-axis.y()/sinth,axis.x()/sinth,0.));
+    rot.rotateX(Constants::pi);
+  }
+  if(abs(1.-q.e()/q.vect().mag())>1e-6) 
+    rot.boostZ(q.e()/q.vect().mag());
+  Lorentz5Momentum ptemp = rot*pin;
+  if(ptemp.perp2()/GeV2>1e-20) {
+    Boost trans = -1./ptemp.e()*ptemp.vect();
+    trans.setZ(0.);
+    rot.boost(trans);
+  }
+  rot.invert();
+  Energy Q = sqrt(-q.m2());
+  double xT = sqrt((1.-xB)/xB);
+  double xTMin = 2.*minpT_/Q;
+  double wgt(0.);
+  double a = alphaQED_->overestimateValue()*prefactor_[iloc]/Constants::twopi;
+  Lorentz5Momentum p1,p2,p3;
+  do {
+    wgt = 0.;
+    // intergration variables dxT/xT^3
+    xT *= 1./sqrt(1.-2.*log(UseRandom::rnd())/a*sqr(xT));
+    // dz
+    double zp = UseRandom::rnd();
+    double xp = 1./(1.+0.25*sqr(xT)/zp/(1.-zp));
+    if(xT<xTMin) break;
+    // check allowed
+    if(xp<xB||xp>1.) continue;
+    // phase-space piece of the weight
+    wgt = 4.*sqr(1.-xp)*(1.-zp)*zp/prefactor_[iloc]/loME_;
+    // coupling
+    Energy2 pT2 = 0.25*sqr(Q*xT);
+    wgt *= alphaQED_->ratio(pT2);
+    // matrix element
+    wgt *= 4.*Constants::pi/alphaEM_;
+    // PDF
+    double pdf[2];
+    if(iloc==6) {
+      pdf[0] = beams_[0]->pdf()->
+	xfx(beams_[0],partons_[0],scale()    ,x.first    );
+      pdf[1] = beams_[0]->pdf()->
+	xfx(beams_[0],partons_[0],scale()+pT2,x.first /xp);
+    }
+    else {
+      pdf[0] = beams_[1]->pdf()->
+	xfx(beams_[1],partons_[1],scale()    ,x.second   );
+      pdf[1] = beams_[1]->pdf()->
+	xfx(beams_[1],partons_[1],scale()+pT2,x.second/xp);
+    }
+    if(pdf[0]<=0.||pdf[1]<=0.) {
+      wgt = 0.;
+      continue;
+    }
+    wgt *= pdf[1]/pdf[0];
+    // matrix element piece
+    double phi = Constants::twopi*UseRandom::rnd();
+    double x2 = 1.-(1.-zp)/xp;
+    double x3 = 2.-1./xp-x2;
+    p1=Lorentz5Momentum(ZERO,ZERO,0.5*Q/xp,0.5*Q/xp,ZERO);
+    p2=Lorentz5Momentum( 0.5*Q*xT*cos(phi), 0.5*Q*xT*sin(phi),
+			 -0.5*Q*x2,0.5*Q*sqrt(sqr(xT)+sqr(x2)));
+    p3=Lorentz5Momentum(-0.5*Q*xT*cos(phi),-0.5*Q*xT*sin(phi),
+			-0.5*Q*x3,0.5*Q*sqrt(sqr(xT)+sqr(x3)));
+    selectedMomenta[iloc-6] = rot*p1;
+    selectedMomenta[3] = rot*p3;
+    selectedMomenta[4] = rot*p2;
+    if(iloc==6) {
+      mewgt.first  = 
+	sqr(Q)*realGammaGammaqME(selectedParticles,selectedMomenta,IFQED1,Shower,false);
+      mewgt.second = 
+	sqr(Q)*realGammaGammaqME(selectedParticles,selectedMomenta,FIQED1,Shower,false);
+      wgt *= mewgt.first+mewgt.second;
+    }
+    else {
+      mewgt.first  = 
+	sqr(Q)*realGammaGammaqbarME(selectedParticles,selectedMomenta,IFQED2,Shower,false);
+      mewgt.second = 
+	sqr(Q)*realGammaGammaqbarME(selectedParticles,selectedMomenta,FIQED2,Shower,false); 
+      wgt *= mewgt.first+mewgt.second;
+    }
+    if(wgt>1.) generator()->log() << "Weight greater than one in "
+				  << "MEPP2GammaGammaPowheg::hardQEDEmission() "
+				  << "for IF channel "
+				  << " Weight = " << wgt << "\n";
+  }
+  while(xT>xTMin&&UseRandom::rnd()>wgt);
+  // if no emission
+  if(xT<xTMin) {
+    for(unsigned int ix=0;ix<particlesToShower.size();++ix)
+      particlesToShower[ix]->maximumpT(minpT_,ShowerInteraction::QED);
+    return HardTreePtr();
+  }
+  pTmax = 0.5*xT*Q;
+  iemit = mewgt.first>mewgt.second ? 2 : 3;
+  // construct the HardTree object needed to perform the showers
+  // create the partons
+  ShowerParticleVector newparticles;
+  newparticles.push_back(new_ptr(ShowerParticle(selectedParticles[0],false)));
+  newparticles.push_back(new_ptr(ShowerParticle(selectedParticles[1],false)));
+  newparticles.push_back(new_ptr(ShowerParticle(selectedParticles[3], true)));
+  // set the momenta
+  for(unsigned int ix=0;ix<2;++ix) 
+    newparticles[ix]->set5Momentum(selectedMomenta[ix]);
+  newparticles[2]->set5Momentum(selectedMomenta[3]);
+  // create the off-shell particle
+  if(iemit==2) {
+    if(particlesToShower[0]->progenitor()->dataPtr()->charged()) {
+      Lorentz5Momentum poff = selectedMomenta[0] - selectedMomenta[3];
+      poff.rescaleMass();
+      newparticles.push_back(new_ptr(ShowerParticle(partons_[0],false)));
+      newparticles.back()->set5Momentum(poff);
+    }
+    else {
+      Lorentz5Momentum poff = selectedMomenta[1] - selectedMomenta[3];
+      poff.rescaleMass();
+      newparticles.push_back(new_ptr(ShowerParticle(partons_[1],false)));
+      newparticles.back()->set5Momentum(poff);
+    }
+  }
+  else if(iemit==3) {
+    Lorentz5Momentum poff = selectedMomenta[3]+selectedMomenta[4];
+    poff.rescaleMass();
+    newparticles.push_back(new_ptr(ShowerParticle(particlesToShower[3]
+						  ->progenitor()->dataPtr(),true)));
+    newparticles.back()->set5Momentum(poff);
+  }
+  else
+    assert(false);
+  for(unsigned int ix=2;ix<particlesToShower.size();++ix) {
+    newparticles.push_back(new_ptr(ShowerParticle(particlesToShower[ix]->
+						  progenitor()->dataPtr(),true)));
+    newparticles.back()->set5Momentum(selectedMomenta[ix==2 ? 2 : 4 ]);
+  }
+  vector<HardBranchingPtr> inBranch,hardBranch;
+  // create the branchings for the incoming particles
+  inBranch.push_back(new_ptr(HardBranching(newparticles[0],SudakovPtr(),
+					   HardBranchingPtr(),HardBranching::Incoming)));
+  inBranch.push_back(new_ptr(HardBranching(newparticles[1],SudakovPtr(),
+					   HardBranchingPtr(),HardBranching::Incoming)));
+  if(iemit<3) {
+    int icharged = iemit;
+    if(icharged==2) icharged = particlesToShower[0]->progenitor()->
+		      dataPtr()->charged() ? 0 : 1;
+    // intermediate IS particle
+    hardBranch.push_back(new_ptr(HardBranching(newparticles[3],SudakovPtr(),
+					      inBranch[icharged],HardBranching::Incoming)));
+    inBranch[icharged]->addChild(hardBranch.back());
+    inBranch[icharged]->type(ShowerPartnerType::QED);
+    // create the branching for the emitted jet
+    inBranch[icharged]->addChild(new_ptr(HardBranching(newparticles[2],SudakovPtr(),
+						      inBranch[icharged],
+						      HardBranching::Outgoing)));
+    // set the colour partners
+    if(iemit<2) {
+      hardBranch.back()->colourPartner(inBranch[icharged==0 ? 1 : 0]);
+      inBranch[icharged==0 ? 1 : 0]->colourPartner(hardBranch.back());
+    }
+    // add other particle
+    hardBranch.push_back(inBranch[icharged == 0 ? 1 : 0]);
+    // outgoing particles
+    for(unsigned int ix=4;ix<newparticles.size();++ix) {
+      hardBranch.push_back(new_ptr(HardBranching(newparticles[ix],SudakovPtr(),
+						HardBranchingPtr(),
+						HardBranching::Outgoing)));
+    }
+    if(iemit==2) {
+      hardBranch.back()->colourPartner(hardBranch[0]);
+      hardBranch[0]->colourPartner(hardBranch.back());
+    }
+  }
+  else {
+    for(unsigned int ix=0;ix<2;++ix)
+      hardBranch.push_back(inBranch[ix]);
+    hardBranch.push_back(new_ptr(HardBranching(newparticles[4],SudakovPtr(),
+					       HardBranchingPtr(),
+					       HardBranching::Outgoing)));
+    hardBranch.push_back(new_ptr(HardBranching(newparticles[3],SudakovPtr(),
+					       HardBranchingPtr(),
+					       HardBranching::Outgoing)));
+    hardBranch.back()->type(ShowerPartnerType::QED);
+    hardBranch.back()->addChild(new_ptr(HardBranching(newparticles[5],SudakovPtr(),
+						      HardBranchingPtr(),
+						      HardBranching::Outgoing)));
+    hardBranch.back()->addChild(new_ptr(HardBranching(newparticles[2],SudakovPtr(),
+						      HardBranchingPtr(),
+						      HardBranching::Outgoing)));
+    if(hardBranch[0]->branchingParticle()->dataPtr()->charged()) {
+      hardBranch.back()->colourPartner(hardBranch[0]);
+      hardBranch[0]->colourPartner(hardBranch.back());
+    }
+    else {
+      hardBranch.back()->colourPartner(hardBranch[1]);
+      hardBranch[1]->colourPartner(hardBranch.back());
+    }
+  }
+  // make the tree
+  HardTreePtr hardtree=new_ptr(HardTree(hardBranch,inBranch,ShowerInteraction::QED));
+  // connect the ShowerParticles with the branchings
+  // and set the maximum pt for the radiation
+  set<HardBranchingPtr> hard=hardtree->branchings();
+  for(unsigned int ix=0;ix<particlesToShower.size();++ix) {
+    particlesToShower[ix]->maximumpT(pTmax,ShowerInteraction::QED);
+    for(set<HardBranchingPtr>::const_iterator mit=hard.begin();
+ 	mit!=hard.end();++mit) {
+      if(particlesToShower[ix]->progenitor()->id()==(*mit)->branchingParticle()->id()&&
+	 (( particlesToShower[ix]->progenitor()->isFinalState()&&
+	    (**mit).status()==HardBranching::Outgoing)||
+	  (!particlesToShower[ix]->progenitor()->isFinalState()&&
+	   (**mit).status()==HardBranching::Incoming))) {
+	hardtree->connect(particlesToShower[ix]->progenitor(),*mit);
+	if((**mit).status()==HardBranching::Incoming) {
+	  (*mit)->beam(particlesToShower[ix]->original()->parents()[0]);
+	}
+	HardBranchingPtr parent=(*mit)->parent();
+	while(parent) {
+	  parent->beam(particlesToShower[ix]->original()->parents()[0]);
+	  parent=parent->parent();
+	};
+      }
+    }
+  }
+  ColinePtr newline1 = new_ptr(ColourLine());
+  ColinePtr newline2 = new_ptr(ColourLine());
+  HardBranchingPtr gluon,quark,antiQuark;
+  for(set<HardBranchingPtr>::const_iterator cit=hardtree->branchings().begin();
+      cit!=hardtree->branchings().end();++cit) {
+    if((**cit).branchingParticle()->dataPtr()->iColour()==PDT::Colour8) {
+      gluon = *cit;
+      if((**cit).status()==HardBranching::Incoming) {
+	newline1->addColoured    ((**cit).branchingParticle());
+	newline2->addAntiColoured((**cit).branchingParticle());
+      }
+      else {
+	newline2->addColoured    ((**cit).branchingParticle());
+	newline1->addAntiColoured((**cit).branchingParticle());
+      }
+    }
+    else if((**cit).branchingParticle()->dataPtr()->iColour()==PDT::Colour3) {
+      if((**cit).status()==HardBranching::Incoming) {
+	antiQuark = *cit;
+	newline2->addColoured((**cit).branchingParticle());
+      }
+      else {
+	quark = *cit;
+	newline1->addColoured((**cit).branchingParticle());
+      }
+    }
+    else if((**cit).branchingParticle()->dataPtr()->iColour()==PDT::Colour3bar) {
+      if((**cit).status()==HardBranching::Incoming) {
+	quark = *cit;
+	newline1->addAntiColoured((**cit).branchingParticle());
+      }
+      else {
+	antiQuark = *cit;
+	newline2->addAntiColoured((**cit).branchingParticle());
+      }
+    }
+  }
+  assert(quark&&antiQuark&&gluon);
+  gluon->colourPartner(UseRandom::rndbool() ? quark : antiQuark);
+  // return the tree
+  return hardtree;
+}
diff --git a/MatrixElement/Powheg/MEPP2GammaGammaPowheg.h b/MatrixElement/Powheg/MEPP2GammaGammaPowheg.h
new file mode 100644
--- /dev/null
+++ b/MatrixElement/Powheg/MEPP2GammaGammaPowheg.h
@@ -0,0 +1,538 @@
+// -*- C++ -*-
+#ifndef HERWIG_MEPP2GammaGammaPowheg_H
+#define HERWIG_MEPP2GammaGammaPowheg_H
+//
+// This is the declaration of the MEPP2GammaGammaPowheg class.
+//
+
+#include "Herwig/MatrixElement/HwMEBase.h"
+#include "ThePEG/Helicity/Vertex/Vector/FFVVertex.h"
+#include "Herwig/MatrixElement/ProductionMatrixElement.h"
+#include "Herwig/Shower/Couplings/ShowerAlpha.h"
+
+namespace Herwig {
+
+using namespace ThePEG;
+
+/**
+ * Here is the documentation of the MEPP2GammaGammaPowheg class.
+ *
+ * @see \ref MEPP2GammaGammaPowhegInterfaces "The interfaces"
+ * defined for MEPP2GammaGammaPowheg.
+ */
+class MEPP2GammaGammaPowheg: public HwMEBase {
+
+  enum DipoleType {           IIQCD1=2,           IIQCD2=4, 
+		    IFQED1=5, FIQED1=6, IFQED2=7, FIQED2=8 };
+
+  enum RadiationType {Subtraction,Hard,Shower};
+
+public:
+
+  /** @name Standard constructors and destructors. */
+  //@{
+  /**
+   * The default constructor.
+   */
+  MEPP2GammaGammaPowheg();
+  //@}
+ 
+  /** @name Member functions for the generation of hard QCD radiation */
+  //@{
+  /**
+   *  Has a POWHEG style correction
+   */
+  virtual POWHEGType hasPOWHEGCorrection() {return ISR;}
+
+  /**
+   *  Apply the POWHEG style correction
+   */
+  virtual HardTreePtr generateHardest(ShowerTreePtr,
+				      vector<ShowerInteraction::Type>);
+  //@}
+
+public:
+
+  /** @name Virtual functions required by the MEBase class. */
+  //@{
+  /**
+   * Return the order in \f$\alpha_S\f$ in which this matrix
+   * element is given.
+   */
+  virtual unsigned int orderInAlphaS() const;
+
+  /**
+   * Return the order in \f$\alpha_{EW}\f$ in which this matrix
+   * element is given.
+   */
+  virtual unsigned int orderInAlphaEW() const;
+
+  /**
+   * The matrix element for the kinematical configuration
+   * previously provided by the last call to setKinematics(), suitably
+   * scaled by sHat() to give a dimension-less number.
+   * @return the matrix element scaled with sHat() to give a
+   * dimensionless number.
+   */
+  virtual double me2() const;
+
+  /**
+   * Return the scale associated with the last set phase space point.
+   */
+  virtual Energy2 scale() const;
+
+  /**
+   * The number of internal degrees of freedom used in the matrix
+   * element.
+   */
+  virtual int nDim() const;
+
+  /**
+   * Generate internal degrees of freedom given nDim() uniform
+   * random numbers in the interval \f$ ]0,1[ \f$. To help the phase space
+   * generator, the dSigHatDR should be a smooth function of these
+   * numbers, although this is not strictly necessary.
+   * @param r a pointer to the first of nDim() consecutive random numbers.
+   * @return true if the generation succeeded, otherwise false.
+   */
+  virtual bool generateKinematics(const double * r);
+
+  /**
+   * Return the matrix element squared differential in the variables
+   * given by the last call to generateKinematics().
+   */
+  virtual CrossSection dSigHatDR() const;
+
+  /**
+   * Add all possible diagrams with the add() function.
+   */
+  virtual void getDiagrams() const;
+
+  /**
+   * Get diagram selector. With the information previously supplied with the
+   * setKinematics method, a derived class may optionally
+   * override this method to weight the given diagrams with their
+   * (although certainly not physical) relative probabilities.
+   * @param dv the diagrams to be weighted.
+   * @return a Selector relating the given diagrams to their weights.
+   */
+  virtual Selector<DiagramIndex> diagrams(const DiagramVector & dv) const;
+
+  /**
+   * Return a Selector with possible colour geometries for the selected
+   * diagram weighted by their relative probabilities.
+   * @param diag the diagram chosen.
+   * @return the possible colour geometries weighted by their
+   * relative probabilities.
+   */
+  virtual Selector<const ColourLines *>
+  colourGeometries(tcDiagPtr diag) 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:
+
+  /**
+   *  Calculate of the full next-to-leading order weight
+   */
+  virtual double NLOWeight() const;
+
+  /**
+   *  Leading-order matrix element for \f$q\bar q\to \gamma\gamma\f$
+   */
+  double loGammaGammaME(const cPDVector & particles,
+			const vector<Lorentz5Momentum> & momenta,
+			bool first=false) const;
+
+  /**
+   *  Leading-order matrix element for \f$qg\to \gamma q\f$
+   */
+  double loGammaqME(const cPDVector & particles,
+		const vector<Lorentz5Momentum> & momenta,
+		bool first=false) const;
+
+  /**
+   *  Leading-order matrix element for \f$g\bar q\to \gamma \bar q\f$
+   */
+  double loGammaqbarME(const cPDVector & particles,
+		       const vector<Lorentz5Momentum> & momenta,
+		       bool first=false) const;
+  
+  /**
+   *  Leading-order matrix element for \f$q\bar q\to \gamma g\f$
+   */
+  double loGammagME(const cPDVector & particles,
+		    const vector<Lorentz5Momentum> & momenta,
+		    bool first=false) const;
+
+  /**
+   *  Real emission matrix element for \f$q\bar q\to \gamma \gamma g\f$
+   */
+  InvEnergy2 realGammaGammagME(const cPDVector & particles,
+			       const vector<Lorentz5Momentum> & momenta,
+			       DipoleType dipole, RadiationType rad,
+			       bool first=false) const;
+  
+  /**
+   *  Real emission matrix element for \f$qg\to \gamma \gamma q\f$
+   */
+  InvEnergy2 realGammaGammaqME(const cPDVector & particles,
+			       const vector<Lorentz5Momentum> & momenta,
+			       DipoleType dipole, RadiationType rad,
+			       bool first=false) const;
+  
+  /**
+   *  Real emission matrix element for \f$g\bar q\to \gamma \gamma \bar q\f$
+   */
+  InvEnergy2 realGammaGammaqbarME(const cPDVector & particles,
+				  const vector<Lorentz5Momentum> & momenta,
+				  DipoleType dipole, RadiationType rad,
+				  bool first=false) const;
+  
+  /**
+   *  The dipole subtractedvirtual contribution
+   */
+  double subtractedVirtual() const;
+
+  /**
+   *  Subtracted real contribution
+   */
+  double subtractedReal(pair<double,double> x, double z,
+			double zJac, double oldqPDF, double newqPDF,
+			double newgPDF,bool order) const;
+
+  /**
+   *  Calculate of the collinear counterterms
+   */
+  //@{
+  /**
+   *  Quark collinear counter term
+   */
+  double collinearQuark(double x, Energy2 mu2, double jac, double z,
+			double oldPDF, double newPDF) const;
+
+  /**
+   *  Gluon collinear counter term
+   */
+  double collinearGluon(Energy2 mu2, double jac, double z,
+			double oldPDF, double newPDF) const;
+  //@}
+
+  /**
+   * The real matrix element divided by \f$2 g_S^2\f$, to be implemented in the
+   * inheriting classes. 
+   * @param particles The ParticleData objects of the particles
+   * @param momenta The momenta of the particles
+   */
+  double realME(const cPDVector & particles,
+		const vector<Lorentz5Momentum> & momenta) const;
+
+  /**
+   *  Generate hard QCD emission
+   */
+  HardTreePtr hardQCDEmission(vector<ShowerProgenitorPtr>);
+
+  /**
+   *  Generate hard QED emission 
+   */
+  HardTreePtr hardQEDEmission(vector<ShowerProgenitorPtr>);
+
+  /**
+   *  The supression function
+   */
+  pair<double,double> supressionFunction(Energy pT,Energy scale) const {
+    if(supressionScale_==0) scale = lambda_;
+    Energy2 scale2 = sqr(scale), pT2 = sqr(pT);
+    switch( supressionFunction_ ) {
+    case 0:
+      return make_pair(1.,0.);
+    case 1:
+      if(pT < scale ) return make_pair(1.,0.);
+      else            return make_pair(0.,1.);
+    case 2:
+      return make_pair(scale2/(pT2+scale2),pT2/(pT2+scale2));
+    default:
+      assert(false);
+    }
+  }
+
+
+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();
+  //@}
+
+private:
+
+  /**
+   * The assignment operator is private and must never be called.
+   * In fact, it should not even be implemented.
+   */
+  MEPP2GammaGammaPowheg & operator=(const MEPP2GammaGammaPowheg &);
+
+private:
+
+  /**
+   *  Vertices
+   */
+  //@{
+  /**
+   *   FFPVertex
+   */
+  AbstractFFVVertexPtr FFPvertex_;
+
+  /**
+   *   FFGVertex
+   */
+  AbstractFFVVertexPtr FFGvertex_;
+  //@}
+
+  /**
+   *  Kinematic variables for the real radiation
+   */
+  //@{
+  /**
+   *  First  variable
+   */
+  mutable double zTilde_;
+
+  /**
+   *  Second variable
+   */
+  mutable double vTilde_;
+
+  /**
+   *  Azimuthal angle
+   */
+  mutable double phi_;
+  //@}
+
+  /**
+   *  Whether to generate the positive, negative or leading order contribution
+   */
+  unsigned int contrib_;
+
+  /**
+   *  Power for sampling \f$x_p\f$
+   */
+  double power_;
+
+  /**
+   *  Pointer to the gluon ParticleData object
+   */
+  tcPDPtr gluon_;
+
+  /**
+   *  Processes
+   */
+  unsigned int process_;
+
+  /**
+   *  Processes
+   */
+  unsigned int threeBodyProcess_;
+
+  /**
+   *  Allowed flavours of the incoming quarks
+   */
+  int maxflavour_;
+
+  /**
+   *  Factor for \f$C_F\f$ dependent pieces
+   */
+  mutable double CFfact_;
+
+  /**
+   *  Factor for \f$T_R\f$ dependent pieces
+   */
+  mutable double TRfact_;
+
+  /**
+   *  Strong coupling
+   */
+  mutable double alphaS_;
+
+  /**
+   *  Use a fixed value of \f$\alpha_S\f$
+   */
+  bool fixedAlphaS_;
+
+  /**
+   *  Electromagnetic coupling
+   */
+  mutable double alphaEM_;
+
+  /**
+   *  Leading-order matrix element
+   */
+  mutable double loME_;
+
+  /**
+   *  The matrix element
+   */
+  mutable ProductionMatrixElement me_;
+
+  /**
+   *  the selected dipole
+   */
+  mutable DipoleType dipole_;
+
+  /**
+   *  Supression Function
+   */
+  //@{
+  /**
+   *  Choice of the supression function
+   */
+  unsigned int supressionFunction_;
+
+  /**
+   *  Choice for the scale in the supression function
+   */
+  unsigned int supressionScale_;
+
+  /**
+   *  Scalar for the supression function
+   */
+  Energy lambda_;
+  //@}
+
+
+  /**
+   *  Hard emission stuff
+   */
+  //@{
+  /**
+   *  Whether the quark is in the + or - z direction
+   */
+  bool quarkplus_;
+  //@}
+
+  /**
+   *  Properties of the incoming particles
+   */
+  //@{
+  /**
+   *  Pointers to the BeamParticleData objects
+   */
+  vector<tcBeamPtr> beams_;
+  
+  /**
+   *  Pointers to the ParticleDataObjects for the partons
+   */
+  vector<tcPDPtr> partons_;
+  //@}
+
+  /**
+   *  Constants for the sampling. The distribution is assumed to have the
+   *  form \f$\frac{c}{{\rm GeV}}\times\left(\frac{{\rm GeV}}{p_T}\right)^n\f$ 
+   */
+  //@{
+  /**
+   *  The prefactor, \f$c\f$ for the \f$q\bar{q}\f$ channel
+   */
+  double preQCDqqbarq_;
+  /**
+   *  The prefactor, \f$c\f$ for the \f$q\bar{q}\f$ channel
+   */
+  double preQCDqqbarqbar_;
+
+  /**
+   *  The prefactor, \f$c\f$ for the \f$qg\f$ channel
+   */
+  double preQCDqg_;
+
+  /**
+   *  The prefactor, \f$c\f$ for the \f$g\bar{q}\f$ channel
+   */
+  double preQCDgqbar_;
+
+  double preQEDqqbarq_;
+  double preQEDqqbarqbar_;
+  double preQEDqgq_;
+  double preQEDgqbarqbar_;
+
+  /**
+   *  The prefactors as a vector for easy use
+   */
+  vector<double> prefactor_;
+  //@}
+
+  /**
+   *  The transverse momentum of the jet
+   */
+  Energy minpT_;
+
+  /**
+   *  Pointer to the object calculating the strong coupling
+   */
+  ShowerAlphaPtr alphaQCD_;
+
+  /**
+   *  Pointer to the object calculating the EM
+   */
+  ShowerAlphaPtr alphaQED_;
+
+  /**
+   *  Scale choice
+   */
+  unsigned int scaleChoice_;
+
+  /**
+   *  Scale factor
+   */
+  double scalePreFactor_;
+
+};
+
+}
+
+#endif /* HERWIG_MEPP2GammaGammaPowheg_H */
diff --git a/MatrixElement/Powheg/Makefile.am b/MatrixElement/Powheg/Makefile.am
--- a/MatrixElement/Powheg/Makefile.am
+++ b/MatrixElement/Powheg/Makefile.am
@@ -1,16 +1,17 @@
 pkglib_LTLIBRARIES = HwPowhegMEHadron.la HwPowhegMELepton.la
 HwPowhegMEHadron_la_LDFLAGS = $(AM_LDFLAGS) -module -version-info 6:0:0
 HwPowhegMEHadron_la_SOURCES = \
 MEqq2gZ2ffPowheg.cc MEqq2gZ2ffPowheg.h \
 MEqq2W2ffPowheg.cc  MEqq2W2ffPowheg.h \
 MEPP2HiggsPowheg.cc  MEPP2HiggsPowheg.h \
 MEPP2WHPowheg.cc  MEPP2WHPowheg.h \
 MEPP2ZHPowheg.cc  MEPP2ZHPowheg.h \
 MEPP2VVPowheg.cc  MEPP2VVPowheg.h \
 VVKinematics.cc VVKinematics.h \
+MEPP2GammaGammaPowheg.cc  MEPP2GammaGammaPowheg.h \
 MEPP2HiggsVBFPowheg.cc MEPP2HiggsVBFPowheg.h
 
 HwPowhegMELepton_la_LDFLAGS = $(AM_LDFLAGS) -module -version-info 1:0:0
 HwPowhegMELepton_la_SOURCES = \
 MEee2gZ2qqPowheg.cc MEee2gZ2qqPowheg.h \
 MEee2gZ2llPowheg.cc MEee2gZ2llPowheg.h 
diff --git a/Shower/Base/Evolver.cc b/Shower/Base/Evolver.cc
--- a/Shower/Base/Evolver.cc
+++ b/Shower/Base/Evolver.cc
@@ -1,3630 +1,3630 @@
 // -*- C++ -*-
 //
 // Evolver.cc is a part of Herwig - A multi-purpose Monte Carlo event generator
 // Copyright (C) 2002-2011 The Herwig Collaboration
 //
 // Herwig is licenced under version 2 of the GPL, see COPYING for details.
 // Please respect the MCnet academic guidelines, see GUIDELINES for details.
 //
 //
 // This is the implementation of the non-inlined, non-templated member
 // functions of the Evolver class.
 //
 #include "Evolver.h"
 #include "ThePEG/Interface/ClassDocumentation.h"
 #include "ThePEG/Interface/Reference.h"
 #include "ThePEG/Interface/RefVector.h"
 #include "ThePEG/Interface/Switch.h"
 #include "ThePEG/Interface/Parameter.h"
 #include "ThePEG/Persistency/PersistentOStream.h"
 #include "ThePEG/Persistency/PersistentIStream.h"
 #include "Herwig/Shower/Base/ShowerParticle.h"
 #include "ThePEG/Utilities/EnumIO.h"
 #include "ShowerKinematics.h"
 #include "ThePEG/PDT/EnumParticles.h"
 #include "ThePEG/Repository/EventGenerator.h"
 #include "ThePEG/Handlers/EventHandler.h"
 #include "ThePEG/Utilities/Throw.h"
 #include "ShowerTree.h"
 #include "ShowerProgenitor.h"
 #include "KinematicsReconstructor.h"
 #include "PartnerFinder.h"
 #include "ThePEG/Handlers/StandardXComb.h"
 #include "ThePEG/PDT/DecayMode.h"
 #include "Herwig/Shower/ShowerHandler.h" 
 #include "ThePEG/Utilities/DescribeClass.h"
 #include "ShowerVertex.h"
 #include "ThePEG/Repository/CurrentGenerator.h"
 #include "Herwig/MatrixElement/Matchbox/Base/SubtractedME.h"
 #include "Herwig/MatrixElement/Matchbox/MatchboxFactory.h"
 #include "ThePEG/Handlers/StandardXComb.h"
 
 using namespace Herwig;
 
 namespace {
 
   /**
    *  A struct to order the particles in the same way as in the DecayMode's
    */
   struct ParticleOrdering {
     /**
      *  Operator for the ordering
      * @param p1 The first ParticleData object
      * @param p2 The second ParticleData object
      */
     bool operator() (tcPDPtr p1, tcPDPtr p2) {
       return abs(p1->id()) > abs(p2->id()) ||
 	( abs(p1->id()) == abs(p2->id()) && p1->id() > p2->id() ) ||
 	( p1->id() == p2->id() && p1->fullName() > p2->fullName() );
     }
   };
   typedef multiset<tcPDPtr,ParticleOrdering> OrderedParticles;
 
   /**
    * Cached lookup of decay modes.
    * Generator::findDecayMode() is not efficient.
    */
   tDMPtr findDecayMode(const string & tag) {
     static map<string,DMPtr> cache;
     map<string,DMPtr>::const_iterator pos = cache.find(tag);
 
     if ( pos != cache.end() ) 
     	return pos->second;
 
     tDMPtr dm = CurrentGenerator::current().findDecayMode(tag);
     cache[tag] = dm;
     return dm;
   }
 }
 
 DescribeClass<Evolver,Interfaced>
 describeEvolver ("Herwig::Evolver","HwShower.so");
 
 bool Evolver::_hardEmissionModeWarn = true;
 bool Evolver::_missingTruncWarn = true;
 
 IBPtr Evolver::clone() const {
   return new_ptr(*this);
 }
 
 IBPtr Evolver::fullclone() const {
   return new_ptr(*this);
 }
 
 void Evolver::persistentOutput(PersistentOStream & os) const {
   os << _model << _splittingGenerator << _maxtry 
      << _meCorrMode << _hardVetoMode << _hardVetoRead << _hardVetoReadOption
      << _limitEmissions << _spinOpt << _softOpt << _hardPOWHEG
      << ounit(_iptrms,GeV) << _beta << ounit(_gamma,GeV) << ounit(_iptmax,GeV) 
      << _vetoes << _trunc_Mode << _hardEmissionMode << _reconOpt 
      << isMCatNLOSEvent << isMCatNLOHEvent
      << isPowhegSEvent << isPowhegHEvent
      << theFactorizationScaleFactor << theRenormalizationScaleFactor << ounit(muPt,GeV)
      << interaction_ << _maxTryFSR << _maxFailFSR << _fracFSR << interactions_.size();
   for(unsigned int ix=0;ix<interactions_.size();++ix) 
     os << oenum(interactions_[ix]);
 }
 
 void Evolver::persistentInput(PersistentIStream & is, int) {
   unsigned int isize;
   is >> _model >> _splittingGenerator >> _maxtry 
      >> _meCorrMode >> _hardVetoMode >> _hardVetoRead >> _hardVetoReadOption
      >> _limitEmissions >> _spinOpt >> _softOpt >> _hardPOWHEG
      >> iunit(_iptrms,GeV) >> _beta >> iunit(_gamma,GeV) >> iunit(_iptmax,GeV)
      >> _vetoes >> _trunc_Mode >> _hardEmissionMode >> _reconOpt
      >> isMCatNLOSEvent >> isMCatNLOHEvent
      >> isPowhegSEvent >> isPowhegHEvent
      >> theFactorizationScaleFactor >> theRenormalizationScaleFactor >> iunit(muPt,GeV)
      >> interaction_ >> _maxTryFSR >> _maxFailFSR >> _fracFSR >> isize;
   interactions_.resize(isize);
   for(unsigned int ix=0;ix<interactions_.size();++ix) 
     is >> ienum(interactions_[ix]);
 }
 
 void Evolver::doinit() {
   Interfaced::doinit();
   // interactions may have been changed through a setup file so we
   // clear it up here
   interactions_.clear();
   if(interaction_==0) {
     interactions_.push_back(ShowerInteraction::QCD);
     interactions_.push_back(ShowerInteraction::QED);
   }
   else if(interaction_==1) {
     interactions_.push_back(ShowerInteraction::QCD);
   }
   else if(interaction_==2) {
     interactions_.push_back(ShowerInteraction::QED);
     interactions_.push_back(ShowerInteraction::QCD);
   }
   else if(interaction_==3) {
     interactions_.push_back(ShowerInteraction::QED);
   }
   else if(interaction_==4) {
     interactions_.push_back(ShowerInteraction::Both);
   }
   // calculate max no of FSR vetos
   _maxFailFSR = max(int(_maxFailFSR), int(_fracFSR*double(generator()->N())));
 }
 
 void Evolver::Init() {
   
   static ClassDocumentation<Evolver> documentation
     ("This class is responsible for carrying out the showering,",
      "including the kinematics reconstruction, in a given scale range,"
      "including the option of the POWHEG approach to simulated next-to-leading order"
      " radiation\\cite{Nason:2004rx}.",
      "%\\cite{Nason:2004rx}\n"
      "\\bibitem{Nason:2004rx}\n"
      "  P.~Nason,\n"
      "  ``A new method for combining NLO QCD with shower Monte Carlo algorithms,''\n"
      "  JHEP {\\bf 0411} (2004) 040\n"
      "  [arXiv:hep-ph/0409146].\n"
      "  %%CITATION = JHEPA,0411,040;%%\n");
 
   static Reference<Evolver,SplittingGenerator> 
     interfaceSplitGen("SplittingGenerator", 
 		      "A reference to the SplittingGenerator object", 
 		      &Herwig::Evolver::_splittingGenerator,
 		      false, false, true, false);
 
   static Reference<Evolver,ShowerModel> interfaceShowerModel
     ("ShowerModel",
      "The pointer to the object which defines the shower evolution model.",
      &Evolver::_model, false, false, true, false, false);
 
   static Parameter<Evolver,unsigned int> interfaceMaxTry
     ("MaxTry",
      "The maximum number of attempts to generate the shower from a"
      " particular ShowerTree",
      &Evolver::_maxtry, 100, 1, 1000,
      false, false, Interface::limited);
 
   static Switch<Evolver, unsigned int> ifaceMECorrMode
     ("MECorrMode",
      "Choice of the ME Correction Mode",
      &Evolver::_meCorrMode, 1, false, false);
   static SwitchOption off
     (ifaceMECorrMode,"No","MECorrections off", 0);
   static SwitchOption on
     (ifaceMECorrMode,"Yes","hard+soft on", 1);
   static SwitchOption hard
     (ifaceMECorrMode,"Hard","only hard on", 2);
   static SwitchOption soft
     (ifaceMECorrMode,"Soft","only soft on", 3);
 
   static Switch<Evolver, unsigned int> ifaceHardVetoMode
     ("HardVetoMode",
      "Choice of the Hard Veto Mode",
      &Evolver::_hardVetoMode, 1, false, false);
   static SwitchOption HVoff
     (ifaceHardVetoMode,"No","hard vetos off", 0);
   static SwitchOption HVon
     (ifaceHardVetoMode,"Yes","hard vetos on", 1);
   static SwitchOption HVIS
     (ifaceHardVetoMode,"Initial", "only IS emissions vetoed", 2);
   static SwitchOption HVFS
     (ifaceHardVetoMode,"Final","only FS emissions vetoed", 3);
 
   static Switch<Evolver, unsigned int> ifaceHardVetoRead
     ("HardVetoScaleSource",
      "If hard veto scale is to be read",
      &Evolver::_hardVetoRead, 0, false, false);
   static SwitchOption HVRcalc
     (ifaceHardVetoRead,"Calculate","Calculate from hard process", 0);
   static SwitchOption HVRread
     (ifaceHardVetoRead,"Read","Read from XComb->lastScale", 1);
 
   static Switch<Evolver, bool> ifaceHardVetoReadOption
     ("HardVetoReadOption",
      "Apply read-in scale veto to all collisions or just the primary one?",
      &Evolver::_hardVetoReadOption, false, false, false);
   static SwitchOption AllCollisions
     (ifaceHardVetoReadOption,
      "AllCollisions",
      "Read-in pT veto applied to primary and secondary collisions.",
      false);
   static SwitchOption PrimaryCollision
     (ifaceHardVetoReadOption,
      "PrimaryCollision",
      "Read-in pT veto applied to primary but not secondary collisions.",
      true);
 
   static Parameter<Evolver, Energy> ifaceiptrms
     ("IntrinsicPtGaussian",
      "RMS of intrinsic pT of Gaussian distribution:\n"
      "2*(1-Beta)*exp(-sqr(intrinsicpT/RMS))/sqr(RMS)",
      &Evolver::_iptrms, GeV, ZERO, ZERO, 1000000.0*GeV,
      false, false, Interface::limited);
 
   static Parameter<Evolver, double> ifacebeta
     ("IntrinsicPtBeta",
      "Proportion of inverse quadratic distribution in generating intrinsic pT.\n"
      "(1-Beta) is the proportion of Gaussian distribution",
      &Evolver::_beta, 0, 0, 1,
      false, false, Interface::limited);
 
   static Parameter<Evolver, Energy> ifacegamma
     ("IntrinsicPtGamma",
      "Parameter for inverse quadratic:\n"
      "2*Beta*Gamma/(sqr(Gamma)+sqr(intrinsicpT))",
      &Evolver::_gamma,GeV, ZERO, ZERO, 100000.0*GeV,
      false, false, Interface::limited);
 
   static Parameter<Evolver, Energy> ifaceiptmax
     ("IntrinsicPtIptmax",
      "Upper bound on intrinsic pT for inverse quadratic",
      &Evolver::_iptmax,GeV, ZERO, ZERO, 100000.0*GeV,
      false, false, Interface::limited);
 
   static RefVector<Evolver,ShowerVeto> ifaceVetoes
     ("Vetoes",
      "The vetoes to be checked during showering",
      &Evolver::_vetoes, -1,
      false,false,true,true,false);
 
   static Switch<Evolver,unsigned int> interfaceLimitEmissions
     ("LimitEmissions",
      "Limit the number and type of emissions for testing",
      &Evolver::_limitEmissions, 0, false, false);
   static SwitchOption interfaceLimitEmissionsNoLimit
     (interfaceLimitEmissions,
      "NoLimit",
      "Allow an arbitrary number of emissions",
      0);
   static SwitchOption interfaceLimitEmissionsOneInitialStateEmission
     (interfaceLimitEmissions,
      "OneInitialStateEmission",
      "Allow one emission in the initial state and none in the final state",
      1);
   static SwitchOption interfaceLimitEmissionsOneFinalStateEmission
     (interfaceLimitEmissions,
      "OneFinalStateEmission",
      "Allow one emission in the final state and none in the initial state",
      2);
   static SwitchOption interfaceLimitEmissionsHardOnly
     (interfaceLimitEmissions,
      "HardOnly",
      "Only allow radiation from the hard ME correction",
      3);
   static SwitchOption interfaceLimitEmissionsOneEmission
     (interfaceLimitEmissions,
      "OneEmission",
      "Allow one emission in either the final state or initial state, but not both",
      4);
 
   static Switch<Evolver,bool> interfaceTruncMode
     ("TruncatedShower", "Include the truncated shower?", 
      &Evolver::_trunc_Mode, 1, false, false);
   static SwitchOption interfaceTruncMode0
     (interfaceTruncMode,"No","Truncated Shower is OFF", 0);
   static SwitchOption interfaceTruncMode1
     (interfaceTruncMode,"Yes","Truncated Shower is ON", 1);
 
   static Switch<Evolver,int> interfaceHardEmissionMode
     ("HardEmissionMode",
      "Whether to use ME corrections or POWHEG for the hardest emission",
      &Evolver::_hardEmissionMode, 0, false, false);
   static SwitchOption interfaceHardEmissionModeDecayMECorrection
     (interfaceHardEmissionMode,
      "DecayMECorrection",
      "Old fashioned ME correction for decays only",
      -1);
   static SwitchOption interfaceHardEmissionModeMECorrection
     (interfaceHardEmissionMode,
      "MECorrection",
      "Old fashioned ME correction",
      0);
   static SwitchOption interfaceHardEmissionModePOWHEG
     (interfaceHardEmissionMode,
      "POWHEG",
      "Powheg style hard emission using internal matrix elements",
      1);
   static SwitchOption interfaceHardEmissionModeMatchboxPOWHEG
     (interfaceHardEmissionMode,
      "MatchboxPOWHEG",
      "Powheg style emission for the hard process using Matchbox",
      2);
   static SwitchOption interfaceHardEmissionModeFullPOWHEG
     (interfaceHardEmissionMode,
      "FullPOWHEG",
      "Powheg style emission for the hard process using Matchbox "
      "and decays using internal matrix elements",
      3);
 
   static Switch<Evolver,unsigned int > interfaceInteractions
     ("Interactions",
      "The interactions to be used in the shower",
      &Evolver::interaction_, 1, false, false);
   static SwitchOption interfaceInteractionsQCDFirst
     (interfaceInteractions,
      "QCDFirst",
      "QCD first then QED",
      0);
   static SwitchOption interfaceInteractionsQCDOnly
     (interfaceInteractions,
      "QCDOnly",
      "Only QCD",
      1);
   static SwitchOption interfaceInteractionsQEDFirst
     (interfaceInteractions,
      "QEDFirst",
      "QED first then QCD",
      2);
   static SwitchOption interfaceInteractionsQEDOnly
     (interfaceInteractions,
      "QEDOnly",
      "Only QED",
      3);
   static SwitchOption interfaceInteractionsBothAtOnce
     (interfaceInteractions,
      "BothAtOnce",
      "Generate both at the same time",
      4);
 
   static Switch<Evolver,unsigned int> interfaceReconstructionOption
     ("ReconstructionOption",
      "Treatment of the reconstruction of the transverse momentum of "
      "a branching from the evolution scale.",
      &Evolver::_reconOpt, 0, false, false);
   static SwitchOption interfaceReconstructionOptionCutOff
     (interfaceReconstructionOption,
      "CutOff",
      "Use the cut-off masses in the calculation",
      0);
   static SwitchOption interfaceReconstructionOptionOffShell
     (interfaceReconstructionOption,
      "OffShell",
      "Use the off-shell masses in the calculation veto the emission of the parent,"
      " no veto in generation of emissions from children",
      1);
   static SwitchOption interfaceReconstructionOptionOffShell2
     (interfaceReconstructionOption,
      "OffShell2",
      "Use the off-shell masses in the calculation veto the emissions from the children."
      " no veto in generation of emissions from children",
      2);
   static SwitchOption interfaceReconstructionOptionOffShell3
     (interfaceReconstructionOption,
      "OffShell3",
      "Use the off-shell masses in the calculation veto the emissions from the children."
      " veto in generation of emissions from children using cut-off for second parton",
      3);
 
   static Switch<Evolver,unsigned int> interfaceSpinCorrelations
     ("SpinCorrelations",
      "Treatment of spin correlations in the parton shower",
      &Evolver::_spinOpt, 1, false, false);
   static SwitchOption interfaceSpinCorrelationsOff
     (interfaceSpinCorrelations,
      "No",
      "No spin correlations",
      0);
   static SwitchOption interfaceSpinCorrelationsSpin
     (interfaceSpinCorrelations,
      "Yes",
      "Include the azimuthal spin correlations only",
      1);
 
   static Switch<Evolver,unsigned int> interfaceSoftCorrelations
     ("SoftCorrelations",
      "Option for the treatment of soft correlations in the parton shower",
      &Evolver::_softOpt, 2, false, false);
   static SwitchOption interfaceSoftCorrelationsNone
     (interfaceSoftCorrelations,
      "No",
      "No soft correlations",
      0);
   static SwitchOption interfaceSoftCorrelationsFull
     (interfaceSoftCorrelations,
      "Full",
      "Use the full eikonal",
      1);
   static SwitchOption interfaceSoftCorrelationsSingular
     (interfaceSoftCorrelations,
      "Singular",
      "Use original Webber-Marchisini form",
      2);
 
   static Switch<Evolver,bool> interfaceHardPOWHEG
     ("HardPOWHEG",
      "Treatment of powheg emissions which are too hard to have a shower interpretation",
      &Evolver::_hardPOWHEG, false, false, false);
   static SwitchOption interfaceHardPOWHEGAsShower
     (interfaceHardPOWHEG,
      "AsShower",
      "Still interpret as shower emissions",
      false);
   static SwitchOption interfaceHardPOWHEGRealEmission
     (interfaceHardPOWHEG,
      "RealEmission",
      "Generate shower from the real emmission configuration",
      true);
 
   static Parameter<Evolver,unsigned int> interfaceMaxTryFSR
     ("MaxTryFSR",
      "The maximum number of attempted FSR emissions in"
      " the generation of the FSR",
      &Evolver::_maxTryFSR, 100000, 10, 100000000,
      false, false, Interface::limited);
 
   static Parameter<Evolver,unsigned int> interfaceMaxFailFSR
     ("MaxFailFSR",
      "Maximum number of failures generating the FSR",
      &Evolver::_maxFailFSR, 100, 1, 100000000,
      false, false, Interface::limited);
 
 
   static Parameter<Evolver,double> interfaceFSRFailureFraction
     ("FSRFailureFraction",
      "Maximum fraction of events allowed to fail due to too many FSR emissions",
      &Evolver::_fracFSR, 0.001, 1e-10, 1,
      false, false, Interface::limited);
 }
 
 void Evolver::generateIntrinsicpT(vector<ShowerProgenitorPtr> particlesToShower) {
   _intrinsic.clear();
   if ( !ipTon() || !isISRadiationON() ) return;
   // don't do anything for the moment for secondary scatters
   if( !ShowerHandler::currentHandler()->firstInteraction() ) return;
   // generate intrinsic pT
   for(unsigned int ix=0;ix<particlesToShower.size();++ix) {
     // only consider initial-state particles
     if(particlesToShower[ix]->progenitor()->isFinalState()) continue;
     if(!particlesToShower[ix]->progenitor()->dataPtr()->coloured()) continue;
     Energy ipt;
     if(UseRandom::rnd() > _beta) {
       ipt=_iptrms*sqrt(-log(UseRandom::rnd()));
     }
     else {
       ipt=_gamma*sqrt(pow(1.+sqr(_iptmax/_gamma), UseRandom::rnd())-1.);
     }
     pair<Energy,double> pt = make_pair(ipt,UseRandom::rnd(Constants::twopi));
     _intrinsic[particlesToShower[ix]] = pt;
   }
 }
 
 void Evolver::setupMaximumScales(const vector<ShowerProgenitorPtr> & p,
 				 XCPtr xcomb) {
   // let POWHEG events radiate freely
   if(_hardEmissionMode>0&&hardTree()) {
     vector<ShowerProgenitorPtr>::const_iterator ckt = p.begin();
     for (; ckt != p.end(); ckt++) (*ckt)->maxHardPt(Constants::MaxEnergy);
     return;
   }
   // return if no vetos
   if (!hardVetoOn()) return; 
   // find out if hard partonic subprocess.
   bool isPartonic(false); 
   map<ShowerProgenitorPtr,ShowerParticlePtr>::const_iterator 
     cit = _currenttree->incomingLines().begin();
   Lorentz5Momentum pcm;
   for(; cit!=currentTree()->incomingLines().end(); ++cit) {
     pcm += cit->first->progenitor()->momentum();
     isPartonic |= cit->first->progenitor()->coloured();
   }
   // find minimum pt from hard process, the maximum pt from all outgoing
   // coloured lines (this is simpler and more general than
   // 2stu/(s^2+t^2+u^2)).  Maximum scale for scattering processes will
   // be transverse mass.
   Energy ptmax = generator()->maximumCMEnergy();
   // general case calculate the scale  
   if (!hardVetoXComb()||
       (hardVetoReadOption()&&
        !ShowerHandler::currentHandler()->firstInteraction())) {
     // scattering process
     if(currentTree()->isHard()) {
       assert(xcomb);
       // coloured incoming particles
       if (isPartonic) {
 	map<ShowerProgenitorPtr,tShowerParticlePtr>::const_iterator 
 	  cjt = currentTree()->outgoingLines().begin();
 	for(; cjt!=currentTree()->outgoingLines().end(); ++cjt) {
 	  if (cjt->first->progenitor()->coloured())
 	    ptmax = min(ptmax,cjt->first->progenitor()->momentum().mt());
 	}
       }
       if (ptmax == generator()->maximumCMEnergy() ) ptmax = pcm.m();
       if(hardVetoXComb()&&hardVetoReadOption()&&
 	 !ShowerHandler::currentHandler()->firstInteraction()) {
-	ptmax=min(ptmax,sqrt(xcomb->lastCentralScale()));
+	ptmax=min(ptmax,sqrt(xcomb->lastShowerScale()));
       }
     } 
     // decay, incoming() is the decaying particle.
     else { 
       ptmax = currentTree()->incomingLines().begin()->first
 	->progenitor()->momentum().mass(); 
     }
   }
   // hepeup.SCALUP is written into the lastXComb by the
   // LesHouchesReader itself - use this by user's choice. 
   // Can be more general than this. 
   else {
     if(currentTree()->isHard()) {
       assert(xcomb);
-      ptmax = sqrt( xcomb->lastCentralScale() );
+      ptmax = sqrt( xcomb->lastShowerScale() );
     }
     else {
       ptmax = currentTree()->incomingLines().begin()->first
 	->progenitor()->momentum().mass(); 
     }
   }
   ptmax *= ShowerHandler::currentHandler()->hardScaleFactor();
   // set maxHardPt for all progenitors.  For partonic processes this
   // is now the max pt in the FS, for non-partonic processes or
   // processes with no coloured FS the invariant mass of the IS
   vector<ShowerProgenitorPtr>::const_iterator ckt = p.begin();
   for (; ckt != p.end(); ckt++) (*ckt)->maxHardPt(ptmax);
 }
 
 void Evolver::setupHardScales(const vector<ShowerProgenitorPtr> & p,
 			      XCPtr xcomb) {
   if ( hardVetoXComb() &&
        (!hardVetoReadOption() ||
 	ShowerHandler::currentHandler()->firstInteraction()) ) {
     Energy hardScale = ZERO;
     if(currentTree()->isHard()) {
       assert(xcomb);
-      hardScale = sqrt( xcomb->lastCentralScale() );
+      hardScale = sqrt( xcomb->lastShowerScale() );
     }
     else {
       hardScale = currentTree()->incomingLines().begin()->first
 	->progenitor()->momentum().mass(); 
     }
     hardScale *= ShowerHandler::currentHandler()->hardScaleFactor();
     vector<ShowerProgenitorPtr>::const_iterator ckt = p.begin();
     for (; ckt != p.end(); ckt++) (*ckt)->hardScale(hardScale);
     muPt = hardScale;
   }
 }
 
 void Evolver::showerHardProcess(ShowerTreePtr hard, XCPtr xcomb) {
 
 
   isMCatNLOSEvent = false;
   isMCatNLOHEvent = false;
   isPowhegSEvent  = false;
   isPowhegHEvent  = false;
 
   Ptr<SubtractedME>::tptr subme;
   Ptr<MatchboxMEBase>::tptr me;
   Ptr<SubtractionDipole>::tptr dipme;
 
   Ptr<StandardXComb>::ptr sxc = dynamic_ptr_cast<Ptr<StandardXComb>::ptr>(xcomb);
 
   if ( sxc ) {
     subme = dynamic_ptr_cast<Ptr<SubtractedME>::tptr>(sxc->matrixElement());
     me = dynamic_ptr_cast<Ptr<MatchboxMEBase>::tptr>(sxc->matrixElement());
     dipme = dynamic_ptr_cast<Ptr<SubtractionDipole>::tptr>(sxc->matrixElement());
   }
 
   if ( subme ) {
     if ( subme->showerApproximation() ) {
       theShowerApproximation = subme->showerApproximation();
       // separate MCatNLO and POWHEG-type corrections
       if ( !subme->showerApproximation()->needsSplittingGenerator() ) {
 	if ( subme->realShowerSubtraction() )
 	  isMCatNLOHEvent = true;
 	else if ( subme->virtualShowerSubtraction() )
 	  isMCatNLOSEvent = true;
       }
       else {
   	if ( subme->realShowerSubtraction() )
   	  isPowhegHEvent = true;
   	else if ( subme->virtualShowerSubtraction() ||  subme->loopSimSubtraction() )
   	  isPowhegSEvent = true;
       }
     }
   } else if ( me ) {
     if ( me->factory()->showerApproximation() ) {
       theShowerApproximation = me->factory()->showerApproximation();
       if ( !me->factory()->showerApproximation()->needsSplittingGenerator() ) 
 	isMCatNLOSEvent = true;
       else
   	isPowhegSEvent = true;
     }
   }
 
   string error = "Inconsistent hard emission set-up in Evolver::showerHardProcess(). "; 
   if ( ( isMCatNLOSEvent || isMCatNLOHEvent ) ){
     if (_hardEmissionMode > 1)
       throw Exception() << error
 			<< "Cannot generate POWHEG matching with MC@NLO shower "
 			<< "approximation.  Add 'set Evolver:HardEmissionMode 0' to input file."
 			<< Exception::runerror;
     if ( ShowerHandler::currentHandler()->canHandleMatchboxTrunc())
       throw Exception() << error
 			<< "Cannot use truncated qtilde shower with MC@NLO shower "
 			<< "approximation.  Set LHCGenerator:EventHandler"
 			<< ":CascadeHandler to '/Herwig/Shower/ShowerHandler' or "
 			<< "'/Herwig/DipoleShower/DipoleShowerHandler'."
 			<< Exception::runerror;
   }
   else if ( ((isPowhegSEvent || isPowhegHEvent) || dipme) &&
 	    _hardEmissionMode < 2){
     if ( ShowerHandler::currentHandler()->canHandleMatchboxTrunc())
       throw Exception() << error
 			<< "Unmatched events requested for POWHEG shower "
 			<< "approximation.  Set Evolver:HardEmissionMode to "
 			<< "'MatchboxPOWHEG' or 'FullPOWHEG'."
 			<< Exception::runerror;
     else if (_hardEmissionModeWarn){
       _hardEmissionModeWarn = false;
       _hardEmissionMode+=2;
       throw Exception() << error
 			<< "Unmatched events requested for POWHEG shower "
 			<< "approximation. Changing Evolver:HardEmissionMode from "
 			<< _hardEmissionMode-2 << " to " << _hardEmissionMode
 			<< Exception::warning;
     }
   }
 
   if ( isPowhegSEvent || isPowhegHEvent) {
     if (theShowerApproximation->needsTruncatedShower() &&
 	!ShowerHandler::currentHandler()->canHandleMatchboxTrunc() )
       throw Exception() << error
 			<< "Current shower handler cannot generate truncated shower.  "
 			<< "Set Generator:EventHandler:CascadeHandler to "
 			<< "'/Herwig/Shower/PowhegShowerHandler'."
 			<< Exception::runerror;
   }
   else if ( dipme && _missingTruncWarn){
     _missingTruncWarn=false;
     throw Exception() << "Warning: POWHEG shower approximation used without "
 		      << "truncated shower.  Set Generator:EventHandler:"
 		      << "CascadeHandler to '/Herwig/Shower/PowhegShowerHandler' and "
 		      << "'MEMatching:TruncatedShower Yes'."
 		      << Exception::warning;   
   }
   else if ( !dipme && _hardEmissionMode > 1 && 
 	    ShowerHandler::currentHandler()->firstInteraction())
     throw Exception() << error
 		      << "POWHEG matching requested for LO events.  Include "
 		      << "'set Factory:ShowerApproximation MEMatching' in input file."
 		      << Exception::runerror;
 
   _hardme = HwMEBasePtr();
   // extract the matrix element
   tStdXCombPtr lastXC = dynamic_ptr_cast<tStdXCombPtr>(xcomb);
   if(lastXC) {
     _hardme = dynamic_ptr_cast<HwMEBasePtr>(lastXC->matrixElement());
   }
   _decayme = HwDecayerBasePtr();
   // set the current tree
   currentTree(hard);
   hardTree(HardTreePtr());
   // number of attempts if more than one interaction switched on
   unsigned int interactionTry=0;
   do {
     try {
       // generate the showering
       doShowering(true,xcomb);
       // if no vetos return
       return;
     }
     catch (InteractionVeto) {
       currentTree()->clear();
       ++interactionTry;
     }
   }
   while(interactionTry<=5);
   throw Exception() << "Too many tries for shower in "
 		    << "Evolver::showerHardProcess()"
 		    << Exception::eventerror;
 }
 
 void Evolver::hardMatrixElementCorrection(bool hard) {
   // set the initial enhancement factors for the soft correction
   _initialenhance = 1.;
   _finalenhance   = 1.;
   // if hard matrix element switched off return
   if(!MECOn(hard)) return;
   // see if we can get the correction from the matrix element
   // or decayer
   if(hard) {
     if(_hardme&&_hardme->hasMECorrection()) {
       _hardme->initializeMECorrection(_currenttree,
 				      _initialenhance,_finalenhance);
       if(hardMEC(hard))
 	_hardme->applyHardMatrixElementCorrection(_currenttree);
     }
   }
   else {
     if(_decayme&&_decayme->hasMECorrection()) {
       _decayme->initializeMECorrection(_currenttree,
 				       _initialenhance,_finalenhance);
       if(hardMEC(hard))
 	_decayme->applyHardMatrixElementCorrection(_currenttree);
     }
   }
 }
 
 ShowerParticleVector Evolver::createTimeLikeChildren(tShowerParticlePtr particle, IdList ids) {
   // Create the ShowerParticle objects for the two children of
   // the emitting particle; set the parent/child relationship
   // if same as definition create particles, otherwise create cc
   tcPDPtr pdata[2];
   for(unsigned int ix=0;ix<2;++ix) pdata[ix]=getParticleData(ids[ix+1]);
   if(particle->id()!=ids[0]) {
     for(unsigned int ix=0;ix<2;++ix) {
       tPDPtr cc(pdata[ix]->CC());
       if(cc) pdata[ix]=cc;
     }
   }
   ShowerParticleVector children;
   for(unsigned int ix=0;ix<2;++ix) {
     children.push_back(new_ptr(ShowerParticle(pdata[ix],true)));
     if(children[ix]->id()==_progenitor->id()&&!pdata[ix]->stable())
       children[ix]->set5Momentum(Lorentz5Momentum(_progenitor->progenitor()->mass()));
     else
       children[ix]->set5Momentum(Lorentz5Momentum(pdata[ix]->mass()));
   }
   return children;
 }
 
 bool Evolver::timeLikeShower(tShowerParticlePtr particle, 
 			     ShowerInteraction::Type type,
 			     Branching fb, bool first) {
   // don't do anything if not needed
   if(_limitEmissions == 1 || hardOnly() || 
      ( _limitEmissions == 2 && _nfs != 0) ||
      ( _limitEmissions == 4 && _nfs + _nis != 0) ) {
     if(particle->spinInfo()) particle->spinInfo()->develop();
     return false;
   }
   // too many tries
   if(_nFSR>=_maxTryFSR) {
     ++_nFailedFSR;
     // too many failed events
     if(_nFailedFSR>=_maxFailFSR)
       throw Exception() << "Too many events have failed due to too many shower emissions, in\n"
 			<< "Evolver::timeLikeShower(). Terminating run\n"
 			<< Exception::runerror;
     throw Exception() << "Too many attempted emissions in Evolver::timeLikeShower()\n"
 		      << Exception::eventerror;
   }
   // generate the emission
   ShowerParticleVector children;
   int ntry=0;
   // generate the emission
   if(!fb.kinematics) 
     fb = selectTimeLikeBranching(particle,type,HardBranchingPtr());
   // no emission, return
   if(!fb.kinematics) {
     if(particle->spinInfo()) particle->spinInfo()->develop();
     return false;
   }
   Branching fc[2];
   bool setupChildren = true;
   while (ntry<50) {
     fc[0] = Branching();
     fc[1] = Branching();
     ++ntry;
     assert(fb.kinematics);
     // has emitted
     // Assign the shower kinematics to the emitting particle.
     if(setupChildren) {
       ++_nFSR;
       particle->showerKinematics(fb.kinematics);
       // generate phi
       fb.kinematics->phi(fb.sudakov->generatePhiForward(*particle,fb.ids,fb.kinematics));
       // check highest pT
       if(fb.kinematics->pT()>progenitor()->highestpT())
 	progenitor()->highestpT(fb.kinematics->pT());
       // create the children
       children = createTimeLikeChildren(particle,fb.ids);
       // update the children
       particle->showerKinematics()->
 	updateChildren(particle, children,fb.type,_reconOpt>=3);
       // update number of emissions
       ++_nfs;
       if(_limitEmissions!=0) {
 	if(children[0]->spinInfo()) children[0]->spinInfo()->develop();
 	if(children[1]->spinInfo()) children[1]->spinInfo()->develop();
 	if(particle->spinInfo()) particle->spinInfo()->develop();
 	return true;
       }
       setupChildren = false;
     }
     // select branchings for children
     fc[0] = selectTimeLikeBranching(children[0],type,HardBranchingPtr());
     fc[1] = selectTimeLikeBranching(children[1],type,HardBranchingPtr());
     // old default
     if(_reconOpt==0) {
       // shower the first  particle
       if(fc[0].kinematics) timeLikeShower(children[0],type,fc[0],false);
       if(children[0]->spinInfo()) children[0]->spinInfo()->develop();
       // shower the second particle
       if(fc[1].kinematics) timeLikeShower(children[1],type,fc[1],false);
       if(children[1]->spinInfo()) children[1]->spinInfo()->develop();
       break;
     }
     // Herwig default
     else if(_reconOpt==1) {
       // shower the first  particle
       if(fc[0].kinematics) timeLikeShower(children[0],type,fc[0],false);
       if(children[0]->spinInfo()) children[0]->spinInfo()->develop();
       // shower the second particle
       if(fc[1].kinematics) timeLikeShower(children[1],type,fc[1],false);
       if(children[1]->spinInfo()) children[1]->spinInfo()->develop();
       // branching has happened
       particle->showerKinematics()->updateParent(particle, children,fb.type);
       // clean up the vetoed emission
       if(particle->virtualMass()==ZERO) {
    	particle->showerKinematics(ShoKinPtr());
    	for(unsigned int ix=0;ix<children.size();++ix)
    	  particle->abandonChild(children[ix]);
    	children.clear();
    	if(particle->spinInfo()) particle->spinInfo()->decayVertex(VertexPtr());
 	particle->vetoEmission(fb.type,fb.kinematics->scale());
 	// generate the new emission
 	fb = selectTimeLikeBranching(particle,type,HardBranchingPtr());
 	// no emission, return
 	if(!fb.kinematics) {
 	  if(particle->spinInfo()) particle->spinInfo()->develop();
 	  return false;
 	}
 	setupChildren = true;
 	continue;
       }
       else
 	break;
     }
     // veto children
     else if(_reconOpt>=2) {
       // cut-off masses for the branching
       const vector<Energy> & virtualMasses = fb.sudakov->virtualMasses(fb.ids);
       // compute the masses of the children
       Energy masses[3];
       for(unsigned int ix=0;ix<2;++ix) {
    	if(fc[ix].kinematics) {
    	  const vector<Energy> & vm = fc[ix].sudakov->virtualMasses(fc[ix].ids);
    	  Energy2 q2 = 
    	    fc[ix].kinematics->z()*(1.-fc[ix].kinematics->z())*sqr(fc[ix].kinematics->scale());
    	  if(fc[ix].ids[0]!=ParticleID::g) q2 += sqr(vm[0]);
    	  masses[ix+1] = sqrt(q2);
    	}
    	else {
    	  masses[ix+1] = virtualMasses[ix+1];
    	}
       }
       masses[0] = fb.ids[0]!=ParticleID::g ? virtualMasses[0] : ZERO;
       double z = fb.kinematics->z();
       Energy2 pt2 = z*(1.-z)*(z*(1.-z)*sqr(fb.kinematics->scale()) + sqr(masses[0]))
    	- sqr(masses[1])*(1.-z) - sqr(masses[2])*z;
       if(pt2>=ZERO) {
 	break;
       }
       else {
 	// reset the scales for the children
 	for(unsigned int ix=0;ix<2;++ix) {
 	  if(fc[ix].kinematics)
 	    children[ix]->vetoEmission(fc[ix].type,fc[ix].kinematics->scale());
 	  else
 	    children[ix]->vetoEmission(ShowerPartnerType::QCDColourLine,ZERO);
 	  children[ix]->virtualMass(ZERO);
 	} 
       }
     }
   };
   if(_reconOpt>=2) {
     // shower the first  particle
     if(fc[0].kinematics) timeLikeShower(children[0],type,fc[0],false);
     if(children[0]->spinInfo()) children[0]->spinInfo()->develop();
     // shower the second particle
     if(fc[1].kinematics) timeLikeShower(children[1],type,fc[1],false);
     if(children[1]->spinInfo()) children[1]->spinInfo()->develop();
     // branching has happened
       particle->showerKinematics()->updateParent(particle, children,fb.type);
   }
   if(first&&!children.empty())
     particle->showerKinematics()->resetChildren(particle,children);
   if(particle->spinInfo()) particle->spinInfo()->develop();
   return true;
 }
 
 bool 
 Evolver::spaceLikeShower(tShowerParticlePtr particle, PPtr beam,
 			 ShowerInteraction::Type type) {
   //using the pdf's associated with the ShowerHandler assures, that
   //modified pdf's are used for the secondary interactions via 
   //CascadeHandler::resetPDFs(...)
   tcPDFPtr pdf;
   if(ShowerHandler::currentHandler()->firstPDF().particle() == _beam)
     pdf = ShowerHandler::currentHandler()->firstPDF().pdf();
   if(ShowerHandler::currentHandler()->secondPDF().particle() == _beam)
     pdf = ShowerHandler::currentHandler()->secondPDF().pdf();
   Energy freeze = ShowerHandler::currentHandler()->pdfFreezingScale();
   // don't do anything if not needed
   if(_limitEmissions == 2  || hardOnly() ||
      ( _limitEmissions == 1 && _nis != 0 ) ||
      ( _limitEmissions == 4 && _nis + _nfs != 0 ) ) {
     if(particle->spinInfo()) particle->spinInfo()->develop();
     return false;
   }
   Branching bb;
   // generate branching
   while (true) {
     bb=_splittingGenerator->chooseBackwardBranching(*particle,beam,
 						    _initialenhance,
 						    _beam,type,
 						    pdf,freeze);
     // return if no emission
     if(!bb.kinematics) {
       if(particle->spinInfo()) particle->spinInfo()->develop();
       return false;
     }
     // if not vetoed break
     if(!spaceLikeVetoed(bb,particle)) break;
     // otherwise reset scale and continue
     particle->vetoEmission(bb.type,bb.kinematics->scale());
     if(particle->spinInfo()) particle->spinInfo()->decayVertex(VertexPtr());
   }
   // assign the splitting function and shower kinematics
   particle->showerKinematics(bb.kinematics);
   if(bb.kinematics->pT()>progenitor()->highestpT())
     progenitor()->highestpT(bb.kinematics->pT());
   // For the time being we are considering only 1->2 branching
   // particles as in Sudakov form factor
   tcPDPtr part[2]={getParticleData(bb.ids[0]),
 		   getParticleData(bb.ids[2])};
   if(particle->id()!=bb.ids[1]) {
     if(part[0]->CC()) part[0]=part[0]->CC();
     if(part[1]->CC()) part[1]=part[1]->CC();
   }
   // Now create the actual particles, make the otherChild a final state
   // particle, while the newParent is not
   ShowerParticlePtr newParent=new_ptr(ShowerParticle(part[0],false));
   ShowerParticlePtr otherChild = new_ptr(ShowerParticle(part[1],true,true));
   ShowerParticleVector theChildren;
   theChildren.push_back(particle); 
   theChildren.push_back(otherChild);
   //this updates the evolution scale
   particle->showerKinematics()->
     updateParent(newParent, theChildren,bb.type);
   // update the history if needed
   _currenttree->updateInitialStateShowerProduct(_progenitor,newParent);
   _currenttree->addInitialStateBranching(particle,newParent,otherChild);
   // for the reconstruction of kinematics, parent/child
   // relationships are according to the branching process:
   // now continue the shower
   ++_nis;
   bool emitted = _limitEmissions==0 ? 
     spaceLikeShower(newParent,beam,type) : false;
   if(newParent->spinInfo()) newParent->spinInfo()->develop();
   // now reconstruct the momentum
   if(!emitted) {
     if(_intrinsic.find(_progenitor)==_intrinsic.end()) {
       bb.kinematics->updateLast(newParent,ZERO,ZERO);
     }
     else {
       pair<Energy,double> kt=_intrinsic[_progenitor];
       bb.kinematics->updateLast(newParent,
 				kt.first*cos(kt.second),
 				kt.first*sin(kt.second));
     }
   }
   particle->showerKinematics()->
     updateChildren(newParent, theChildren,bb.type,false);
   if(_limitEmissions!=0) {
     if(particle->spinInfo()) particle->spinInfo()->develop();
     return true;
   }
   // perform the shower of the final-state particle
   timeLikeShower(otherChild,type,Branching(),true);
   updateHistory(otherChild);
   if(theChildren[1]->spinInfo()) theChildren[1]->spinInfo()->develop();
   // return the emitted
   if(particle->spinInfo()) particle->spinInfo()->develop();
   return true;
 }
 
 void Evolver::showerDecay(ShowerTreePtr decay) {
   _decayme = HwDecayerBasePtr();
   _hardme  = HwMEBasePtr();
   // find the decayer
   // try the normal way if possible
   tDMPtr dm = decay->incomingLines().begin()->first->original()   ->decayMode();
   if(!dm) dm = decay->incomingLines().begin()->first->copy()      ->decayMode();
   if(!dm) dm = decay->incomingLines().begin()->first->progenitor()->decayMode();
   // otherwise make a string and look it up
   if(!dm) {
     string tag = decay->incomingLines().begin()->first->original()->dataPtr()->name() 
       + "->";
     OrderedParticles outgoing;
     for(map<ShowerProgenitorPtr,tShowerParticlePtr>::const_iterator 
 	  it=decay->outgoingLines().begin();it!=decay->outgoingLines().end();++it) {
       if(abs(decay->incomingLines().begin()->first->original()->id()) == ParticleID::t &&
 	 abs(it->first->original()->id())==ParticleID::Wplus &&
 	 decay->treelinks().size() == 1) {
 	ShowerTreePtr Wtree = decay->treelinks().begin()->first;
 	for(map<ShowerProgenitorPtr,tShowerParticlePtr>::const_iterator
 	      it2=Wtree->outgoingLines().begin();it2!=Wtree->outgoingLines().end();++it2) {
 	  outgoing.insert(it2->first->original()->dataPtr());
 	}
       }
       else {
 	outgoing.insert(it->first->original()->dataPtr());
       }
     }
     for(OrderedParticles::const_iterator it=outgoing.begin(); it!=outgoing.end();++it) {
       if(it!=outgoing.begin()) tag += ",";
       tag +=(**it).name();
     }
     tag += ";";
     dm = findDecayMode(tag);
   }
   if(dm) _decayme = dynamic_ptr_cast<HwDecayerBasePtr>(dm->decayer());
   // set the ShowerTree to be showered
   currentTree(decay);
   decay->applyTransforms();
   hardTree(HardTreePtr());
   unsigned int interactionTry=0;
   do {
     try {
       // generate the showering
       doShowering(false,XCPtr());
       // if no vetos 
       // force calculation of spin correlations
       SpinPtr spInfo = decay->incomingLines().begin()->first->progenitor()->spinInfo();
       if(spInfo) {
 	if(!spInfo->developed()) spInfo->needsUpdate();
 	spInfo->develop();
       }
       // and then return
       return;
     }
     catch (InteractionVeto) {
       currentTree()->clear();
       ++interactionTry;
     }
   }
   while(interactionTry<=5);
   throw Exception() << "Too many tries for QED shower in Evolver::showerDecay()"
 		    << Exception::eventerror;
 }
 
 bool Evolver::spaceLikeDecayShower(tShowerParticlePtr particle,
 				   const ShowerParticle::EvolutionScales & maxScales,
 				   Energy minmass,ShowerInteraction::Type type,
 				   Branching fb) {
   // too many tries
   if(_nFSR>=_maxTryFSR) {
     ++_nFailedFSR;
     // too many failed events
     if(_nFailedFSR>=_maxFailFSR)
       throw Exception() << "Too many events have failed due to too many shower emissions, in\n"
 			<< "Evolver::timeLikeShower(). Terminating run\n"
 			<< Exception::runerror;
     throw Exception() << "Too many attempted emissions in Evolver::timeLikeShower()\n"
 		      << Exception::eventerror;
   }
   // generate the emission
   ShowerParticleVector children;
   int ntry=0;
   // generate the emission
   if(!fb.kinematics) 
     fb = selectSpaceLikeDecayBranching(particle,maxScales,minmass,type,
 				       HardBranchingPtr());
   // no emission, return
   if(!fb.kinematics) return false;
   Branching fc[2];
   bool setupChildren = true;
   while (ntry<50) {
     if(particle->virtualMass()==ZERO) 
       particle->virtualMass(_progenitor->progenitor()->mass());
     fc[0] = Branching();
     fc[1] = Branching();
     ++ntry;
     assert(fb.kinematics);
     // has emitted
     // Assign the shower kinematics to the emitting particle.
     if(setupChildren) {
       ++_nFSR;
       // Assign the shower kinematics to the emitting particle.
       particle->showerKinematics(fb.kinematics);
       if(fb.kinematics->pT()>progenitor()->highestpT())
 	progenitor()->highestpT(fb.kinematics->pT());
       // create the ShowerParticle objects for the two children
       children = createTimeLikeChildren(particle,fb.ids);
       // updateChildren the children
       particle->showerKinematics()->
 	updateChildren(particle, children, fb.type,_reconOpt>=3);
       setupChildren = false;
     }
     // select branchings for children
     fc[0] = selectSpaceLikeDecayBranching(children[0],maxScales,minmass,
 					  type,HardBranchingPtr());
     fc[1] = selectTimeLikeBranching      (children[1],type,HardBranchingPtr());
     // old default
     if(_reconOpt==0) {
       // shower the first  particle
       _currenttree->updateInitialStateShowerProduct(_progenitor,children[0]);
       _currenttree->addInitialStateBranching(particle,children[0],children[1]);
       if(fc[0].kinematics) spaceLikeDecayShower(children[0],maxScales,minmass,type,Branching());
       // shower the second particle
       if(fc[1].kinematics) timeLikeShower(children[1],type,fc[1],true);
       updateHistory(children[1]);
       // branching has happened
       break;
     }
     // Herwig default
     else if(_reconOpt==1) {
       // shower the first  particle
       _currenttree->updateInitialStateShowerProduct(_progenitor,children[0]);
       _currenttree->addInitialStateBranching(particle,children[0],children[1]);
       if(fc[0].kinematics) spaceLikeDecayShower(children[0],maxScales,minmass,type,Branching());
       // shower the second particle
       if(fc[1].kinematics) timeLikeShower(children[1],type,fc[1],true);
       updateHistory(children[1]);
       // branching has happened
       particle->showerKinematics()->updateParent(particle, children,fb.type);
       // clean up the vetoed emission
       if(particle->virtualMass()==ZERO) {
     	particle->showerKinematics(ShoKinPtr());
    	for(unsigned int ix=0;ix<children.size();++ix)
    	  particle->abandonChild(children[ix]);
     	children.clear();
  	particle->vetoEmission(fb.type,fb.kinematics->scale());
  	// generate the new emission
   	fb = selectSpaceLikeDecayBranching(particle,maxScales,minmass,type,
 				       HardBranchingPtr());
  	// no emission, return
   	if(!fb.kinematics) {
   	  return false;
    	}
   	setupChildren = true;
    	continue;
       }
       else
    	break;
     }
     else if(_reconOpt>=2) {
       // cut-off masses for the branching
       const vector<Energy> & virtualMasses = fb.sudakov->virtualMasses(fb.ids);
       // compute the masses of the children
       Energy masses[3];
       // space-like children
       masses[1] = children[0]->virtualMass();
       // time-like child
       if(fc[1].kinematics) {
 	const vector<Energy> & vm = fc[1].sudakov->virtualMasses(fc[1].ids);
 	Energy2 q2 = 
 	  fc[1].kinematics->z()*(1.-fc[1].kinematics->z())*sqr(fc[1].kinematics->scale());
 	if(fc[1].ids[0]!=ParticleID::g) q2 += sqr(vm[0]);
 	masses[2] = sqrt(q2);
       }
       else {
 	masses[2] = virtualMasses[2];
       } 
       masses[0]=particle->virtualMass();
       double z = fb.kinematics->z();
       Energy2 pt2 = (1.-z)*(z*sqr(masses[0])-sqr(masses[1])-z/(1.-z)*sqr(masses[2]));
       if(pt2>=ZERO) {
   	break;
       }
       else {
   	// reset the scales for the children
   	for(unsigned int ix=0;ix<2;++ix) {
   	  if(fc[ix].kinematics)
   	    children[ix]->vetoEmission(fc[ix].type,fc[ix].kinematics->scale());
   	  else {
 	    if(ix==0) 
 	      children[ix]->vetoEmission(ShowerPartnerType::QCDColourLine,Constants::MaxEnergy);
 	    else
 	      children[ix]->vetoEmission(ShowerPartnerType::QCDColourLine,ZERO);
 	  }
    	} 
 	children[0]->virtualMass(_progenitor->progenitor()->mass());
 	children[1]->virtualMass(ZERO);
       }
     }
   };
   if(_reconOpt>=2) {
     // In the case of splittings which involves coloured particles,
     // set properly the colour flow of the branching.
     // update the history if needed
     _currenttree->updateInitialStateShowerProduct(_progenitor,children[0]);
     _currenttree->addInitialStateBranching(particle,children[0],children[1]);
     // shower the first  particle
     if(fc[0].kinematics) spaceLikeDecayShower(children[0],maxScales,minmass,type,Branching());
     // shower the second particle
     if(fc[1].kinematics) timeLikeShower(children[1],type,fc[1],true);
     updateHistory(children[1]);
     // branching has happened
     particle->showerKinematics()->updateParent(particle, children,fb.type);
   }
   // branching has happened
   return true;
 }
 
 vector<ShowerProgenitorPtr> Evolver::setupShower(bool hard) {
   // generate POWHEG hard emission if needed
   if(_hardEmissionMode>0) hardestEmission(hard);
   ShowerInteraction::Type inter = interactions_[0];
   if(_hardtree&&inter!=ShowerInteraction::Both) {
     inter = _hardtree->interaction();
   }
   // set the initial colour partners
   setEvolutionPartners(hard,inter,false);
   // generate hard me if needed
   if(_hardEmissionMode==0 ||
      (!hard && _hardEmissionMode==-1)) hardMatrixElementCorrection(hard);
   // get the particles to be showered
   vector<ShowerProgenitorPtr> particlesToShower = 
     currentTree()->extractProgenitors();
   // remake the colour partners if needed
   if(_currenttree->hardMatrixElementCorrection()) {
     setEvolutionPartners(hard,interactions_[0],true);
     _currenttree->resetShowerProducts();
   }
   // return the answer
   return particlesToShower;
 }
 
 void Evolver::setEvolutionPartners(bool hard,ShowerInteraction::Type type,
 				   bool clear) {
   // match the particles in the ShowerTree and hardTree
   if(hardTree() && !hardTree()->connect(currentTree()))
     throw Exception() << "Can't match trees in "
 		      << "Evolver::setEvolutionPartners()"
 		      << Exception::eventerror;
   // extract the progenitors
   vector<ShowerParticlePtr> particles = 
     currentTree()->extractProgenitorParticles();
   // clear the partners if needed
   if(clear) {
     for(unsigned int ix=0;ix<particles.size();++ix) {
       particles[ix]->partner(ShowerParticlePtr());
       particles[ix]->clearPartners();
     }
   }
   // sort out the colour partners
   if(hardTree()) {
     // find the partner
     for(unsigned int ix=0;ix<particles.size();++ix) {
       tHardBranchingPtr partner = 
 	hardTree()->particles()[particles[ix]]->colourPartner();
       if(!partner) continue;
       for(map<ShowerParticlePtr,tHardBranchingPtr>::const_iterator
 	    it=hardTree()->particles().begin();
 	  it!=hardTree()->particles().end();++it) {
 	if(it->second==partner) particles[ix]->partner(it->first);
       }
       if(!particles[ix]->partner()) 
 	throw Exception() << "Can't match partners in "
 			  << "Evolver::setEvolutionPartners()"
 			  << Exception::eventerror;
     }
   }
   // Set the initial evolution scales
   showerModel()->partnerFinder()->
     setInitialEvolutionScales(particles,!hard,type,!_hardtree);
   if(hardTree() && _hardPOWHEG) {
     bool tooHard=false;
     map<ShowerParticlePtr,tHardBranchingPtr>::const_iterator 
       eit=hardTree()->particles().end();
     for(unsigned int ix=0;ix<particles.size();++ix) {
       map<ShowerParticlePtr,tHardBranchingPtr>::const_iterator 
 	mit = hardTree()->particles().find(particles[ix]);
       Energy hardScale(ZERO);
       ShowerPartnerType::Type type(ShowerPartnerType::Undefined);
       // final-state
       if(particles[ix]->isFinalState()) {
 	if(mit!= eit && !mit->second->children().empty()) {
 	  hardScale = mit->second->scale();
 	  type = mit->second->type();
 	}
       }
       // initial-state
       else {
 	if(mit!= eit && mit->second->parent()) {
 	  hardScale = mit->second->parent()->scale();
 	  type = mit->second->parent()->type();
 	}
       }
       if(type!=ShowerPartnerType::Undefined) {
 	if(type==ShowerPartnerType::QED) {
 	  tooHard |= particles[ix]->scales().QED_noAO<hardScale;
 	}
 	else if(type==ShowerPartnerType::QCDColourLine) {
 	  tooHard |= particles[ix]->scales().QCD_c_noAO<hardScale;
 	}
 	else if(type==ShowerPartnerType::QCDAntiColourLine) {
 	  tooHard |= particles[ix]->scales().QCD_ac_noAO<hardScale;
 	}
       }
     }
     if(tooHard) convertHardTree(hard,type);
   }
 }
 
 void Evolver::updateHistory(tShowerParticlePtr particle) {
   if(!particle->children().empty()) {
     ShowerParticleVector theChildren;
     for(unsigned int ix=0;ix<particle->children().size();++ix) {
       ShowerParticlePtr part = dynamic_ptr_cast<ShowerParticlePtr>
 	(particle->children()[ix]);
       theChildren.push_back(part);
     }
     // update the history if needed
     if(particle==_currenttree->getFinalStateShowerProduct(_progenitor))
       _currenttree->updateFinalStateShowerProduct(_progenitor,
 						  particle,theChildren);
     _currenttree->addFinalStateBranching(particle,theChildren);
     for(unsigned int ix=0;ix<theChildren.size();++ix)
       updateHistory(theChildren[ix]);
   }
 }
 
 bool Evolver::startTimeLikeShower(ShowerInteraction::Type type) {
   _nFSR = 0;
   if(hardTree()) {
     map<ShowerParticlePtr,tHardBranchingPtr>::const_iterator 
       eit=hardTree()->particles().end(),
       mit = hardTree()->particles().find(progenitor()->progenitor());
     if( mit != eit && !mit->second->children().empty() ) {
       bool output=truncatedTimeLikeShower(progenitor()->progenitor(),
 					  mit->second ,type,Branching(),true);
       if(output) updateHistory(progenitor()->progenitor());
       return output;
     }
   }
   bool output = hardOnly() ? false :
     timeLikeShower(progenitor()->progenitor() ,type,Branching(),true) ;
   if(output) updateHistory(progenitor()->progenitor());
   return output;
 }
 
 bool Evolver::startSpaceLikeShower(PPtr parent, ShowerInteraction::Type type) {
   if(hardTree()) {
     map<ShowerParticlePtr,tHardBranchingPtr>::const_iterator 
       eit =hardTree()->particles().end(),
       mit = hardTree()->particles().find(progenitor()->progenitor());
     if( mit != eit && mit->second->parent() ) {
       return truncatedSpaceLikeShower( progenitor()->progenitor(),
 				       parent, mit->second->parent(), type );
     } 
   }
   return  hardOnly() ? false :
     spaceLikeShower(progenitor()->progenitor(),parent,type);
 }
 
 bool Evolver::
 startSpaceLikeDecayShower(const ShowerParticle::EvolutionScales & maxScales,
 			  Energy minimumMass,ShowerInteraction::Type type) {
   _nFSR = 0;
   if(hardTree()) {
     map<ShowerParticlePtr,tHardBranchingPtr>::const_iterator 
       eit =hardTree()->particles().end(),
       mit = hardTree()->particles().find(progenitor()->progenitor());
     if( mit != eit && mit->second->parent() ) {
       HardBranchingPtr branch=mit->second;
       while(branch->parent()) branch=branch->parent();
       return truncatedSpaceLikeDecayShower(progenitor()->progenitor(),maxScales,
 					   minimumMass, branch ,type, Branching());
     }
   }
   return  hardOnly() ? false :
     spaceLikeDecayShower(progenitor()->progenitor(),maxScales,minimumMass,type,Branching());
 }
 
 bool Evolver::timeLikeVetoed(const Branching & fb,
 			     ShowerParticlePtr particle) {
   // work out type of interaction
   ShowerInteraction::Type type = fb.type==ShowerPartnerType::QED ? 
     ShowerInteraction::QED : ShowerInteraction::QCD;
   // check whether emission was harder than largest pt of hard subprocess
   if ( hardVetoFS() && fb.kinematics->pT() > _progenitor->maxHardPt() ) 
     return true;
   // soft matrix element correction veto
   if( softMEC()) {
     if(_hardme && _hardme->hasMECorrection()) {
       if(_hardme->softMatrixElementVeto(_progenitor,particle,fb))
 	return true;
     }
     else if(_decayme && _decayme->hasMECorrection()) {
       if(_decayme->softMatrixElementVeto(_progenitor,particle,fb))
 	return true;
     }
   }
   // veto on maximum pt
   if(fb.kinematics->pT()>_progenitor->maximumpT(type)) return true;
   // general vetos
   if (fb.kinematics && !_vetoes.empty()) {
     bool vetoed=false;
     for (vector<ShowerVetoPtr>::iterator v = _vetoes.begin();
 	 v != _vetoes.end(); ++v) {
       bool test = (**v).vetoTimeLike(_progenitor,particle,fb);
       switch((**v).vetoType()) {
       case ShowerVeto::Emission:
 	vetoed |= test;
 	break;
       case ShowerVeto::Shower:
 	if(test) throw VetoShower();
 	break;
       case ShowerVeto::Event:
 	if(test) throw Veto();
 	break;
       }
     }
     if(vetoed) return true;
   }
   if ( ShowerHandler::currentHandler()->firstInteraction() &&
        ShowerHandler::currentHandler()->profileScales() ) {
     double weight = 
       ShowerHandler::currentHandler()->profileScales()->
       hardScaleProfile(_progenitor->hardScale(),fb.kinematics->pT());
     if ( UseRandom::rnd() > weight )
       return true;
   }
   return false;
 }
 
 bool Evolver::spaceLikeVetoed(const Branching & bb,
 			      ShowerParticlePtr particle) {
   // work out type of interaction
   ShowerInteraction::Type type = bb.type==ShowerPartnerType::QED ? 
     ShowerInteraction::QED : ShowerInteraction::QCD;
   // check whether emission was harder than largest pt of hard subprocess
   if (hardVetoIS() && bb.kinematics->pT() > _progenitor->maxHardPt())
     return true;
   // apply the soft correction
   if( softMEC() && _hardme && _hardme->hasMECorrection() ) {
     if(_hardme->softMatrixElementVeto(_progenitor,particle,bb))
       return true;
   }
   // the more general vetos
 
   // check vs max pt for the shower
   if(bb.kinematics->pT()>_progenitor->maximumpT(type)) return true;
 
   if (!_vetoes.empty()) {
     bool vetoed=false;
     for (vector<ShowerVetoPtr>::iterator v = _vetoes.begin();
 	 v != _vetoes.end(); ++v) {
       bool test = (**v).vetoSpaceLike(_progenitor,particle,bb);
       switch ((**v).vetoType()) {
       case ShowerVeto::Emission:
 	vetoed |= test;
 	break;
       case ShowerVeto::Shower:
 	if(test) throw VetoShower();
 	break;
       case ShowerVeto::Event:
 	if(test) throw Veto();
 	break;
       }
     }
     if (vetoed) return true;
   }
   if ( ShowerHandler::currentHandler()->firstInteraction() &&
        ShowerHandler::currentHandler()->profileScales() ) {
     double weight = 
       ShowerHandler::currentHandler()->profileScales()->
       hardScaleProfile(_progenitor->hardScale(),bb.kinematics->pT());
     if ( UseRandom::rnd() > weight )
       return true;
   }
   return false;
 }
 
 bool Evolver::spaceLikeDecayVetoed( const Branching & fb,
 				    ShowerParticlePtr particle) {
   // work out type of interaction
   ShowerInteraction::Type type = fb.type==ShowerPartnerType::QED ? 
     ShowerInteraction::QED : ShowerInteraction::QCD;
   // apply the soft correction
   if( softMEC() && _decayme && _decayme->hasMECorrection() ) {
     if(_decayme->softMatrixElementVeto(_progenitor,particle,fb))
       return true;
   }
   // veto on hardest pt in the shower
   if(fb.kinematics->pT()> _progenitor->maximumpT(type)) return true;
   // general vetos
   if (!_vetoes.empty()) {
     bool vetoed=false;
     for (vector<ShowerVetoPtr>::iterator v = _vetoes.begin();
 	 v != _vetoes.end(); ++v) {
       bool test = (**v).vetoSpaceLike(_progenitor,particle,fb);
       switch((**v).vetoType()) {
       case ShowerVeto::Emission:
 	vetoed |= test;
 	break;
       case ShowerVeto::Shower:
 	if(test) throw VetoShower();
 	break;
       case ShowerVeto::Event:
 	if(test) throw Veto();
 	break;
       }
       if (vetoed) return true;
     }
   }
   return false;
 }
 
 void Evolver::hardestEmission(bool hard) {
   HardTreePtr ISRTree;
   if(  ( _hardme  &&  _hardme->hasPOWHEGCorrection()!=0  && _hardEmissionMode< 2) ||
        ( _decayme && _decayme->hasPOWHEGCorrection()!=0  && _hardEmissionMode!=2) ) {
     if(_hardme) {
       assert(hard);
       if(interaction_==4) {
 	vector<ShowerInteraction::Type> inter(2);
 	inter[0] = ShowerInteraction::QCD;
 	inter[1] = ShowerInteraction::QED;
 	_hardtree =  _hardme->generateHardest( currentTree(),inter         );
       }
       else {
 	_hardtree =  _hardme->generateHardest( currentTree(),interactions_ );
       }
     }
     else {
       assert(!hard);
       _hardtree = _decayme->generateHardest( currentTree() );
     }
     // store initial state POWHEG radiation
     if(_hardtree && _hardme && _hardme->hasPOWHEGCorrection()==1) 
       ISRTree=_hardtree;
   }
 
   else if (_hardEmissionMode>1 && hard) {
     // Get minimum pT cutoff used in shower approximation
     Energy maxpt = 1.*GeV;
     int colouredIn  = 0;
     int colouredOut = 0;
     for( map< ShowerProgenitorPtr, tShowerParticlePtr >::iterator it
 	   = currentTree()->outgoingLines().begin(); 
 	 it != currentTree()->outgoingLines().end(); ++it ) {
       if( it->second->coloured() ) colouredOut+=1;
     }  
     for( map< ShowerProgenitorPtr, ShowerParticlePtr >::iterator it
 	   = currentTree()->incomingLines().begin(); 
 	 it != currentTree()->incomingLines().end(); ++it ) {
       if( ! it->second->coloured() ) colouredIn+=1;
     }
 
     if ( theShowerApproximation ){
       if ( theShowerApproximation->ffPtCut() == theShowerApproximation->fiPtCut() &&
 	   theShowerApproximation->ffPtCut() == theShowerApproximation->iiPtCut() ) 
 	maxpt = theShowerApproximation->ffPtCut();
       else if ( colouredIn == 2 && colouredOut == 0 )
 	maxpt = theShowerApproximation->iiPtCut();
       else if ( colouredIn == 0 && colouredOut > 1 )
 	maxpt = theShowerApproximation->ffPtCut();
       else if ( colouredIn == 2 && colouredOut == 1 )
 	maxpt = min(theShowerApproximation->iiPtCut(), theShowerApproximation->fiPtCut());
       else if ( colouredIn == 1 && colouredOut > 1 )
 	maxpt = min(theShowerApproximation->ffPtCut(), theShowerApproximation->fiPtCut());
       else 
 	maxpt = min(min(theShowerApproximation->iiPtCut(), theShowerApproximation->fiPtCut()), 
 		    theShowerApproximation->ffPtCut());
     }
 
     // Generate hardtree from born and real emission subprocesses
     _hardtree = ShowerHandler::currentHandler()->generateCKKW(currentTree());
 
     // Find transverse momentum of hardest emission
     if (_hardtree){
       for(set<HardBranchingPtr>::iterator it=_hardtree->branchings().begin();
      	  it!=_hardtree->branchings().end();++it) {
       	if ((*it)->parent() && (*it)->status()==HardBranching::Incoming)
       	  maxpt=(*it)->branchingParticle()->momentum().perp();
       	if ((*it)->children().size()==2 && (*it)->status()==HardBranching::Outgoing){
 	  if ((*it)->branchingParticle()->id()!=21 &&
 	      abs((*it)->branchingParticle()->id())>5 ){
 	    if ((*it)->children()[0]->branchingParticle()->id()==21 ||
 		abs((*it)->children()[0]->branchingParticle()->id())<6)
 	      maxpt=(*it)->children()[0]->branchingParticle()->momentum().perp();
 	    else if ((*it)->children()[1]->branchingParticle()->id()==21 ||
 		     abs((*it)->children()[1]->branchingParticle()->id())<6)
 	      maxpt=(*it)->children()[1]->branchingParticle()->momentum().perp();
 	  }
 	  else {
 	    if ( abs((*it)->branchingParticle()->id())<6){
 	      if (abs((*it)->children()[0]->branchingParticle()->id())<6)
 		maxpt = (*it)->children()[1]->branchingParticle()->momentum().perp();
 	      else 
 		maxpt = (*it)->children()[0]->branchingParticle()->momentum().perp();
 	    }
 	    else maxpt = (*it)->children()[1]->branchingParticle()->momentum().perp();
 	  }
       	}
       } 
     }
      
     
     // Hardest (pt) emission should be the first powheg emission.
-    maxpt=min(sqrt(ShowerHandler::currentHandler()->lastXCombPtr()->lastCentralScale()),maxpt);
+    maxpt=min(sqrt(ShowerHandler::currentHandler()->lastXCombPtr()->lastShowerScale()),maxpt);
 
     // Set maxpt to pT of emission when showering POWHEG real-emission subprocesses
     if (!isPowhegSEvent && !isPowhegHEvent){
       vector<int> outGluon;
       vector<int> outQuark;
       map< ShowerProgenitorPtr, tShowerParticlePtr >::iterator it;
       for( it = currentTree()->outgoingLines().begin(); 
 	   it != currentTree()->outgoingLines().end(); ++it ) {
 	if ( abs(it->second->id())< 6) outQuark.push_back(it->second->id());
 	if ( it->second->id()==21 )    outGluon.push_back(it->second->id());
       } 
       if (outGluon.size() + outQuark.size() == 1){
 	for( it = currentTree()->outgoingLines().begin(); 
 	     it != currentTree()->outgoingLines().end(); ++it ) {
 	  if ( abs(it->second->id())< 6 || it->second->id()==21 )
 	    maxpt = it->second->momentum().perp();
 	}
       }
       else if (outGluon.size() + outQuark.size() > 1){
 	// assume qqbar pair from a Z/gamma
 	if (outGluon.size()==1 && outQuark.size() == 2 && outQuark[0]==-outQuark[1]){
 	  for( it = currentTree()->outgoingLines().begin(); 
 	       it != currentTree()->outgoingLines().end(); ++it ) {
 	    if ( it->second->id()==21 )
 	      maxpt = it->second->momentum().perp();
 	  }
 	}
 	// otherwise take the lowest pT avoiding born DY events
 	else {
 	  maxpt = generator()->maximumCMEnergy();
 	  for( it = currentTree()->outgoingLines().begin(); 
 	       it != currentTree()->outgoingLines().end(); ++it ) {
 	    if ( abs(it->second->id())< 6 || it->second->id()==21 )
 	      maxpt = min(maxpt,it->second->momentum().perp());
 	  }
 	}
       }
     } 
 
     // set maximum pT for subsequent emissions from S events
     if ( isPowhegSEvent  || (!isPowhegSEvent && !isPowhegHEvent)){
       for( map< ShowerProgenitorPtr, tShowerParticlePtr >::iterator it
 	     = currentTree()->outgoingLines().begin(); 
 	   it != currentTree()->outgoingLines().end(); ++it ) {
 	if( ! it->second->coloured() ) continue;
 	it->first->maximumpT(maxpt, ShowerInteraction::QCD  );
       }  
       for( map< ShowerProgenitorPtr, ShowerParticlePtr >::iterator it
 	     = currentTree()->incomingLines().begin(); 
 	   it != currentTree()->incomingLines().end(); ++it ) {
 	if( ! it->second->coloured() ) continue;
 	it->first->maximumpT(maxpt, ShowerInteraction::QCD );
       }
     }  
   }
   else 
     _hardtree = ShowerHandler::currentHandler()->generateCKKW(currentTree());
 
   // if hard me doesn't have a FSR powheg 
   // correction use decay powheg correction
   if (_hardme && _hardme->hasPOWHEGCorrection()<2) {      
     // check for intermediate colour singlet resonance
     const ParticleVector inter =  _hardme->subProcess()->intermediates();
     if (inter.size()!=1 || 
 	inter[0]->momentum().m2()/GeV2 < 0 || 
 	inter[0]->dataPtr()->iColour()!=PDT::Colour0){
       if(_hardtree) connectTrees(currentTree(),_hardtree,hard);
       return;
     }
    
     map<ShowerProgenitorPtr, tShowerParticlePtr > out = currentTree()->outgoingLines();
     // ignore cases where outgoing particles are not coloured
     if (out.size()!=2 ||
 	out. begin()->second->dataPtr()->iColour()==PDT::Colour0 ||
     	out.rbegin()->second->dataPtr()->iColour()==PDT::Colour0) {
       if(_hardtree) connectTrees(currentTree(),_hardtree,hard);
       return;
     }
     
     // look up decay mode
     tDMPtr dm;
     string tag;
     string inParticle = inter[0]->dataPtr()->name() + "->";
     vector<string> outParticles;
     outParticles.push_back(out.begin ()->first->progenitor()->dataPtr()->name());
     outParticles.push_back(out.rbegin()->first->progenitor()->dataPtr()->name());
     for (int it=0; it<2; ++it){
       tag = inParticle + outParticles[it] + "," + outParticles[(it+1)%2] + ";";
       dm = generator()->findDecayMode(tag);
       if(dm) break;
     }
 
     // get the decayer
     HwDecayerBasePtr decayer;   
     if(dm) decayer = dynamic_ptr_cast<HwDecayerBasePtr>(dm->decayer());
     // check if decayer has a FSR POWHEG correction 
     if (!decayer || decayer->hasPOWHEGCorrection()<2){
       if(_hardtree) connectTrees(currentTree(),_hardtree,hard);
       return;
     }
     
     // generate the hardest emission
     ShowerDecayMap decay;
     PPtr in = new_ptr(*inter[0]);
     ShowerTreePtr decayTree = new_ptr(ShowerTree(in, decay));
     HardTreePtr     FSRTree = decayer->generateHardest(decayTree); 
     if (!FSRTree) {
       if(_hardtree) connectTrees(currentTree(),_hardtree,hard);
       return;
     }
 
     // if there is no ISRTree make _hardtree from FSRTree
     if (!ISRTree){
       vector<HardBranchingPtr> inBranch,hardBranch;
       for(map<ShowerProgenitorPtr,ShowerParticlePtr>::const_iterator
 	  cit =currentTree()->incomingLines().begin();
 	  cit!=currentTree()->incomingLines().end();++cit ) {
 	inBranch.push_back(new_ptr(HardBranching(cit->second,SudakovPtr(),
 						 HardBranchingPtr(),
 						 HardBranching::Incoming)));
 	inBranch.back()->beam(cit->first->original()->parents()[0]);
 	hardBranch.push_back(inBranch.back());
       }
       if(inBranch[0]->branchingParticle()->dataPtr()->coloured()) {
 	inBranch[0]->colourPartner(inBranch[1]);
 	inBranch[1]->colourPartner(inBranch[0]);
       }
       for(set<HardBranchingPtr>::iterator it=FSRTree->branchings().begin();
 	  it!=FSRTree->branchings().end();++it) {
 	if((**it).branchingParticle()->id()!=in->id()) 
 	  hardBranch.push_back(*it);
       } 
       hardBranch[2]->colourPartner(hardBranch[3]);
       hardBranch[3]->colourPartner(hardBranch[2]);
       HardTreePtr newTree = new_ptr(HardTree(hardBranch,inBranch,
 					     ShowerInteraction::QCD));            
       _hardtree = newTree;    
     }
 
     // Otherwise modify the ISRTree to include the emission in FSRTree
     else {    
       vector<tShowerParticlePtr> FSROut, ISROut;   
       set<HardBranchingPtr>::iterator itFSR, itISR;
       // get outgoing particles 
       for(itFSR =FSRTree->branchings().begin();
 	  itFSR!=FSRTree->branchings().end();++itFSR){
 	if ((**itFSR).status()==HardBranching::Outgoing) 
 	  FSROut.push_back((*itFSR)->branchingParticle());
       }     
       for(itISR =ISRTree->branchings().begin();
 	  itISR!=ISRTree->branchings().end();++itISR){
 	if ((**itISR).status()==HardBranching::Outgoing) 
 	  ISROut.push_back((*itISR)->branchingParticle());
       }
 
       // find COM frame formed by outgoing particles
       LorentzRotation eventFrameFSR, eventFrameISR;
       eventFrameFSR = ((FSROut[0]->momentum()+FSROut[1]->momentum()).findBoostToCM());  
       eventFrameISR = ((ISROut[0]->momentum()+ISROut[1]->momentum()).findBoostToCM());
 
       // find rotation between ISR and FSR frames
       int j=0;
       if (ISROut[0]->id()!=FSROut[0]->id()) j=1;
       eventFrameISR.rotateZ( (eventFrameFSR*FSROut[0]->momentum()).phi()-
 			     (eventFrameISR*ISROut[j]->momentum()).phi() );
       eventFrameISR.rotateY( (eventFrameFSR*FSROut[0]->momentum()).theta()-
 			     (eventFrameISR*ISROut[j]->momentum()).theta() );
       eventFrameISR.invert();
 
       for (itFSR=FSRTree->branchings().begin();
 	   itFSR!=FSRTree->branchings().end();++itFSR){
 	if ((**itFSR).branchingParticle()->id()==in->id()) continue;
 	for (itISR =ISRTree->branchings().begin();
 	     itISR!=ISRTree->branchings().end();++itISR){
 	  if ((**itISR).status()==HardBranching::Incoming) continue;
 	  if ((**itFSR).branchingParticle()->id()==
 	      (**itISR).branchingParticle()->id()){
 	    // rotate FSRTree particle to ISRTree event frame
 	    (**itISR).branchingParticle()->setMomentum(eventFrameISR*
 						       eventFrameFSR*
 			  (**itFSR).branchingParticle()->momentum());
 	    (**itISR).branchingParticle()->rescaleMass();
 	    // add the children of the FSRTree particles to the ISRTree
 	    if(!(**itFSR).children().empty()){
 	      (**itISR).addChild((**itFSR).children()[0]);
 	      (**itISR).addChild((**itFSR).children()[1]);
 	      // rotate momenta to ISRTree event frame
 	      (**itISR).children()[0]->branchingParticle()->setMomentum(eventFrameISR*
 									eventFrameFSR*
 			    (**itFSR).children()[0]->branchingParticle()->momentum());
 	      (**itISR).children()[1]->branchingParticle()->setMomentum(eventFrameISR*
 									eventFrameFSR*
 			    (**itFSR).children()[1]->branchingParticle()->momentum());
 	    }
 	  }
 	}	
       }
       _hardtree = ISRTree;
     }
   }
   if(_hardtree){
     connectTrees(currentTree(),_hardtree,hard); 
   }
 }
 
 bool Evolver::truncatedTimeLikeShower(tShowerParticlePtr particle,
 				      HardBranchingPtr branch,
 				      ShowerInteraction::Type type,
 				      Branching fb, bool first) {
   // select a branching if we don't have one
   if(!fb.kinematics)
     fb = selectTimeLikeBranching(particle,type,branch);
   // must be an emission, the forced one it not a truncated one
   assert(fb.kinematics);
   ShowerParticleVector children;
   int ntry=0;
   Branching fc[2];
   bool setupChildren = true;
   while (ntry<50) {
     if(!fc[0].hard) fc[0] = Branching();
     if(!fc[1].hard) fc[1] = Branching();
     ++ntry;
     // Assign the shower kinematics to the emitting particle.
     if(setupChildren) {
       ++_nFSR;
       // Assign the shower kinematics to the emitting particle.
       particle->showerKinematics(fb.kinematics);
       if(fb.kinematics->pT()>progenitor()->highestpT())
 	progenitor()->highestpT(fb.kinematics->pT());
       // if not hard generate phi
       if(!fb.hard)
 	fb.kinematics->phi(fb.sudakov->generatePhiForward(*particle,fb.ids,fb.kinematics));
       // create the children
       children = createTimeLikeChildren(particle,fb.ids);
       // update the children
       particle->showerKinematics()->
    	updateChildren(particle, children,fb.type,_reconOpt>=3);
       setupChildren = false;
     }
     // select branchings for children
     if(!fc[0].kinematics) {
       // select branching for first particle
       if(!fb.hard && fb.iout ==1 )
 	fc[0] = selectTimeLikeBranching(children[0],type,branch);
       else if(fb.hard && !branch->children()[0]->children().empty() )
 	fc[0] = selectTimeLikeBranching(children[0],type,branch->children()[0]);
       else
 	fc[0] = selectTimeLikeBranching(children[0],type,HardBranchingPtr());
     }
     // select branching for the second particle
     if(!fc[1].kinematics) {
       // select branching for first particle
       if(!fb.hard && fb.iout ==2 )
 	fc[1] = selectTimeLikeBranching(children[1],type,branch);
       else if(fb.hard && !branch->children()[1]->children().empty() )
 	fc[1] = selectTimeLikeBranching(children[1],type,branch->children()[1]);
       else
 	fc[1] = selectTimeLikeBranching(children[1],type,HardBranchingPtr());
     }
     // old default
     if(_reconOpt==0 || (_reconOpt==1 && fb.hard) ) {
       // shower the first  particle
       if(fc[0].kinematics) {
 	// the parent has truncated emission and following line
 	if(!fb.hard && fb.iout == 1)
 	  truncatedTimeLikeShower(children[0],branch,type,fc[0],false);
 	// hard emission and subsquent hard emissions
 	else if(fb.hard && !branch->children()[0]->children().empty() )
 	  truncatedTimeLikeShower(children[0],branch->children()[0],type,fc[0],false);
 	// normal shower
 	else
 	  timeLikeShower(children[0],type,fc[0],false);
       }
       if(children[0]->spinInfo()) children[0]->spinInfo()->develop();
       // shower the second particle
       if(fc[1].kinematics) {
 	// the parent has truncated emission and following line
 	if(!fb.hard && fb.iout == 2)
 	  truncatedTimeLikeShower(children[1],branch,type,fc[1],false);
 	// hard emission and subsquent hard emissions
 	else if(fb.hard && !branch->children()[1]->children().empty() )
 	  truncatedTimeLikeShower(children[1],branch->children()[1],type,fc[1],false);
 	else
 	  timeLikeShower(children[1],type,fc[1],false);
       }
       if(children[1]->spinInfo()) children[1]->spinInfo()->develop();
       // branching has happened
       particle->showerKinematics()->updateParent(particle, children,fb.type);
       break;
     }
     // H7 default
     else if(_reconOpt==1) {
       // shower the first  particle
       if(fc[0].kinematics) {
 	// the parent has truncated emission and following line
 	if(!fb.hard && fb.iout == 1)
 	  truncatedTimeLikeShower(children[0],branch,type,fc[0],false);
 	else
 	  timeLikeShower(children[0],type,fc[0],false);
       }
       if(children[0]->spinInfo()) children[0]->spinInfo()->develop();
       // shower the second particle
       if(fc[1].kinematics) {
 	// the parent has truncated emission and following line
 	if(!fb.hard && fb.iout == 2)
 	  truncatedTimeLikeShower(children[1],branch,type,fc[1],false);
 	else
 	  timeLikeShower(children[1],type,fc[1],false);
       }
       if(children[1]->spinInfo()) children[1]->spinInfo()->develop();
       // branching has happened
       particle->showerKinematics()->updateParent(particle, children,fb.type);
       // clean up the vetoed emission
       if(particle->virtualMass()==ZERO) {
    	particle->showerKinematics(ShoKinPtr());
     	for(unsigned int ix=0;ix<children.size();++ix)
    	  particle->abandonChild(children[ix]);
     	children.clear();
    	if(particle->spinInfo()) particle->spinInfo()->decayVertex(VertexPtr());
   	particle->vetoEmission(fb.type,fb.kinematics->scale());
    	// generate the new emission
    	fb = selectTimeLikeBranching(particle,type,branch);
 	// must be at least hard emission
 	assert(fb.kinematics);
    	setupChildren = true;
   	continue;
       }
       else
    	break;
     }
     else if(_reconOpt>=2) {
       // cut-off masses for the branching
       const vector<Energy> & virtualMasses = fb.sudakov->virtualMasses(fb.ids);
       // compute the masses of the children
       Energy masses[3];
       for(unsigned int ix=0;ix<2;++ix) {
    	if(fc[ix].kinematics) {
    	  const vector<Energy> & vm = fc[ix].sudakov->virtualMasses(fc[ix].ids);
    	  Energy2 q2 = 
    	    fc[ix].kinematics->z()*(1.-fc[ix].kinematics->z())*sqr(fc[ix].kinematics->scale());
    	  if(fc[ix].ids[0]!=ParticleID::g) q2 += sqr(vm[0]);
    	  masses[ix+1] = sqrt(q2);
    	}
    	else {
    	  masses[ix+1] = virtualMasses[ix+1];
    	}
       }
       masses[0] = fb.ids[0]!=ParticleID::g ? virtualMasses[0] : ZERO;
       double z = fb.kinematics->z();
       Energy2 pt2 = z*(1.-z)*(z*(1.-z)*sqr(fb.kinematics->scale()) + sqr(masses[0]))
    	- sqr(masses[1])*(1.-z) - sqr(masses[2])*z;
       if(pt2>=ZERO) {
   	break;
       }
       // if only the hard emission have to accept it
       else if ((fc[0].hard && !fc[1].kinematics) ||
 	       (fc[1].hard && !fc[0].kinematics) ) {
 	break;
       }
       else {
   	// reset the scales for the children
    	for(unsigned int ix=0;ix<2;++ix) {
 	  if(fc[ix].hard) continue;
    	  if(fc[ix].kinematics && ! fc[ix].hard )
    	    children[ix]->vetoEmission(fc[ix].type,fc[ix].kinematics->scale());
   	  else
   	    children[ix]->vetoEmission(ShowerPartnerType::QCDColourLine,ZERO);
   	  children[ix]->virtualMass(ZERO);
   	} 
       }
     }
   };
   if(_reconOpt>=2) {
     // shower the first  particle
     if(fc[0].kinematics) {
       // the parent has truncated emission and following line
       if(!fb.hard && fb.iout == 1)
 	truncatedTimeLikeShower(children[0],branch,type,fc[0],false);
       // hard emission and subsquent hard emissions
       else if(fb.hard && !branch->children()[0]->children().empty() )
 	truncatedTimeLikeShower(children[0],branch->children()[0],type,fc[0],false);
       // normal shower
       else
 	timeLikeShower(children[0],type,fc[0],false);
     }
     if(children[0]->spinInfo()) children[0]->spinInfo()->develop();
     // shower the second particle
     if(fc[1].kinematics) {
       // the parent has truncated emission and following line
       if(!fb.hard && fb.iout == 2)
 	truncatedTimeLikeShower(children[1],branch,type,fc[1],false);
       // hard emission and subsquent hard emissions
       else if(fb.hard && !branch->children()[1]->children().empty() )
 	truncatedTimeLikeShower(children[1],branch->children()[1],type,fc[1],false);
       else
 	timeLikeShower(children[1],type,fc[1],false);
     }
     if(children[1]->spinInfo()) children[1]->spinInfo()->develop();
     // branching has happened
     particle->showerKinematics()->updateParent(particle, children,fb.type);
   }
   if(first&&!children.empty())
     particle->showerKinematics()->resetChildren(particle,children);
   if(particle->spinInfo()) particle->spinInfo()->develop();
   return true;
 }
 
 bool Evolver::truncatedSpaceLikeShower(tShowerParticlePtr particle, PPtr beam,
 				       HardBranchingPtr branch,
 				       ShowerInteraction::Type type) {
   tcPDFPtr pdf;
   if(ShowerHandler::currentHandler()->firstPDF().particle()  == beamParticle())
     pdf = ShowerHandler::currentHandler()->firstPDF().pdf();
   if(ShowerHandler::currentHandler()->secondPDF().particle() == beamParticle())
     pdf = ShowerHandler::currentHandler()->secondPDF().pdf();
   Energy freeze = ShowerHandler::currentHandler()->pdfFreezingScale();
   Branching bb;
   // parameters of the force branching
   double z(0.);
   HardBranchingPtr timelike;
   for( unsigned int ix = 0; ix < branch->children().size(); ++ix ) {
     if( branch->children()[ix]->status() ==HardBranching::Outgoing) {
       timelike = branch->children()[ix];
     }
     if( branch->children()[ix]->status() ==HardBranching::Incoming )
       z = branch->children()[ix]->z();
   }
   // generate truncated branching
   tcPDPtr part[2];
   if(z>=0.&&z<=1.) {
     while (true) {
       if( !isTruncatedShowerON() || hardOnly() ) break;
       bb = splittingGenerator()->chooseBackwardBranching( *particle, 
 							  beam, 1., beamParticle(), 
 							  type , pdf,freeze);
       if( !bb.kinematics || bb.kinematics->scale() < branch->scale() ) {
 	bb = Branching();
 	break;
       }
       // particles as in Sudakov form factor
       part[0] = getParticleData( bb.ids[0] );
       part[1] = getParticleData( bb.ids[2] );
       
       //is emitter anti-particle
       if( particle->id() != bb.ids[1]) {
 	if( part[0]->CC() ) part[0] = part[0]->CC();
 	if( part[1]->CC() ) part[1] = part[1]->CC();
       }
       double zsplit = bb.kinematics->z();
       // apply the vetos for the truncated shower
       // if doesn't carry most of momentum
       ShowerInteraction::Type type2 = bb.type==ShowerPartnerType::QED ? 
 	ShowerInteraction::QED : ShowerInteraction::QCD;
       if(type2==branch->sudakov()->interactionType() &&
 	 zsplit < 0.5) {
 	particle->vetoEmission(bb.type,bb.kinematics->scale());
 	continue;
       }
       // others
       if( part[0]->id() != particle->id() || // if particle changes type
 	  bb.kinematics->pT() > progenitor()->maximumpT(type2) ||   // pt veto
 	  bb.kinematics->scale() < branch->scale()) { // angular ordering veto
 	particle->vetoEmission(bb.type,bb.kinematics->scale());
 	continue;
       }
       // and those from the base class
       if(spaceLikeVetoed(bb,particle)) {
 	particle->vetoEmission(bb.type,bb.kinematics->scale());
 	continue;
       }
       break;
     }
   }
   if( !bb.kinematics ) {
     //do the hard emission
     ShoKinPtr kinematics =
       branch->sudakov()->createInitialStateBranching( branch->scale(), z, branch->phi(),
     						      branch->children()[0]->pT() );
     kinematics->initialize( *particle, beam );
     // assign the splitting function and shower kinematics
     particle->showerKinematics( kinematics );
     if(kinematics->pT()>progenitor()->highestpT())
       progenitor()->highestpT(kinematics->pT());
     // For the time being we are considering only 1->2 branching
     // Now create the actual particles, make the otherChild a final state
     // particle, while the newParent is not
     ShowerParticlePtr newParent = 
       new_ptr( ShowerParticle( branch->branchingParticle()->dataPtr(), false ) );
     ShowerParticlePtr otherChild = 
       new_ptr( ShowerParticle( timelike->branchingParticle()->dataPtr(),
     			       true, true ) );
     ShowerParticleVector theChildren;
     theChildren.push_back( particle ); 
     theChildren.push_back( otherChild );
     particle->showerKinematics()->
       updateParent( newParent, theChildren, branch->type());
     // update the history if needed
     currentTree()->updateInitialStateShowerProduct( progenitor(), newParent );
     currentTree()->addInitialStateBranching( particle, newParent, otherChild );
     // for the reconstruction of kinematics, parent/child
     // relationships are according to the branching process:
     // now continue the shower
     bool emitted=false;
     if(!hardOnly()) {
       if( branch->parent() ) {
     	emitted = truncatedSpaceLikeShower( newParent, beam, branch->parent() , type);
       }
       else {
     	emitted = spaceLikeShower( newParent, beam , type);
       }
     }
     if( !emitted ) {
       if( intrinsicpT().find( progenitor() ) == intrinsicpT().end() ) {
     	kinematics->updateLast( newParent, ZERO, ZERO );
       }
       else {
     	pair<Energy,double> kt = intrinsicpT()[progenitor()];
     	kinematics->updateLast( newParent,
     				kt.first*cos( kt.second ),
     				kt.first*sin( kt.second ) );
       }
     }
     particle->showerKinematics()->
       updateChildren( newParent, theChildren,bb.type,false);
     if(hardOnly()) return true;
     // perform the shower of the final-state particle
     if( timelike->children().empty() ) {
       timeLikeShower( otherChild , type,Branching(),true);
     }
     else {
       truncatedTimeLikeShower( otherChild, timelike , type,Branching(), true);
     }
     updateHistory(otherChild);
     // return the emitted
     return true;
   }
   // assign the splitting function and shower kinematics
   particle->showerKinematics( bb.kinematics );
   if(bb.kinematics->pT()>progenitor()->highestpT())
     progenitor()->highestpT(bb.kinematics->pT());
   // For the time being we are considering only 1->2 branching
   // Now create the actual particles, make the otherChild a final state
   // particle, while the newParent is not
   ShowerParticlePtr newParent = new_ptr( ShowerParticle( part[0], false ) );
   ShowerParticlePtr otherChild = new_ptr( ShowerParticle( part[1], true, true ) );
   ShowerParticleVector theChildren; 
   theChildren.push_back( particle ); 
   theChildren.push_back( otherChild );
   particle->showerKinematics()->
     updateParent( newParent, theChildren, bb.type);
   // update the history if needed
   currentTree()->updateInitialStateShowerProduct( progenitor(), newParent );
   currentTree()->addInitialStateBranching( particle, newParent, otherChild );
   // for the reconstruction of kinematics, parent/child
   // relationships are according to the branching process:
   // now continue the shower
   bool emitted = truncatedSpaceLikeShower( newParent, beam, branch,type);
   // now reconstruct the momentum
   if( !emitted ) {
     if( intrinsicpT().find( progenitor() ) == intrinsicpT().end() ) {
       bb.kinematics->updateLast( newParent, ZERO, ZERO );
     }
     else {
       pair<Energy,double> kt = intrinsicpT()[ progenitor() ];
       bb.kinematics->updateLast( newParent,
 				 kt.first*cos( kt.second ),
 				 kt.first*sin( kt.second ) );
     }
   }
   particle->showerKinematics()->
     updateChildren( newParent, theChildren, bb.type,false);
   // perform the shower of the final-state particle
   timeLikeShower( otherChild , type,Branching(),true);
   updateHistory(otherChild);
   // return the emitted
   return true;
 }
 
 bool Evolver::
 truncatedSpaceLikeDecayShower(tShowerParticlePtr particle, 
 			      const ShowerParticle::EvolutionScales & maxScales,
 			      Energy minmass, HardBranchingPtr branch,
 			      ShowerInteraction::Type type, Branching fb) {
   // select a branching if we don't have one
   if(!fb.kinematics)
     fb = selectSpaceLikeDecayBranching(particle,maxScales,minmass,type,branch);
   // must be an emission, the forced one it not a truncated one
   assert(fb.kinematics);
   ShowerParticleVector children;
   int ntry=0;
   Branching fc[2];
   bool setupChildren = true;
   while (ntry<50) {
     if(!fc[0].hard) fc[0] = Branching();
     if(!fc[1].hard) fc[1] = Branching();
     ++ntry;
     if(setupChildren) {
       ++_nFSR;
       // Assign the shower kinematics to the emitting particle.
       particle->showerKinematics(fb.kinematics);
       if(fb.kinematics->pT()>progenitor()->highestpT())
 	progenitor()->highestpT(fb.kinematics->pT());
       // create the ShowerParticle objects for the two children
       children = createTimeLikeChildren(particle,fb.ids);
       // updateChildren the children
       particle->showerKinematics()->
 	updateChildren(particle, children, fb.type,_reconOpt>=3);
       setupChildren = false;
     }
     // select branchings for children
     if(!fc[0].kinematics) {
       if(children[0]->id()==particle->id()) {
 	// select branching for first particle
 	if(!fb.hard)
 	  fc[0] = selectSpaceLikeDecayBranching(children[0],maxScales,minmass,type,branch);
 	else if(fb.hard && ! branch->children()[0]->children().empty() )
 	  fc[0] = selectSpaceLikeDecayBranching(children[0],maxScales,minmass,type,
 						branch->children()[0]);
 	else
 	  fc[0] = selectSpaceLikeDecayBranching(children[0],maxScales,minmass,type,
 						HardBranchingPtr());
       }
       else {
 	// select branching for first particle
 	if(fb.hard && !branch->children()[0]->children().empty() )
 	  fc[0] = selectTimeLikeBranching(children[0],type,branch->children()[0]);
 	else
 	  fc[0] = selectTimeLikeBranching(children[0],type,HardBranchingPtr());
       }
     }
     // select branching for the second particle
      if(!fc[1].kinematics) {
        if(children[1]->id()==particle->id()) {
 	 // select branching for first particle
 	 if(!fb.hard)
 	   fc[1] = selectSpaceLikeDecayBranching(children[1],maxScales,minmass,type,branch);
 	 else if(fb.hard && ! branch->children()[1]->children().empty() )
 	   fc[1] = selectSpaceLikeDecayBranching(children[1],maxScales,minmass,type,
 						 branch->children()[1]);
 	 else
 	   fc[1] = selectSpaceLikeDecayBranching(children[1],maxScales,minmass,type,
 						 HardBranchingPtr());
        }
        else {
 	 if(fb.hard && !branch->children()[1]->children().empty() )
 	   fc[1] = selectTimeLikeBranching(children[1],type,branch->children()[1]);
 	 else
 	   fc[1] = selectTimeLikeBranching(children[1],type,HardBranchingPtr());
        }
      }
     // old default
     if(_reconOpt==0 || (_reconOpt==1 && fb.hard) ) {
       // update the history if needed
       currentTree()->updateInitialStateShowerProduct(progenitor(),children[0]);
       currentTree()->addInitialStateBranching(particle,children[0],children[1]);
       // shower the first  particle
       if(fc[0].kinematics) {
 	if(children[0]->id()==particle->id()) {
 	  if(!fb.hard)
 	    truncatedSpaceLikeDecayShower( children[0],maxScales,minmass,
 					   branch,type,fc[0]);
 	  else if(fb.hard && ! branch->children()[0]->children().empty() )
 	    truncatedSpaceLikeDecayShower( children[0],maxScales,minmass,
 					   branch->children()[0],type,fc[0]);
 	  else
 	    spaceLikeDecayShower( children[0],maxScales,minmass,type,fc[0]);
 	}
 	else {
 	  if(fb.hard && !branch->children()[0]->children().empty() )
 	    truncatedTimeLikeShower(children[0],branch->children()[0],type,fc[0],false);
 	  // normal shower
 	  else
 	    timeLikeShower(children[0],type,fc[0],false);
 	}
       }
       // shower the second  particle
       if(fc[1].kinematics) {
 	if(children[0]->id()==particle->id()) {
 	  if(!fb.hard)
 	    truncatedSpaceLikeDecayShower( children[0],maxScales,minmass,
 					   branch,type,fc[1]);
 	  else if(fb.hard && ! branch->children()[0]->children().empty() )
 	    truncatedSpaceLikeDecayShower( children[0],maxScales,minmass,
 					   branch->children()[0],type,fc[1]);
 	  else
 	    spaceLikeDecayShower( children[0],maxScales,minmass,type,fc[1]);
 	}
 	else {
 	  if(fb.hard && !branch->children()[0]->children().empty() )
 	    truncatedTimeLikeShower(children[0],branch->children()[0],type,fc[1],false);
 	  // normal shower
 	  else
 	    timeLikeShower(children[0],type,fc[1],false);
 	}
       }
       updateHistory(children[1]);
       // branching has happened
       break;
     }
     // H7 default
     else if(_reconOpt==1) {
       // update the history if needed
       currentTree()->updateInitialStateShowerProduct(progenitor(),children[0]);
       currentTree()->addInitialStateBranching(particle,children[0],children[1]);
       // shower the first  particle
       if(fc[0].kinematics) {
 	if(children[0]->id()==particle->id()) {
 	  if(!fb.hard)
 	    truncatedSpaceLikeDecayShower( children[0],maxScales,minmass,
 					   branch,type,fc[0]);
 	  else if(fb.hard && ! branch->children()[0]->children().empty() )
 	    truncatedSpaceLikeDecayShower( children[0],maxScales,minmass,
 					   branch->children()[0],type,fc[0]);
 	  else
 	    spaceLikeDecayShower( children[0],maxScales,minmass,type,fc[0]);
 	}
 	else {
 	  if(fb.hard && !branch->children()[0]->children().empty() )
 	    truncatedTimeLikeShower(children[0],branch->children()[0],type,fc[0],false);
 	  // normal shower
 	  else
 	    timeLikeShower(children[0],type,fc[0],false);
 	}
       }
       // shower the second  particle
       if(fc[1].kinematics) {
 	if(children[0]->id()==particle->id()) {
 	  if(!fb.hard)
 	    truncatedSpaceLikeDecayShower( children[0],maxScales,minmass,
 					   branch,type,fc[1]);
 	  else if(fb.hard && ! branch->children()[0]->children().empty() )
 	    truncatedSpaceLikeDecayShower( children[0],maxScales,minmass,
 					   branch->children()[0],type,fc[1]);
 	  else
 	    spaceLikeDecayShower( children[0],maxScales,minmass,type,fc[1]);
 	}
 	else {
 	  if(fb.hard && !branch->children()[0]->children().empty() )
 	    truncatedTimeLikeShower(children[0],branch->children()[0],type,fc[1],false);
 	  // normal shower
 	  else
 	    timeLikeShower(children[0],type,fc[1],false);
 	}
       }
       // clean up the vetoed emission
       if(particle->virtualMass()==ZERO) {
    	particle->showerKinematics(ShoKinPtr());
     	for(unsigned int ix=0;ix<children.size();++ix)
    	  particle->abandonChild(children[ix]);
     	children.clear();
    	particle->vetoEmission(fb.type,fb.kinematics->scale());
     	// generate the new emission
    	fb = selectSpaceLikeDecayBranching(particle,maxScales,minmass,type,branch);
    	// must be at least hard emission
   	assert(fb.kinematics);
    	setupChildren = true;
  	continue;
       }
       else {
 	updateHistory(children[1]);
   	break;
       }
     }
     else if(_reconOpt>=2) {
       // cut-off masses for the branching
       const vector<Energy> & virtualMasses = fb.sudakov->virtualMasses(fb.ids);
       // compute the masses of the children
       Energy masses[3];
       // space-like children
       masses[1] = children[0]->virtualMass();
       // time-like child
       if(fc[1].kinematics) {
 	const vector<Energy> & vm = fc[1].sudakov->virtualMasses(fc[1].ids);
 	Energy2 q2 = 
 	  fc[1].kinematics->z()*(1.-fc[1].kinematics->z())*sqr(fc[1].kinematics->scale());
 	if(fc[1].ids[0]!=ParticleID::g) q2 += sqr(vm[0]);
 	masses[2] = sqrt(q2);
       }
       else {
 	masses[2] = virtualMasses[2];
       } 
       masses[0]=particle->virtualMass();
       double z = fb.kinematics->z();
       Energy2 pt2 = (1.-z)*(z*sqr(masses[0])-sqr(masses[1])-z/(1.-z)*sqr(masses[2]));
       if(pt2>=ZERO) {
   	break;
       }
       else {
   	// reset the scales for the children
   	for(unsigned int ix=0;ix<2;++ix) {
   	  if(fc[ix].kinematics)
   	    children[ix]->vetoEmission(fc[ix].type,fc[ix].kinematics->scale());
   	  else {
 	    if(ix==0) 
 	      children[ix]->vetoEmission(ShowerPartnerType::QCDColourLine,Constants::MaxEnergy);
 	    else
 	      children[ix]->vetoEmission(ShowerPartnerType::QCDColourLine,ZERO);
 	  }
    	} 
 	children[0]->virtualMass(_progenitor->progenitor()->mass());
 	children[1]->virtualMass(ZERO);
       }
     }
   };
   if(_reconOpt>=2) {
     // update the history if needed
     currentTree()->updateInitialStateShowerProduct(progenitor(),children[0]);
     currentTree()->addInitialStateBranching(particle,children[0],children[1]);
     // shower the first  particle
     if(fc[0].kinematics) {
       if(children[0]->id()==particle->id()) {
 	if(!fb.hard)
 	  truncatedSpaceLikeDecayShower( children[0],maxScales,minmass,
 					 branch,type,fc[0]);
 	else if(fb.hard && ! branch->children()[0]->children().empty() )
 	  truncatedSpaceLikeDecayShower( children[0],maxScales,minmass,
 					 branch->children()[0],type,fc[0]);
 	else
 	  spaceLikeDecayShower( children[0],maxScales,minmass,type,fc[0]);
       }
       else {
 	if(fb.hard && !branch->children()[0]->children().empty() )
 	  truncatedTimeLikeShower(children[0],branch->children()[0],type,fc[0],false);
 	// normal shower
 	else
 	  timeLikeShower(children[0],type,fc[0],false);
       }
     }
     // shower the second  particle
     if(fc[1].kinematics) {
       if(children[0]->id()==particle->id()) {
 	if(!fb.hard)
 	  truncatedSpaceLikeDecayShower( children[0],maxScales,minmass,
 					 branch,type,fc[1]);
 	else if(fb.hard && ! branch->children()[0]->children().empty() )
 	  truncatedSpaceLikeDecayShower( children[0],maxScales,minmass,
 					 branch->children()[0],type,fc[1]);
 	else
 	  spaceLikeDecayShower( children[0],maxScales,minmass,type,fc[1]);
       }
       else {
 	if(fb.hard && !branch->children()[0]->children().empty() )
 	  truncatedTimeLikeShower(children[0],branch->children()[0],type,fc[1],false);
 	// normal shower
 	else
 	  timeLikeShower(children[0],type,fc[1],false);
       }
     }
     updateHistory(children[1]);
   }
   return true;
 }
 
 bool Evolver::constructDecayTree(vector<ShowerProgenitorPtr> & particlesToShower,
 				 ShowerInteraction::Type inter) {
   Energy ptmax(-GeV);
   // get the maximum pt is all ready a hard tree
   if(hardTree()) {
     for(unsigned int ix=0;ix<particlesToShower.size();++ix) {
       if(particlesToShower[ix]->maximumpT(inter)>ptmax&&
 	 particlesToShower[ix]->progenitor()->isFinalState()) 
 	ptmax = particlesToShower[ix]->maximumpT(inter);
     }
   }
   vector<HardBranchingPtr> spaceBranchings,allBranchings;
   for(unsigned int ix=0;ix<particlesToShower.size();++ix) {
     if(particlesToShower[ix]->progenitor()->isFinalState()) {
       HardBranchingPtr newBranch;
       if(particlesToShower[ix]->hasEmitted()) {
 	newBranch = 
 	  new_ptr(HardBranching(particlesToShower[ix]->progenitor(),
 				particlesToShower[ix]->progenitor()->
 				showerKinematics()->SudakovFormFactor(),
 				HardBranchingPtr(),HardBranching::Outgoing));
 	constructTimeLikeLine(newBranch,particlesToShower[ix]->progenitor());
       }
       else {
 	newBranch = 
 	  new_ptr(HardBranching(particlesToShower[ix]->progenitor(),
 				SudakovPtr(),HardBranchingPtr(),
 				HardBranching::Outgoing));
       }
       allBranchings.push_back(newBranch);
     }
     else {
       HardBranchingPtr newBranch;
       if(particlesToShower[ix]->hasEmitted()) {
 	newBranch = 
 	  new_ptr(HardBranching(particlesToShower[ix]->progenitor(),
 				particlesToShower[ix]->progenitor()->
 				showerKinematics()->SudakovFormFactor(),
 				HardBranchingPtr(),HardBranching::Decay));
 	constructTimeLikeLine(newBranch,particlesToShower[ix]->progenitor());
 	HardBranchingPtr last=newBranch;
 	do {
 	  for(unsigned int ix=0;ix<last->children().size();++ix) {
 	    if(last->children()[ix]->branchingParticle()->id()==
 	       particlesToShower[ix]->id()) {
 	      last = last->children()[ix];
 	      continue;
 	    }
 	  }
 	}
 	while(!last->children().empty());
 	last->status(HardBranching::Incoming);
 	spaceBranchings.push_back(newBranch);
 	allBranchings  .push_back(last);
       }
       else {
 	newBranch = 
 	  new_ptr(HardBranching(particlesToShower[ix]->progenitor(),
 				SudakovPtr(),HardBranchingPtr(),
 				HardBranching::Incoming));
 	spaceBranchings.push_back(newBranch);
 	allBranchings  .push_back(newBranch);
       }
     }
   }
   HardTreePtr QCDTree = new_ptr(HardTree(allBranchings,spaceBranchings,inter));
   // set the charge partners
   ShowerParticleVector particles;
   particles.push_back(spaceBranchings.back()->branchingParticle());
   for(set<HardBranchingPtr>::iterator cit=QCDTree->branchings().begin();
       cit!=QCDTree->branchings().end();++cit) {
     if((*cit)->status()==HardBranching::Outgoing)
       particles.push_back((*cit)->branchingParticle());
   }
   // get the partners
   showerModel()->partnerFinder()->setInitialEvolutionScales(particles,true,inter,true);
   // do the inverse recon
   if(!showerModel()->kinematicsReconstructor()->
      deconstructDecayJets(QCDTree,this,inter)) {
     return false;
   }
   // clear the old shower
   currentTree()->clear();
   // set the hard tree
   hardTree(QCDTree);
   // set the charge partners
   setEvolutionPartners(false,inter,false);
   // get the particles to be showered
   map<ShowerProgenitorPtr,ShowerParticlePtr>::const_iterator cit;
   map<ShowerProgenitorPtr,tShowerParticlePtr>::const_iterator cjt;
   particlesToShower.clear();
   // incoming particles
   for(cit=currentTree()->incomingLines().begin();
       cit!=currentTree()->incomingLines().end();++cit)
     particlesToShower.push_back(((*cit).first));
   assert(particlesToShower.size()==1);
   // outgoing particles
   for(cjt=currentTree()->outgoingLines().begin();
       cjt!=currentTree()->outgoingLines().end();++cjt) {
     particlesToShower.push_back(((*cjt).first));
     if(ptmax>ZERO) particlesToShower.back()->maximumpT(ptmax,inter);
   }
   for(unsigned int ix=0;ix<particlesToShower.size();++ix) {
     map<ShowerParticlePtr,tHardBranchingPtr>::const_iterator 
       eit=hardTree()->particles().end(),
       mit = hardTree()->particles().find(particlesToShower[ix]->progenitor());
     if( mit != eit) {
       if(mit->second->status()==HardBranching::Outgoing)
 	particlesToShower[ix]->progenitor()->set5Momentum(mit->second->pVector());
     }
   }
   return true;
 }
 
 bool Evolver::constructHardTree(vector<ShowerProgenitorPtr> & particlesToShower,
 				ShowerInteraction::Type inter) {
   bool noEmission = true;
   vector<HardBranchingPtr> spaceBranchings,allBranchings;
   for(unsigned int ix=0;ix<particlesToShower.size();++ix) {
     if(particlesToShower[ix]->progenitor()->isFinalState()) {
       HardBranchingPtr newBranch;
       if(particlesToShower[ix]->hasEmitted()) {
 	noEmission = false;
 	newBranch = 
 	  new_ptr(HardBranching(particlesToShower[ix]->progenitor(),
 				particlesToShower[ix]->progenitor()->
 				showerKinematics()->SudakovFormFactor(),
 				HardBranchingPtr(),HardBranching::Outgoing));
 	constructTimeLikeLine(newBranch,particlesToShower[ix]->progenitor());
       }
       else {
 	newBranch = 
 	  new_ptr(HardBranching(particlesToShower[ix]->progenitor(),
 				SudakovPtr(),HardBranchingPtr(),
 				HardBranching::Outgoing));
       }
       allBranchings.push_back(newBranch);
     }
     else {
       HardBranchingPtr first,last;
       if(!particlesToShower[ix]->progenitor()->parents().empty()) {
 	noEmission = false;
 	constructSpaceLikeLine(particlesToShower[ix]->progenitor(),
 			       first,last,SudakovPtr(),
 			       particlesToShower[ix]->original()->parents()[0]);
       }
       else {
 	first = new_ptr(HardBranching(particlesToShower[ix]->progenitor(),
 				      SudakovPtr(),HardBranchingPtr(),
 				      HardBranching::Incoming));
 	if(particlesToShower[ix]->original()->parents().empty())
 	  first->beam(particlesToShower[ix]->original());
 	else
 	  first->beam(particlesToShower[ix]->original()->parents()[0]);
 	last = first;
       }
       spaceBranchings.push_back(first);
       allBranchings.push_back(last);
     }
   }
   if(!noEmission) {
     HardTreePtr QCDTree = new_ptr(HardTree(allBranchings,spaceBranchings,
 					   inter));
     // set the charge partners
     ShowerParticleVector particles;
     for(set<HardBranchingPtr>::iterator cit=QCDTree->branchings().begin();
 	cit!=QCDTree->branchings().end();++cit) {
       particles.push_back((*cit)->branchingParticle());
     }
     // get the partners
     showerModel()->partnerFinder()->setInitialEvolutionScales(particles,false,
 							      inter,true);
     // do the inverse recon
     if(!showerModel()->kinematicsReconstructor()->
        deconstructHardJets(QCDTree,this,inter))
       throw Exception() << "Can't to shower deconstruction for QED shower in"
 			<< "QEDEvolver::showerHard" << Exception::eventerror;
     // set the hard tree
     hardTree(QCDTree);
   }
   // clear the old shower
   currentTree()->clear();
   // set the charge partners
   setEvolutionPartners(true,inter,false);
   // get the particles to be showered
   particlesToShower = currentTree()->extractProgenitors();
   // reset momenta
   if(hardTree()) {
     for(unsigned int ix=0;ix<particlesToShower.size();++ix) {
       map<ShowerParticlePtr,tHardBranchingPtr>::const_iterator 
 	eit=hardTree()->particles().end(),
 	mit = hardTree()->particles().find(particlesToShower[ix]->progenitor());
       if( mit != eit) {
 	particlesToShower[ix]->progenitor()->set5Momentum(mit->second->showerMomentum());
       }
     }
   }
   return true;
 }
 
 void Evolver::constructTimeLikeLine(tHardBranchingPtr branch,
 				       tShowerParticlePtr particle) {
   for(unsigned int ix=0;ix<particle->children().size();++ix) {
     HardBranching::Status status = branch->status();
     tShowerParticlePtr child = 
       dynamic_ptr_cast<ShowerParticlePtr>(particle->children()[ix]);
     if(child->children().empty()) {
       HardBranchingPtr newBranch = 
 	new_ptr(HardBranching(child,SudakovPtr(),branch,status));
       branch->addChild(newBranch);
     }
     else {
       HardBranchingPtr newBranch = 
 	new_ptr(HardBranching(child,child->showerKinematics()->SudakovFormFactor(),
 			      branch,status));
       constructTimeLikeLine(newBranch,child);
       branch->addChild(newBranch);
     }
   }
   // sort out the type of interaction
   if(!branch->children().empty()) {
     if(branch->branchingParticle()->id()==ParticleID::gamma ||
        branch->children()[0]->branchingParticle()->id()==ParticleID::gamma ||
        branch->children()[1]->branchingParticle()->id()==ParticleID::gamma)
       branch->type(ShowerPartnerType::QED);
     else {
       if(branch->branchingParticle()->id()==
 	 branch->children()[0]->branchingParticle()->id()) {
 	if(branch->branchingParticle()->dataPtr()->iColour()==PDT::Colour8) {
 	  tShowerParticlePtr emittor = 
 	    branch->branchingParticle()->showerKinematics()->z()>0.5 ?
 	    branch->children()[0]->branchingParticle() : 
 	    branch->children()[1]->branchingParticle();
 	  if(branch->branchingParticle()->colourLine()==emittor->colourLine())
 	    branch->type(ShowerPartnerType::QCDAntiColourLine);
 	  else if(branch->branchingParticle()->antiColourLine()==emittor->antiColourLine())
 	    branch->type(ShowerPartnerType::QCDColourLine);
 	  else
 	    assert(false);
 	}
 	else if(branch->branchingParticle()->colourLine()) {
 	  branch->type(ShowerPartnerType::QCDColourLine);
 	}
 	else if(branch->branchingParticle()->antiColourLine()) {
 	  branch->type(ShowerPartnerType::QCDAntiColourLine);
 	}
 	else
 	  assert(false);
       }
       else if(branch->branchingParticle()->id()==ParticleID::g &&
 	      branch->children()[0]->branchingParticle()->id()== 
 	      -branch->children()[1]->branchingParticle()->id()) {
 	if(branch->branchingParticle()->showerKinematics()->z()>0.5)
 	  branch->type(ShowerPartnerType::QCDAntiColourLine);
 	else
 	  branch->type(ShowerPartnerType::QCDColourLine);
 	
       }
       else
 	assert(false);
     }
   }
 }
 
 void Evolver::constructSpaceLikeLine(tShowerParticlePtr particle,
 				     HardBranchingPtr & first,
 				     HardBranchingPtr & last,
 				     SudakovPtr sud,PPtr beam) {
   if(!particle) return;
   if(!particle->parents().empty()) {
     tShowerParticlePtr parent = 
       dynamic_ptr_cast<ShowerParticlePtr>(particle->parents()[0]);
     SudakovPtr newSud=particle->showerKinematics()->SudakovFormFactor();
     constructSpaceLikeLine(parent,first,last,newSud,beam);
   }
   HardBranchingPtr newBranch = 
     new_ptr(HardBranching(particle,sud,last,HardBranching::Incoming));
   newBranch->beam(beam);
   if(!first) {
     first=newBranch;
     last =newBranch;
     return;
   }
   last->addChild(newBranch);
   tShowerParticlePtr timeChild = 
     dynamic_ptr_cast<ShowerParticlePtr>(particle->parents()[0]->children()[1]);
   HardBranchingPtr timeBranch;
   if(!timeChild->children().empty()) {
     timeBranch = 
       new_ptr(HardBranching(timeChild,
 			    timeChild->showerKinematics()->SudakovFormFactor(),
 			    last,HardBranching::Outgoing));
     constructTimeLikeLine(timeBranch,timeChild);
   }
   else {
     timeBranch = 
       new_ptr(HardBranching(timeChild,SudakovPtr(),last,HardBranching::Outgoing));
   }
   last->addChild(timeBranch);
   // sort out the type
   if(last->branchingParticle()      ->id() == ParticleID::gamma ||
      newBranch->branchingParticle() ->id() == ParticleID::gamma ||
      timeBranch->branchingParticle()->id() == ParticleID::gamma) {
     last->type(ShowerPartnerType::QED);
   }
   else if(last->branchingParticle()->id()==newBranch->branchingParticle()->id()) {
     if(last->branchingParticle()->id()==ParticleID::g) {
       if(last->branchingParticle()->colourLine()==
 	 newBranch->branchingParticle()->colourLine()) {
 	last->type(ShowerPartnerType::QCDAntiColourLine);
       }
       else {
 	last->type(ShowerPartnerType::QCDColourLine);
       }
     }
     else if(last->branchingParticle()->hasColour()) {
       last->type(ShowerPartnerType::QCDColourLine);
     }
     else if(last->branchingParticle()->hasAntiColour()) {
       last->type(ShowerPartnerType::QCDAntiColourLine);
     }
     else
       assert(false);
   }
   else if(newBranch->branchingParticle()->id()==ParticleID::g) { 
     if(last->branchingParticle()->hasColour()) {
       last->type(ShowerPartnerType::QCDAntiColourLine);
     }
     else if(last->branchingParticle()->hasAntiColour()) {
       last->type(ShowerPartnerType::QCDColourLine);
     }
     else
       assert(false);
   }
   else if(newBranch->branchingParticle()->hasColour()) {
     last->type(ShowerPartnerType::QCDColourLine);
   }
   else if(newBranch->branchingParticle()->hasAntiColour()) {
     last->type(ShowerPartnerType::QCDAntiColourLine);
   }
   else {
     assert(false);
   }
   last=newBranch;
 }
 
 void Evolver::connectTrees(ShowerTreePtr showerTree, 
 			   HardTreePtr hardTree, bool hard ) {
   ShowerParticleVector particles;
   // find the Sudakovs
   for(set<HardBranchingPtr>::iterator cit=hardTree->branchings().begin();
       cit!=hardTree->branchings().end();++cit) {
     // Sudakovs for ISR
     if((**cit).parent()&&(**cit).status()==HardBranching::Incoming) {
       ++_nis;
       IdList br(3);
       br[0] = (**cit).parent()->branchingParticle()->id();
       br[1] = (**cit).          branchingParticle()->id();
       br[2] = (**cit).parent()->children()[0]==*cit ?
 	(**cit).parent()->children()[1]->branchingParticle()->id() :
 	(**cit).parent()->children()[0]->branchingParticle()->id();
       BranchingList branchings = splittingGenerator()->initialStateBranchings();
       if(br[1]<0&&br[0]==br[1]) {
 	br[0] = abs(br[0]);
 	br[1] = abs(br[1]);
       }
       else if(br[1]<0) {
 	br[1] = -br[1];
 	br[2] = -br[2];
       }
       long index = abs(br[1]);
       SudakovPtr sudakov;
       for(BranchingList::const_iterator cjt = branchings.lower_bound(index); 
 	  cjt != branchings.upper_bound(index); ++cjt ) {
 	IdList ids = cjt->second.second;
 	if(ids[0]==br[0]&&ids[1]==br[1]&&ids[2]==br[2]) {
 	  sudakov=cjt->second.first;
 	  break;
 	}
       }
       if(!sudakov) throw Exception() << "Can't find Sudakov for the hard emission in "
 				     << "Evolver::connectTrees() for ISR" 
 				     << Exception::runerror;
       (**cit).parent()->sudakov(sudakov);
     }
     // Sudakovs for FSR
     else if(!(**cit).children().empty()) {
       ++_nfs;
       IdList br(3);
       br[0] = (**cit)               .branchingParticle()->id();
       br[1] = (**cit).children()[0]->branchingParticle()->id();
       br[2] = (**cit).children()[1]->branchingParticle()->id();
       BranchingList branchings = splittingGenerator()->finalStateBranchings();
       if(br[0]<0) {
 	br[0] = abs(br[0]);
 	br[1] = abs(br[1]);
 	br[2] = abs(br[2]);
       }
       long index = br[0];
       SudakovPtr sudakov;
       for(BranchingList::const_iterator cjt = branchings.lower_bound(index); 
 	  cjt != branchings.upper_bound(index); ++cjt ) {
 	IdList ids = cjt->second.second;
 	if(ids[0]==br[0]&&ids[1]==br[1]&&ids[2]==br[2]) {
 	  sudakov=cjt->second.first;
 	  break;
 	}
       }
       if(!sudakov) throw Exception() << "Can't find Sudakov for the hard emission in "
 				     << "Evolver::connectTrees()" 
 				     << Exception::runerror;
       (**cit).sudakov(sudakov);
     }
   }
   // calculate the evolution scale
   for(set<HardBranchingPtr>::iterator cit=hardTree->branchings().begin();
       cit!=hardTree->branchings().end();++cit) {
     particles.push_back((*cit)->branchingParticle());
   }
   showerModel()->partnerFinder()->
     setInitialEvolutionScales(particles,!hard,hardTree->interaction(),
 			      !hardTree->partnersSet());
   hardTree->partnersSet(true);
   // inverse reconstruction
   if(hard) {
     showerModel()->kinematicsReconstructor()->
       deconstructHardJets(hardTree,ShowerHandler::currentHandler()->evolver(),
 			  hardTree->interaction());
   }
   else
     showerModel()->kinematicsReconstructor()->
       deconstructDecayJets(hardTree,ShowerHandler::currentHandler()->evolver(),
 			   hardTree->interaction());
   // now reset the momenta of the showering particles
   vector<ShowerProgenitorPtr> particlesToShower;
   for(map<ShowerProgenitorPtr,ShowerParticlePtr>::const_iterator
 	cit=showerTree->incomingLines().begin();
       cit!=showerTree->incomingLines().end();++cit )
     particlesToShower.push_back(cit->first);
   // extract the showering particles
   for(map<ShowerProgenitorPtr,tShowerParticlePtr>::const_iterator
 	  cit=showerTree->outgoingLines().begin();
 	cit!=showerTree->outgoingLines().end();++cit )
     particlesToShower.push_back(cit->first);
   // match them
   map<ShowerProgenitorPtr,HardBranchingPtr> partners;
   for(set<HardBranchingPtr>::const_iterator bit=hardTree->branchings().begin();
       bit!=hardTree->branchings().end();++bit) {
     Energy2 dmin( 1e30*GeV2 );
     ShowerProgenitorPtr partner;
     for(vector<ShowerProgenitorPtr>::const_iterator pit=particlesToShower.begin();
 	pit!=particlesToShower.end();++pit) {
       if(partners.find(*pit)!=partners.end()) continue;
       if( (**bit).branchingParticle()->id() !=  (**pit).progenitor()->id() ) continue;
       if( (**bit).branchingParticle()->isFinalState() !=
 	  (**pit).progenitor()->isFinalState() ) continue;
       if( (**pit).progenitor()->isFinalState() ) {
 	Energy2 dtest =
 	  sqr( (**pit).progenitor()->momentum().x() - (**bit).showerMomentum().x() ) +
 	  sqr( (**pit).progenitor()->momentum().y() - (**bit).showerMomentum().y() ) +
 	  sqr( (**pit).progenitor()->momentum().z() - (**bit).showerMomentum().z() ) +
 	  sqr( (**pit).progenitor()->momentum().t() - (**bit).showerMomentum().t() );
 	// add mass difference for identical particles (e.g. Z0 Z0 production)
 	dtest += 1e10*sqr((**pit).progenitor()->momentum().m()-(**bit).showerMomentum().m());
 	if( dtest < dmin ) {
 	  partner = *pit;
 	  dmin = dtest;
 	}
       }
       else {
 	// ensure directions are right
 	if((**pit).progenitor()->momentum().z()/(**bit).showerMomentum().z()>ZERO) {
 	  partner = *pit;
 	  break;
 	}
       }
     }
     if(!partner) throw Exception() << "Failed to match shower and hard trees in Evolver::hardestEmission"
 				   << Exception::eventerror;
     partners[partner] = *bit;
   }
   for(vector<ShowerProgenitorPtr>::const_iterator pit=particlesToShower.begin();
       pit!=particlesToShower.end();++pit) {
     HardBranchingPtr partner = partners[*pit];
     if((**pit).progenitor()->dataPtr()->stable()) {
       (**pit).progenitor()->set5Momentum(partner->showerMomentum());
       (**pit).copy()->set5Momentum(partner->showerMomentum());
     }
     else {
       Lorentz5Momentum oldMomentum = (**pit).progenitor()->momentum();
       Lorentz5Momentum newMomentum = partner->showerMomentum();
       LorentzRotation boost( oldMomentum.findBoostToCM(),oldMomentum.e()/oldMomentum.mass());
       (**pit).progenitor()->transform(boost);
       (**pit).copy()      ->transform(boost);
       boost = LorentzRotation(-newMomentum.findBoostToCM(),newMomentum.e()/newMomentum.mass());
       (**pit).progenitor()->transform(boost);
       (**pit).copy()      ->transform(boost);
     }
   }
   // correction boosts for daughter trees
   for(map<tShowerTreePtr,pair<tShowerProgenitorPtr,tShowerParticlePtr> >::const_iterator 
 	tit  = showerTree->treelinks().begin();
       tit != showerTree->treelinks().end();++tit) {
     ShowerTreePtr decayTree = tit->first;
     map<ShowerProgenitorPtr,ShowerParticlePtr>::const_iterator 
       cit = decayTree->incomingLines().begin();
     // reset the momentum of the decay particle
     Lorentz5Momentum oldMomentum = cit->first->progenitor()->momentum();
     Lorentz5Momentum newMomentum = tit->second.second->momentum();
     LorentzRotation boost( oldMomentum.findBoostToCM(),oldMomentum.e()/oldMomentum.mass());
     decayTree->transform(boost,true);
     boost = LorentzRotation(-newMomentum.findBoostToCM(),newMomentum.e()/newMomentum.mass());
     decayTree->transform(boost,true);
   }
 }
 
 void Evolver::doShowering(bool hard,XCPtr xcomb) {
   // order of the interactions
   bool showerOrder(true);
   // zero number of emissions
   _nis = _nfs = 0;
   // if MC@NLO H event and limited emissions
   // indicate both final and initial state emission
   if ( isMCatNLOHEvent && _limitEmissions != 0 ) {
     _nis = _nfs = 1;
   }
   // extract particles to shower
   vector<ShowerProgenitorPtr> particlesToShower(setupShower(hard));
   // setup the maximum scales for the shower
   if (hardVetoOn()) setupMaximumScales(particlesToShower,xcomb);
   // set the hard scales for the profiles
   setupHardScales(particlesToShower,xcomb);
   // specific stuff for hard processes and decays
   Energy minmass(ZERO), mIn(ZERO);
   // hard process generate the intrinsic p_T once and for all
   if(hard) {
     generateIntrinsicpT(particlesToShower);
   }
   // decay compute the minimum mass of the final-state
   else {
     for(unsigned int ix=0;ix<particlesToShower.size();++ix) {
       if(particlesToShower[ix]->progenitor()->isFinalState()) {
 	if(particlesToShower[ix]->progenitor()->dataPtr()->stable()) 
 	  minmass += particlesToShower[ix]->progenitor()->dataPtr()->constituentMass();
 	else
 	  minmass += particlesToShower[ix]->progenitor()->mass();
       }
       else {
 	mIn = particlesToShower[ix]->progenitor()->mass();
       }
     }
     // throw exception if decay can't happen
     if ( minmass > mIn ) {
       throw Exception() << "Evolver.cc: Mass of decaying particle is "
 			<< "below constituent masses of decay products."
 			<< Exception::eventerror;
     }
   }
   // check if interactions in right order
   if(hardTree() && interaction_!=4 && 
      hardTree()->interaction()!=interactions_[0]) {
     assert(interactions_.size()==2);
     showerOrder = false;
     swap(interactions_[0],interactions_[1]);
   }
   // loop over possible interactions
   for(unsigned int inter=0;inter<interactions_.size();++inter) {
     // set up for second pass if required
     if(inter!=0) {
       // zero intrinsic pt so only added first time round
       intrinsicpT().clear();
       // construct the tree and throw veto if not possible
       if(!(hard ? 
 	   constructHardTree (particlesToShower,interactions_[inter]) :
 	   constructDecayTree(particlesToShower,interactions_[inter]))) 
 	throw InteractionVeto();
     }
     // create random particle vector (only need to do once)
     vector<ShowerProgenitorPtr> tmp;
     unsigned int nColouredIncoming = 0;
     while(particlesToShower.size()>0){
       unsigned int xx=UseRandom::irnd(particlesToShower.size());
       tmp.push_back(particlesToShower[xx]);
       particlesToShower.erase(particlesToShower.begin()+xx);
     }
     particlesToShower=tmp;
     for(unsigned int ix=0;ix<particlesToShower.size();++ix) {
       if(!particlesToShower[ix]->progenitor()->isFinalState() &&
 	 particlesToShower[ix]->progenitor()->coloured()) ++nColouredIncoming;
     }
     bool switchRecon = hard && nColouredIncoming !=1;
     // main shower loop
     unsigned int ntry(0);
     bool reconstructed = false;
     do {
       // clear results of last attempt if needed
       if(ntry!=0) {
 	currentTree()->clear();
 	setEvolutionPartners(hard,interactions_[inter],true);
 	_nis = _nfs = 0;
 	// if MC@NLO H event and limited emissions
 	// indicate both final and initial state emission
 	if ( isMCatNLOHEvent && _limitEmissions != 0 ) {
 	  _nis = _nfs = 1;
 	}
 	for(unsigned int ix=0; ix<particlesToShower.size();++ix) {
 	  SpinPtr spin = particlesToShower[ix]->progenitor()->spinInfo();
 	  if(spin && spin->decayVertex() &&
 	     dynamic_ptr_cast<tcSVertexPtr>(spin->decayVertex())) {
 	    spin->decayVertex(VertexPtr());
 	  }
 	}
       }
       // loop over particles
       for(unsigned int ix=0;ix<particlesToShower.size();++ix) {
 	// extract the progenitor
 	progenitor(particlesToShower[ix]);
 	// final-state radiation
 	if(progenitor()->progenitor()->isFinalState()) {
 	  if(!isFSRadiationON()) continue;
 	  // perform shower
 	  progenitor()->hasEmitted(startTimeLikeShower(interactions_[inter]));
 	}
 	// initial-state radiation
 	else {
 	  if(!isISRadiationON()) continue;
 	  // hard process
 	  if(hard) {
 	    // get the PDF
 	    setBeamParticle(_progenitor->beam());
 	    assert(beamParticle());
 	    // perform the shower
 	    // set the beam particle
 	    tPPtr beamparticle=progenitor()->original();
 	    if(!beamparticle->parents().empty()) 
 	      beamparticle=beamparticle->parents()[0];
 	    // generate the shower
 	    progenitor()->hasEmitted(startSpaceLikeShower(beamparticle,
 							  interactions_[inter]));
 	  }
 	  // decay
 	  else {
 	    // skip colour and electrically neutral particles
 	    if(!progenitor()->progenitor()->dataPtr()->coloured() &&
 	       !progenitor()->progenitor()->dataPtr()->charged()) {
 	      progenitor()->hasEmitted(false);
 	      continue;
 	    }
  	    // perform shower
  	    // set the scales correctly. The current scale is the maximum scale for
  	    // emission not the starting scale
 	    ShowerParticle::EvolutionScales maxScales(progenitor()->progenitor()->scales());
 	    progenitor()->progenitor()->scales() = ShowerParticle::EvolutionScales();
 	    if(progenitor()->progenitor()->dataPtr()->charged()) {
 	      progenitor()->progenitor()->scales().QED      = progenitor()->progenitor()->mass();
 	      progenitor()->progenitor()->scales().QED_noAO = progenitor()->progenitor()->mass();
 	    }
 	    if(progenitor()->progenitor()->hasColour()) {
 	      progenitor()->progenitor()->scales().QCD_c       = progenitor()->progenitor()->mass();
 	      progenitor()->progenitor()->scales().QCD_c_noAO  = progenitor()->progenitor()->mass();
 	    }
 	    if(progenitor()->progenitor()->hasAntiColour()) {
 	      progenitor()->progenitor()->scales().QCD_ac      = progenitor()->progenitor()->mass();
 	      progenitor()->progenitor()->scales().QCD_ac_noAO = progenitor()->progenitor()->mass();
 	    }
 	    // perform the shower
 	    progenitor()->hasEmitted(startSpaceLikeDecayShower(maxScales,minmass,
 							       interactions_[inter]));
 	  }
 	}
       }
       // do the kinematic reconstruction, checking if it worked
       reconstructed = hard ?
 	showerModel()->kinematicsReconstructor()->
 	reconstructHardJets (currentTree(),intrinsicpT(),interactions_[inter],
 			     switchRecon && ntry>maximumTries()/2) :
 	showerModel()->kinematicsReconstructor()->
 	reconstructDecayJets(currentTree(),interactions_[inter]);
     }
     while(!reconstructed&&maximumTries()>++ntry);
     // check if failed to generate the shower
     if(ntry==maximumTries()) {
       if(hard)
 	throw ShowerHandler::ShowerTriesVeto(ntry);
       else
 	throw Exception() << "Failed to generate the shower after "
 			  << ntry << " attempts in Evolver::showerDecay()"
 			  << Exception::eventerror;
     }
   }
   // tree has now showered
   _currenttree->hasShowered(true);
   if(!showerOrder) swap(interactions_[0],interactions_[1]);
   hardTree(HardTreePtr());
 }
 
 void Evolver:: convertHardTree(bool hard,ShowerInteraction::Type type) {
   map<ColinePtr,ColinePtr> cmap;
   // incoming particles
   for(map<ShowerProgenitorPtr,ShowerParticlePtr>::const_iterator 
 	cit=currentTree()->incomingLines().begin();cit!=currentTree()->incomingLines().end();++cit) {
     map<ShowerParticlePtr,tHardBranchingPtr>::const_iterator 
       mit = hardTree()->particles().find(cit->first->progenitor());
     // put the colour lines in the map
     ShowerParticlePtr oldParticle = cit->first->progenitor();
     ShowerParticlePtr newParticle = mit->second->branchingParticle();
     ColinePtr cLine = oldParticle->    colourLine();
     ColinePtr aLine = oldParticle->antiColourLine();
     if(newParticle->colourLine() &&
        cmap.find(newParticle->    colourLine())==cmap.end())
       cmap[newParticle->    colourLine()] = cLine;
     if(newParticle->antiColourLine() &&
        cmap.find(newParticle->antiColourLine())==cmap.end())
       cmap[newParticle->antiColourLine()] = aLine;
     // check whether or not particle emits
     bool emission = mit->second->parent();
     if(emission) {
       if(newParticle->colourLine()) {
 	ColinePtr ctemp = newParticle->    colourLine();
 	ctemp->removeColoured(newParticle);
       }
       if(newParticle->antiColourLine()) {
 	ColinePtr ctemp = newParticle->antiColourLine();
 	ctemp->removeAntiColoured(newParticle);
       }
       newParticle = mit->second->parent()->branchingParticle();
     }
     // get the new colour lines
     ColinePtr newCLine,newALine;
     // sort out colour lines
     if(newParticle->colourLine()) {
       ColinePtr ctemp = newParticle->    colourLine();
       ctemp->removeColoured(newParticle);
       if(cmap.find(ctemp)!=cmap.end()) {
 	newCLine = cmap[ctemp];
       }
       else {
 	newCLine = new_ptr(ColourLine());
 	cmap[ctemp] = newCLine;
       }
     }
     // and anticolour lines
     if(newParticle->antiColourLine()) {
       ColinePtr ctemp = newParticle->antiColourLine();
       ctemp->removeAntiColoured(newParticle);
       if(cmap.find(ctemp)!=cmap.end()) {
 	newALine = cmap[ctemp];
       }
       else {
 	newALine = new_ptr(ColourLine());
 	cmap[ctemp] = newALine;
       }
     }
     // remove colour lines from old particle
     if(aLine) {
       aLine->removeAntiColoured(cit->first->copy());
       aLine->removeAntiColoured(cit->first->progenitor());
     }
     if(cLine) {
       cLine->removeColoured(cit->first->copy());
       cLine->removeColoured(cit->first->progenitor());
     }
     // add particle to colour lines
     if(newCLine) newCLine->addColoured    (newParticle);
     if(newALine) newALine->addAntiColoured(newParticle);
     // insert new particles
     cit->first->copy(newParticle);
     ShowerParticlePtr sp(new_ptr(ShowerParticle(*newParticle,1,false)));
     cit->first->progenitor(sp);
     currentTree()->incomingLines()[cit->first]=sp;
     cit->first->perturbative(!emission);
     // and the emitted particle if needed
     if(emission) {
       ShowerParticlePtr newOut = mit->second->parent()->children()[1]->branchingParticle();
       if(newOut->colourLine()) {
 	ColinePtr ctemp = newOut->    colourLine();
 	ctemp->removeColoured(newOut);
 	assert(cmap.find(ctemp)!=cmap.end());
 	cmap[ctemp]->addColoured    (newOut);
       }
       if(newOut->antiColourLine()) {
 	ColinePtr ctemp = newOut->antiColourLine();
 	ctemp->removeAntiColoured(newOut);
 	assert(cmap.find(ctemp)!=cmap.end());
 	cmap[ctemp]->addAntiColoured(newOut);
       }
       ShowerParticlePtr sout=new_ptr(ShowerParticle(*newOut,1,true));
       ShowerProgenitorPtr out=new_ptr(ShowerProgenitor(cit->first->original(),newOut,sout));
       out->perturbative(false);
       currentTree()->outgoingLines().insert(make_pair(out,sout));
     }
     if(hard) {
       // sort out the value of x
       if(mit->second->beam()->momentum().z()>ZERO) {
 	sp->x(newParticle->momentum(). plus()/mit->second->beam()->momentum(). plus());
       }
       else {
 	sp->x(newParticle->momentum().minus()/mit->second->beam()->momentum().minus());
       }
     }
   }
   // outgoing particles
   for(map<ShowerProgenitorPtr,tShowerParticlePtr>::const_iterator 
 	cit=currentTree()->outgoingLines().begin();cit!=currentTree()->outgoingLines().end();++cit) {
     map<tShowerTreePtr,pair<tShowerProgenitorPtr,
 			    tShowerParticlePtr> >::const_iterator tit;
     for(tit  = currentTree()->treelinks().begin();
 	tit != currentTree()->treelinks().end();++tit) {
       if(tit->second.first && tit->second.second==cit->first->progenitor())
 	break;
     }
     map<ShowerParticlePtr,tHardBranchingPtr>::const_iterator 
       mit = hardTree()->particles().find(cit->first->progenitor());
     if(mit==hardTree()->particles().end()) continue;
     // put the colour lines in the map
     ShowerParticlePtr oldParticle = cit->first->progenitor();
     ShowerParticlePtr newParticle = mit->second->branchingParticle();
     ShowerParticlePtr newOut;
     ColinePtr cLine = oldParticle->    colourLine();
     ColinePtr aLine = oldParticle->antiColourLine();
     if(newParticle->colourLine() &&
        cmap.find(newParticle->    colourLine())==cmap.end())
       cmap[newParticle->    colourLine()] = cLine;
     if(newParticle->antiColourLine() &&
        cmap.find(newParticle->antiColourLine())==cmap.end())
       cmap[newParticle->antiColourLine()] = aLine;
     // check whether or not particle emits
     bool emission = !mit->second->children().empty();
     if(emission) {
       if(newParticle->colourLine()) {
 	ColinePtr ctemp = newParticle->    colourLine();
 	ctemp->removeColoured(newParticle);
       }
       if(newParticle->antiColourLine()) {
 	ColinePtr ctemp = newParticle->antiColourLine();
 	ctemp->removeAntiColoured(newParticle);
       }
       newParticle = mit->second->children()[0]->branchingParticle();
       newOut      = mit->second->children()[1]->branchingParticle();
       if(newParticle->id()!=oldParticle->id()&&newParticle->id()==newOut->id())
 	swap(newParticle,newOut);
     }
     // get the new colour lines
     ColinePtr newCLine,newALine;
     // sort out colour lines
     if(newParticle->colourLine()) {
       ColinePtr ctemp = newParticle->    colourLine();
       ctemp->removeColoured(newParticle);
       if(cmap.find(ctemp)!=cmap.end()) {
 	newCLine = cmap[ctemp];
       }
       else {
 	newCLine = new_ptr(ColourLine());
 	cmap[ctemp] = newCLine;
       }
     }
     // and anticolour lines
     if(newParticle->antiColourLine()) {
       ColinePtr ctemp = newParticle->antiColourLine();
       ctemp->removeAntiColoured(newParticle);
       if(cmap.find(ctemp)!=cmap.end()) {
 	newALine = cmap[ctemp];
       }
       else {
 	newALine = new_ptr(ColourLine());
 	cmap[ctemp] = newALine;
       }
     }
     // remove colour lines from old particle
     if(aLine) {
       aLine->removeAntiColoured(cit->first->copy());
       aLine->removeAntiColoured(cit->first->progenitor());
     }
     if(cLine) {
       cLine->removeColoured(cit->first->copy());
       cLine->removeColoured(cit->first->progenitor());
     }
     // special for unstable particles
     if(newParticle->id()==oldParticle->id() &&
        (tit!=currentTree()->treelinks().end()||!oldParticle->dataPtr()->stable())) {
       Lorentz5Momentum oldMomentum = oldParticle->momentum();
       Lorentz5Momentum newMomentum = newParticle->momentum();
       LorentzRotation boost( oldMomentum.findBoostToCM(),oldMomentum.e()/oldMomentum.mass());
       if(tit!=currentTree()->treelinks().end()) tit->first->transform(boost,false);
       oldParticle->transform(boost);
       boost = LorentzRotation(-newMomentum.findBoostToCM(),newMomentum.e()/newMomentum.mass());
       oldParticle->transform(boost);
       if(tit!=currentTree()->treelinks().end()) tit->first->transform(boost,false);
       newParticle=oldParticle;
     }
     // add particle to colour lines
     if(newCLine) newCLine->addColoured    (newParticle);
     if(newALine) newALine->addAntiColoured(newParticle);
     // insert new particles
     cit->first->copy(newParticle);
     ShowerParticlePtr sp(new_ptr(ShowerParticle(*newParticle,1,true)));
     cit->first->progenitor(sp);
     currentTree()->outgoingLines()[cit->first]=sp;
     cit->first->perturbative(!emission);
     // and the emitted particle if needed
     if(emission) {
       if(newOut->colourLine()) {
 	ColinePtr ctemp = newOut->    colourLine();
 	ctemp->removeColoured(newOut);
 	assert(cmap.find(ctemp)!=cmap.end());
 	cmap[ctemp]->addColoured    (newOut);
       }
       if(newOut->antiColourLine()) {
 	ColinePtr ctemp = newOut->antiColourLine();
 	ctemp->removeAntiColoured(newOut);
 	assert(cmap.find(ctemp)!=cmap.end());
 	cmap[ctemp]->addAntiColoured(newOut);
       }
       ShowerParticlePtr sout=new_ptr(ShowerParticle(*newOut,1,true));
       ShowerProgenitorPtr out=new_ptr(ShowerProgenitor(cit->first->original(),newOut,sout));
       out->perturbative(false);
       currentTree()->outgoingLines().insert(make_pair(out,sout));
     }
     // update any decay products
     if(tit!=currentTree()->treelinks().end())
       currentTree()->updateLink(tit->first,make_pair(cit->first,sp));
   }
   // reset the tree
   currentTree()->resetShowerProducts();
   // reextract the particles and set the colour partners
   vector<ShowerParticlePtr> particles = 
     currentTree()->extractProgenitorParticles();
   // clear the partners
   for(unsigned int ix=0;ix<particles.size();++ix) {
     particles[ix]->partner(ShowerParticlePtr());
     particles[ix]->clearPartners();
   }
   // clear the tree
   hardTree(HardTreePtr());
   // Set the initial evolution scales
   showerModel()->partnerFinder()->
     setInitialEvolutionScales(particles,!hard,type,!_hardtree);
 }
 
 Branching Evolver::selectTimeLikeBranching(tShowerParticlePtr particle,
 					   ShowerInteraction::Type type,
 					   HardBranchingPtr branch) {
   Branching fb;
   unsigned int iout=0;
   tcPDPtr pdata[2];
   while (true) {
     // break if doing truncated shower and no truncated shower needed
     if(branch && (!isTruncatedShowerON()||hardOnly())) break;
     fb=_splittingGenerator->chooseForwardBranching(*particle,_finalenhance,type);
     // no emission break
     if(!fb.kinematics) break;
     // special for truncated shower
     if(branch) {
       // check haven't evolved too far
       if(fb.kinematics->scale() < branch->scale()) {
 	fb=Branching();
 	break;
       }
       // get the particle data objects
       for(unsigned int ix=0;ix<2;++ix) pdata[ix]=getParticleData(fb.ids[ix+1]);
       if(particle->id()!=fb.ids[0]) {
     	for(unsigned int ix=0;ix<2;++ix) {
     	  tPDPtr cc(pdata[ix]->CC());
     	  if(cc) pdata[ix]=cc;
     	}
       }
       // find the truncated line
       iout=0;
       if(pdata[0]->id()!=pdata[1]->id()) {
 	if(pdata[0]->id()==particle->id())       iout=1;
 	else if (pdata[1]->id()==particle->id()) iout=2;
       }
       else if(pdata[0]->id()==particle->id()) {
 	if(fb.kinematics->z()>0.5) iout=1;
 	else                       iout=2;
       }
       // apply the vetos for the truncated shower
       // no flavour changing branchings
       if(iout==0) {
 	particle->vetoEmission(fb.type,fb.kinematics->scale());
 	continue;
       }
       double zsplit = iout==1 ? fb.kinematics->z() : 1-fb.kinematics->z();
       // only if same interaction for forced branching
       ShowerInteraction::Type type2 = fb.type==ShowerPartnerType::QED ?
 	ShowerInteraction::QED : ShowerInteraction::QCD;
       // and evolution
       if(type2==branch->sudakov()->interactionType()) {
 	if(zsplit < 0.5 || // hardest line veto
 	   fb.kinematics->scale()*zsplit < branch->scale() ) { // angular ordering veto
 	  particle->vetoEmission(fb.type,fb.kinematics->scale());
 	  continue;
 	}
       }
       // pt veto
       if(fb.kinematics->pT() > progenitor()->maximumpT(type2)) {
 	particle->vetoEmission(fb.type,fb.kinematics->scale());
 	continue;
       }
     }
     // standard vetos for all emissions
     if(timeLikeVetoed(fb,particle)) {
       particle->vetoEmission(fb.type,fb.kinematics->scale());
       if(particle->spinInfo()) particle->spinInfo()->decayVertex(VertexPtr());
       continue;
     }
     break;
   }
   // normal case
   if(!branch) {
     if(fb.kinematics) fb.hard = false;
     return fb;
   }
   // truncated emission
   if(fb.kinematics) {
     fb.hard = false;
     fb.iout = iout;
     return fb;
   }
   // otherwise need to return the hard emission
   // construct the kinematics for the hard emission
   ShoKinPtr showerKin=
     branch->sudakov()->createFinalStateBranching(branch->scale(),
 	                                         branch->children()[0]->z(),
 	                                         branch->phi(),
 						 branch->children()[0]->pT());
   showerKin->initialize( *particle,PPtr() );
   IdList idlist(3);
   idlist[0] = particle->id();
   idlist[1] = branch->children()[0]->branchingParticle()->id();
   idlist[2] = branch->children()[1]->branchingParticle()->id();
   fb = Branching( showerKin, idlist, branch->sudakov(),branch->type() );
   fb.hard = true;
   fb.iout=0;
   // return it
   return fb;
 }
 
 Branching Evolver::selectSpaceLikeDecayBranching(tShowerParticlePtr particle,
 						 const ShowerParticle::EvolutionScales & maxScales,
 						 Energy minmass,ShowerInteraction::Type type,
 						 HardBranchingPtr branch) {
   Branching fb;
   unsigned int iout=0;
   tcPDPtr pdata[2];
   while (true) {
     // break if doing truncated shower and no truncated shower needed
     if(branch && (!isTruncatedShowerON()||hardOnly())) break;
     // select branching
     fb=_splittingGenerator->chooseDecayBranching(*particle,maxScales,minmass,
 						 _initialenhance,type);
     // return if no radiation
     if(!fb.kinematics) break;
     // special for truncated shower
     if(branch) {
       // check haven't evolved too far
       if(fb.kinematics->scale() < branch->scale()) {
 	fb=Branching();
 	break;
       }
       // get the particle data objects
       for(unsigned int ix=0;ix<2;++ix) pdata[ix]=getParticleData(fb.ids[ix+1]);
       if(particle->id()!=fb.ids[0]) {
 	for(unsigned int ix=0;ix<2;++ix) {
 	  tPDPtr cc(pdata[ix]->CC());
 	  if(cc) pdata[ix]=cc;
 	}
       }
       // find the truncated line
       iout=0;
       if(pdata[0]->id()!=pdata[1]->id()) {
 	if(pdata[0]->id()==particle->id())       iout=1;
 	else if (pdata[1]->id()==particle->id()) iout=2;
       }
       else if(pdata[0]->id()==particle->id()) {
 	if(fb.kinematics->z()>0.5) iout=1;
 	else                       iout=2;
       }
       // apply the vetos for the truncated shower
       // no flavour changing branchings
       if(iout==0) {
 	particle->vetoEmission(fb.type,fb.kinematics->scale());
 	continue;
       }
       ShowerInteraction::Type type2 = fb.type==ShowerPartnerType::QED ?
 	ShowerInteraction::QED : ShowerInteraction::QCD;
       double zsplit = iout==1 ? fb.kinematics->z() : 1-fb.kinematics->z();
       if(type2==branch->sudakov()->interactionType()) {
 	if(zsplit < 0.5 || // hardest line veto
 	   fb.kinematics->scale()*zsplit < branch->scale() ) { // angular ordering veto
 	  particle->vetoEmission(fb.type,fb.kinematics->scale());
 	  continue;
 	}
       }
       // pt veto
       if(fb.kinematics->pT() > progenitor()->maximumpT(type2)) {
 	particle->vetoEmission(fb.type,fb.kinematics->scale());
 	continue;
       }
     }
     // if not vetoed break
     if(spaceLikeDecayVetoed(fb,particle)) {
       // otherwise reset scale and continue
       particle->vetoEmission(fb.type,fb.kinematics->scale());
       continue;
     }
     break;
   }
   // normal case
   if(!branch) {
     if(fb.kinematics) fb.hard = false;
     return fb;
   }
   // truncated emission
   if(fb.kinematics) {
     fb.hard = false;
     fb.iout = iout;
     return fb;
   }
   // otherwise need to return the hard emission
   // construct the kinematics for the hard emission
   ShoKinPtr showerKin=
     branch->sudakov()->createDecayBranching(branch->scale(),
 					    branch->children()[0]->z(),
 					    branch->phi(),
 					    branch->children()[0]->pT());
    showerKin->initialize( *particle,PPtr() );
    IdList idlist(3);
    idlist[0] = particle->id();
    idlist[1] = branch->children()[0]->branchingParticle()->id();
    idlist[2] = branch->children()[1]->branchingParticle()->id();
    // create the branching
    fb = Branching( showerKin, idlist, branch->sudakov(),ShowerPartnerType::QCDColourLine  );
    fb.hard=true;
    fb.iout=0;
    // return it
   return fb;
 }
diff --git a/Tests/Makefile.am b/Tests/Makefile.am
--- a/Tests/Makefile.am
+++ b/Tests/Makefile.am
@@ -1,357 +1,360 @@
 AUTOMAKE_OPTIONS = -Wno-portability
 AM_LDFLAGS += -module -avoid-version -rpath /dummy/path/not/used
 
 EXTRA_DIST = Inputs python Rivet 
 
 dist-hook:
 	rm -rf $(distdir)/Inputs/.svn
 	rm -rf $(distdir)/python/.svn
 	rm -rf $(distdir)/Rivet/.svn
 
 EXTRA_LTLIBRARIES = LeptonTest.la GammaTest.la HadronTest.la DISTest.la
 
 if WANT_LIBFASTJET
 EXTRA_LTLIBRARIES += HadronJetTest.la LeptonJetTest.la
 HadronJetTest_la_SOURCES = \
 Hadron/VHTest.h Hadron/VHTest.cc\
 Hadron/VTest.h Hadron/VTest.cc\
 Hadron/HTest.h Hadron/HTest.cc
 HadronJetTest_la_CPPFLAGS = $(AM_CPPFLAGS) $(FASTJETINCLUDE) \
 -I$(FASTJETPATH)
 HadronJetTest_la_LIBADD = $(FASTJETLIBS) 
 LeptonJetTest_la_SOURCES = \
 Lepton/TopDecay.h Lepton/TopDecay.cc
 LeptonJetTest_la_CPPFLAGS = $(AM_CPPFLAGS) $(FASTJETINCLUDE) \
 -I$(FASTJETPATH)
 LeptonJetTest_la_LIBADD = $(FASTJETLIBS) 
 endif
 
 LeptonTest_la_SOURCES = \
 Lepton/VVTest.h Lepton/VVTest.cc \
 Lepton/VBFTest.h Lepton/VBFTest.cc \
 Lepton/VHTest.h Lepton/VHTest.cc \
 Lepton/FermionTest.h Lepton/FermionTest.cc
 
 GammaTest_la_SOURCES = \
 Gamma/GammaMETest.h  Gamma/GammaMETest.cc \
 Gamma/GammaPMETest.h Gamma/GammaPMETest.cc
 
 DISTest_la_SOURCES = \
 DIS/DISTest.h  DIS/DISTest.cc
 
 HadronTest_la_SOURCES = \
 Hadron/HadronVVTest.h  Hadron/HadronVVTest.cc\
 Hadron/HadronVBFTest.h  Hadron/HadronVBFTest.cc\
 Hadron/WHTest.h  Hadron/WHTest.cc\
 Hadron/ZHTest.h  Hadron/ZHTest.cc\
 Hadron/VGammaTest.h  Hadron/VGammaTest.cc\
 Hadron/ZJetTest.h  Hadron/ZJetTest.cc\
 Hadron/WJetTest.h  Hadron/WJetTest.cc\
 Hadron/QQHTest.h  Hadron/QQHTest.cc
 
 
 REPO = $(top_builddir)/src/HerwigDefaults.rpo
 HERWIG = $(top_builddir)/src/Herwig
 HWREAD = $(HERWIG) read --repo $(REPO) -L $(builddir)/.libs -i $(top_builddir)/src
 HWRUN = $(HERWIG) run
 
 tests : tests-LEP tests-DIS tests-LHC tests-Gamma
 
 if WANT_LIBFASTJET
 tests-LEP : test-LEP-VV test-LEP-VH test-LEP-VBF test-LEP-BB test-LEP-Quarks test-LEP-Leptons \
             test-LEP-default test-LEP-Powheg test-LEP-TopDecay
 else
 tests-LEP : test-LEP-VV test-LEP-VH test-LEP-VBF test-LEP-BB test-LEP-Quarks test-LEP-Leptons
 endif
 
 tests-DIS : test-DIS-Charged test-DIS-Neutral
 
 if WANT_LIBFASTJET
 tests-LHC : test-LHC-WW test-LHC-WZ test-LHC-ZZ test-LHC-ZGamma test-LHC-WGamma \
 	    test-LHC-ZH test-LHC-WH test-LHC-ZJet test-LHC-WJet test-LHC-Z test-LHC-W test-LHC-ZZVBF test-LHC-VBF \
 	    test-LHC-WWVBF test-LHC-bbH test-LHC-ttH test-LHC-GammaGamma test-LHC-GammaJet test-LHC-Higgs \
 	    test-LHC-HiggsJet test-LHC-QCDFast test-LHC-QCD test-LHC-Top test-LHC-Bottom \
             test-LHC-WHJet test-LHC-ZHJet test-LHC-HJet test-LHC-ZShower test-LHC-WShower\
             test-LHC-WHJet-Powheg test-LHC-ZHJet-Powheg test-LHC-HJet-Powheg \
             test-LHC-ZShower-Powheg test-LHC-WShower-Powheg
 else
 tests-LHC : test-LHC-WW test-LHC-WZ test-LHC-ZZ test-LHC-ZGamma test-LHC-WGamma \
 	    test-LHC-ZH test-LHC-WH test-LHC-ZJet test-LHC-WJet test-LHC-Z test-LHC-W test-LHC-ZZVBF test-LHC-VBF \
 	    test-LHC-WWVBF test-LHC-bbH test-LHC-ttH test-LHC-GammaGamma test-LHC-GammaJet test-LHC-Higgs \
 	    test-LHC-HiggsJet test-LHC-QCDFast test-LHC-QCD test-LHC-Top
 endif
 
 tests-Gamma : test-Gamma-FF test-Gamma-WW test-Gamma-P
 
 if WANT_LIBFASTJET 
 test-LEP-% : Inputs/LEP-%.in LeptonTest.la LeptonJetTest.la
 	$(HWREAD) $<
 	$(HWRUN) $(notdir $(subst .in,.run,$<)) -N $${NUMEVENTS:-10000}
 else
 test-LEP-% : Inputs/LEP-%.in LeptonTest.la
 	$(HWREAD) $<
 	$(HWRUN) $(notdir $(subst .in,.run,$<)) -N $${NUMEVENTS:-10000}
 endif
 
 Rivet-LHC-Matchbox-% : Rivet/LHC-Matchbox-%.in
 	if [ ! -d Rivet-$(notdir $(subst .in,,$<))  ]; then mkdir Rivet-$(notdir $(subst .in,,$<)); fi;
 	cd Rivet-$(notdir $(subst .in,,$<)); echo `pwd`; \
 	../$(HERWIG) read --repo ../$(REPO) -L ../$(top_builddir)/lib -i ../$(top_builddir)/src ../$<; \
 	../$(HERWIG) run $(notdir $(subst .in,.run,$<)) -N $${NUMEVENTS:-10000}; \
 	mv $(notdir $(subst .in,.yoda,$<)) ..; \
 	cd ..
 
 Rivet-TVT-Matchbox-% : Rivet/TVT-Matchbox-%.in
 	if [ ! -d Rivet-$(notdir $(subst .in,,$<))  ]; then mkdir Rivet-$(notdir $(subst .in,,$<)); fi;
 	cd Rivet-$(notdir $(subst .in,,$<)); echo `pwd`; \
 	../$(HERWIG) read --repo ../$(REPO) -L ../$(top_builddir)/lib -i ../$(top_builddir)/src ../$<; \
 	../$(HERWIG) run $(notdir $(subst .in,.run,$<)) -N $${NUMEVENTS:-10000}; \
 	mv $(notdir $(subst .in,.yoda,$<)) ..; \
 	cd ..
 
 Rivet-TVT-Dipole-% : Rivet/TVT-Dipole-%.in
 	if [ ! -d Rivet-$(notdir $(subst .in,,$<))  ]; then mkdir Rivet-$(notdir $(subst .in,,$<)); fi;
 	cd Rivet-$(notdir $(subst .in,,$<)); echo `pwd`; \
 	../$(HERWIG) read --repo ../$(REPO) -L ../$(top_builddir)/lib -i ../$(top_builddir)/src ../$<; \
 	../$(HERWIG) run $(notdir $(subst .in,.run,$<)) -N $${NUMEVENTS:-10000}; \
 	mv $(notdir $(subst .in,.yoda,$<)) ..; \
 	cd ..
 
 Rivet-LHC-Dipole-% : Rivet/LHC-Dipole-%.in
 	if [ ! -d Rivet-$(notdir $(subst .in,,$<))  ]; then mkdir Rivet-$(notdir $(subst .in,,$<)); fi;
 	cd Rivet-$(notdir $(subst .in,,$<)); echo `pwd`; \
 	../$(HERWIG) read --repo ../$(REPO) -L ../$(top_builddir)/lib -i ../$(top_builddir)/src ../$<; \
 	../$(HERWIG) run $(notdir $(subst .in,.run,$<)) -N $${NUMEVENTS:-10000}; \
 	mv $(notdir $(subst .in,.yoda,$<)) ..; \
 	cd ..
 
 Rivet/LEP-%.in :
 	python/make_input_files.py $(notdir $(subst .in,,$@))
 
 Rivet/DIS-%.in : 
 	python/make_input_files.py $(notdir $(subst .in,,$@))
 
 Rivet/BFactory-%.in:
 	python/make_input_files.py $(notdir $(subst .in,,$@))
 
 Rivet/TVT-%.in:
 	python/make_input_files.py $(notdir $(subst .in,,$@))
 
 Rivet/LHC-%.in:
 	python/make_input_files.py $(notdir $(subst .in,,$@))
 
 Rivet/Star-%.in:
 	python/make_input_files.py $(notdir $(subst .in,,$@))
 
 Rivet/SppS-%.in:
 	python/make_input_files.py $(notdir $(subst .in,,$@))
 
 Rivet/ISR-%.in:
 	python/make_input_files.py $(notdir $(subst .in,,$@))
 
 Rivet-LEP-Matchbox-% : Rivet/LEP-Matchbox-%.in
 	if [ ! -d Rivet-$(notdir $(subst .in,,$<))  ]; then mkdir Rivet-$(notdir $(subst .in,,$<)); fi;
 	cd Rivet-$(notdir $(subst .in,,$<)); echo `pwd`; \
 	../$(HERWIG) read --repo ../$(REPO) -L ../$(top_builddir)/lib -i ../$(top_builddir)/src ../$<; \
 	../$(HERWIG) run $(notdir $(subst .in,.run,$<)) -N $${NUMEVENTS:-10000}; \
 	mv $(notdir $(subst .in,.yoda,$<)) ..; \
 	cd ..
 
 Rivet-LEP-Dipole-% : Rivet/LEP-Dipole-%.in
 	if [ ! -d Rivet-$(notdir $(subst .in,,$<))  ]; then mkdir Rivet-$(notdir $(subst .in,,$<)); fi;
 	cd Rivet-$(notdir $(subst .in,,$<)); echo `pwd`; \
 	../$(HERWIG) read --repo ../$(REPO) -L ../$(top_builddir)/lib -i ../$(top_builddir)/src ../$<; \
 	../$(HERWIG) run $(notdir $(subst .in,.run,$<)) -N $${NUMEVENTS:-10000}; \
 	mv $(notdir $(subst .in,.yoda,$<)) ..; \
 	cd ..
 
 Rivet-BFactory-Matchbox-% : Rivet/BFactory-Matchbox-%.in
 	if [ ! -d Rivet-$(notdir $(subst .in,,$<))  ]; then mkdir Rivet-$(notdir $(subst .in,,$<)); fi;
 	cd Rivet-$(notdir $(subst .in,,$<)); echo `pwd`; \
 	../$(HERWIG) read --repo ../$(REPO) -L ../$(top_builddir)/lib -i ../$(top_builddir)/src ../$<; \
 	../$(HERWIG) run $(notdir $(subst .in,.run,$<)) -N $${NUMEVENTS:-10000}; \
 	mv $(notdir $(subst .in,.yoda,$<)) ..; \
 	cd ..
 
 Rivet-LEP-% : Rivet/LEP-%.in
 	$(HWREAD) $<
 	$(HWRUN) $(notdir $(subst .in,.run,$<)) -N $${NUMEVENTS:-10000}
 
 Rivet-BFactory-% : Rivet/BFactory-%.in
 	$(HWREAD) $<
 	$(HWRUN) $(notdir $(subst .in,.run,$<)) -N $${NUMEVENTS:-10000}
 
 Rivet-TVT-% : Rivet/TVT-%.in
 	$(HWREAD) $<
 	$(HWRUN) $(notdir $(subst .in,.run,$<)) -N $${NUMEVENTS:-10000}
 
 Rivet-DIS-% : Rivet/DIS-%.in
 	$(HWREAD) $<
 	$(HWRUN) $(notdir $(subst .in,.run,$<)) -N $${NUMEVENTS:-10000}
 
 Rivet-LHC-% : Rivet/LHC-%.in
 	$(HWREAD) $<
 	$(HWRUN) $(notdir $(subst .in,.run,$<)) -N $${NUMEVENTS:-10000}
 
 Rivet-Star-% : Rivet/Star-%.in
 	$(HWREAD) $<
 	$(HWRUN) $(notdir $(subst .in,.run,$<)) -N $${NUMEVENTS:-10000}
 
 Rivet-SppS-% : Rivet/SppS-%.in
 	$(HWREAD) $<
 	$(HWRUN) $(notdir $(subst .in,.run,$<)) -N $${NUMEVENTS:-10000}
 
 Rivet-ISR-% : Rivet/ISR-%.in
 	$(HWREAD) $<
 	$(HWRUN) $(notdir $(subst .in,.run,$<)) -N $${NUMEVENTS:-10000}
 
 Rivet-inputfiles: $(shell echo Rivet/LEP{,-Powheg,-Matchbox,-Dipole,-Matchbox-Powheg}-{10,14,22,35,44,91,130,133,136,161,172,177,183,189,192,196,197,200,202,206,91-nopi}.in) \
                   $(shell echo Rivet/BFactory{,-Powheg,-Matchbox,-Dipole,-Matchbox-Powheg}-{10.52,10.52-sym,10.54,10.45,10.58}.in) \
                   $(shell echo Rivet/BFactory-{Upsilon,Upsilon2,Upsilon4,Tau}.in) \
                   $(shell echo Rivet/DIS{,-NoME,-Powheg,-Matchbox,-Dipole,-Matchbox-Powheg}-{e--LowQ2,e+-LowQ2,e+-HighQ2}.in) \
                   $(shell echo Rivet/TVT{,-Powheg,-Matchbox,-Dipole,-Matchbox-Powheg}-{Run-I-Z,Run-I-W,Run-I-WZ,Run-II-Z-e,Run-II-Z-{,LowMass-,HighMass-}mu,Run-II-W}.in) \
-	          $(shell echo Rivet/TVT-Run-II-{DiPhoton,PromptPhoton}.in) \
+	          $(shell echo Rivet/TVT-Run-II-{DiPhoton-GammaGamma,DiPhoton-GammaJet,PromptPhoton}.in) \
+	          $(shell echo Rivet/TVT-Powheg-Run-II-{DiPhoton-GammaGamma,DiPhoton-GammaJet}.in) \
                   $(shell echo Rivet/TVT{,-Dipole,-Matchbox,-Matchbox-Powheg}-{Run-II-Jets-{0..11},Run-I-Jets-{1..8}}.in ) \
 	          $(shell echo Rivet/TVT{,-Dipole,-Matchbox,-Matchbox-Powheg}-{630-Jets-{1..3},300-Jets-1,900-Jets-1}.in ) \
                   $(shell echo Rivet/TVT-{Run-I,Run-II,300,630,900}-UE.in) \
                   $(shell echo Rivet/LHC{,-Dipole,-Matchbox,-Matchbox-Powheg}-7-Jets-{0..15}.in ) \
 	          $(shell echo Rivet/LHC-{900,2360,2760,7,8,13}-UE.in ) \
 	          $(shell echo Rivet/LHC-{900,7}-UE-Long.in ) \
 		  $(shell echo Rivet/LHC{,-Dipole,-Matchbox,-Matchbox-Powheg}-7-Charm-{1..5}.in) \
 		  $(shell echo Rivet/LHC{,-Dipole,-Matchbox,-Matchbox-Powheg}-7-Bottom-{0..8}.in) \
 		  $(shell echo Rivet/LHC{,-Matchbox,-Matchbox-Powheg}-7-Top-{L,SL,All}.in) \
                   $(shell echo Rivet/Star-{UE,Jets-{1..4}}.in ) \
                   $(shell echo Rivet/ISR-{30,44,53,62}-UE.in ) \
 	          $(shell echo Rivet/SppS-{53,63,200,500,900,546}-UE.in ) \
                   $(shell echo Rivet/LHC{,-Matchbox,-Matchbox-Powheg,-Powheg,-Dipole}-{W-{e,mu},13-Z-{e,mu},Z-{e,mu},Z-LowMass-{e,mu},Z-MedMass-e,WZ,WW-{emu,ll},ZZ-{ll,lv},W-Z-{e,mu},8-Z-mu}.in) \
 	          $(shell echo Rivet/LHC{,-Matchbox,-Matchbox-Powheg,-Dipole}-{7-W-Jet-{1..3}-e,7-Z-Jet-{0..3}-e,7-Z-Jet-0-mu}.in) \
 	          $(shell echo Rivet/LHC{-Matchbox,-Matchbox-Powheg,-Dipole}-{Z-b,Z-bb,W-b,8-Z-jj}.in) \
-                  $(shell echo Rivet/LHC-7-PromptPhoton-{1..4}.in) \
-	          Rivet/LHC-7-DiPhoton.in Rivet/LHC-GammaGamma-7.in \
+                  $(shell echo Rivet/LHC-7-PromptPhoton-{1..4}.in) Rivet/LHC-GammaGamma-7.in \
+	          $(shell echo Rivet/LHC{,-Powheg}-7-{DiPhoton-GammaGamma,DiPhoton-GammaJet}.in) \
                   $(shell echo Rivet/LHC{,-Powheg,-Matchbox,-Matchbox-Powheg,-Dipole}-{ggH,VBF,WH,ZH}.in) \
                   $(shell echo Rivet/LHC{,-Powheg,-Matchbox,-Matchbox-Powheg,-Dipole}-8-{ggH,VBF,WH,ZH}{,-GammaGamma}.in) \
                   $(shell echo Rivet/LHC{,-Matchbox,-Matchbox-Powheg,-Dipole}-ggHJet.in)
 
 Rivet-LEP: $(shell echo Rivet-LEP{,-Powheg,-Matchbox,-Dipole}-{10,14,22,35,44,91,130,133,136,161,172,177,183,189,192,196,197,200,202,206,91-nopi})
 	rm -rf Rivet-LEP
 	python/merge-LEP LEP
 	python/merge-LEP LEP-Powheg
 	python/merge-LEP LEP-Matchbox
 	python/merge-LEP LEP-Dipole
 	rivet-mkhtml -o Rivet-LEP LEP.yoda:Hw++ LEP-Powheg.yoda:Hw++-Powheg LEP-Matchbox.yoda:Hw++-Matchbox LEP-Dipole.yoda:Hw++-Dipole
 
 Rivet-BFactory: $(shell echo Rivet-BFactory{,-Powheg,-Matchbox,-Dipole}-{10.52,10.52-sym,10.54,10.45,10.58}) \
                 $(shell echo Rivet-BFactory-{Upsilon,Upsilon2,Upsilon4,Tau})
 	rm -rf Rivet-BFactory
 	python/merge-BFactory BFactory
 	python/merge-BFactory BFactory-Powheg
 	python/merge-BFactory BFactory-Matchbox
 	python/merge-BFactory BFactory-Dipole
 	rivet-mkhtml -o Rivet-BFactory BFactory.yoda:Hw++ BFactory-Powheg.yoda:Hw++-Powheg BFactory-Matchbox.yoda:Hw++-Matchbox BFactory-Dipole.yoda:Hw++-Dipole
 
 Rivet-DIS: $(shell echo Rivet-DIS{,-NoME,-Powheg,-Matchbox,-Dipole}-{e--LowQ2,e+-LowQ2,e+-HighQ2})
 	rm -rf Rivet-DIS
 	python/merge-DIS DIS 
 	python/merge-DIS DIS-Powheg
 	python/merge-DIS DIS-NoME
 	python/merge-DIS DIS-Matchbox
 	python/merge-DIS DIS-Dipole
 	rivet-mkhtml -o Rivet-DIS DIS.yoda:Hw++ DIS-Powheg.yoda:Hw++-Powheg DIS-NoME.yoda:Hw++-NoME DIS-Matchbox.yoda:Hw++-Matchbox DIS-Dipole.yoda:Hw++-Dipole
 
 Rivet-TVT-WZ:  $(shell echo Rivet-TVT{,-Powheg,-Matchbox,-Dipole}-{Run-I-Z,Run-I-W,Run-I-WZ,Run-II-Z-{e,{,LowMass-,HighMass-}mu},Run-II-W})
 	rm -rf Rivet-TVT-WZ
 	python/merge-TVT-EW TVT-Run-II-W.yoda TVT-Run-II-Z-{e,{,LowMass-,HighMass-}mu}.yoda\
                             TVT-Run-I-{W,Z,WZ}.yoda -o TVT-WZ.yoda
 	python/merge-TVT-EW TVT-Powheg-Run-II-W.yoda   TVT-Powheg-Run-II-Z-{e,{,LowMass-,HighMass-}mu}.yoda\
                             TVT-Powheg-Run-I-{W,Z,WZ}.yoda -o TVT-Powheg-WZ.yoda
 	python/merge-TVT-EW TVT-Matchbox-Run-II-W.yoda   TVT-Matchbox-Run-II-Z-{e,{,LowMass-,HighMass-}mu}.yoda\
                             TVT-Matchbox-Run-I-{W,Z,WZ}.yoda -o TVT-Matchbox-WZ.yoda
 	python/merge-TVT-EW TVT-Dipole-Run-II-W.yoda   TVT-Dipole-Run-II-Z-{e,{,LowMass-,HighMass-}mu}.yoda\
                             TVT-Dipole-Run-I-{W,Z,WZ}.yoda -o TVT-Dipole-WZ.yoda
 	rivet-mkhtml -o Rivet-TVT-WZ TVT-WZ.yoda:Hw++ TVT-Powheg-WZ.yoda:Hw++-Powheg TVT-Matchbox-WZ.yoda:Hw++-Matchbox TVT-Dipole-WZ.yoda:Hw++-Dipole
 
-Rivet-TVT-Photon: $(shell echo Rivet-TVT-Run-II-{DiPhoton,PromptPhoton})
-#                  Rivet-TVT-Run-I-PromptPhoton 
-	rm -rf Rivet-TVT-Photon 
-	cat TVT-Run-II-DiPhoton.yoda TVT-Run-II-PromptPhoton.yoda > TVT-Photon.yoda
-	rivet-mkhtml -o Rivet-TVT-Photon TVT-Photon.yoda:Hw++
+Rivet-TVT-Photon: $(shell echo Rivet-TVT-Run-II-{DiPhoton-GammaGamma,DiPhoton-GammaJet,PromptPhoton}) \
+                  $(shell echo Rivet-TVT-Powheg-Run-II-{DiPhoton-GammaGamma,DiPhoton-GammaJet})
+	rm -rf Rivet-TVT-Photon
+	python/merge-TVT-Photon TVT -o TVT-Photon.yoda
+	python/merge-TVT-Photon TVT-Powheg -o TVT-Powheg-Photon.yoda
+	rivet-mkhtml -o Rivet-TVT-Photon TVT-Photon.yoda:Hw TVT-Powheg-Photon.yoda:Hw-Powheg
 
 Rivet-TVT-Jets:  $(shell echo Rivet-TVT-{Run-II-Jets-{0..11},Run-I-Jets-{1..8}} ) \
 	         $(shell echo Rivet-TVT-{630-Jets-{1..3},300-Jets-1,900-Jets-1} ) \
                  $(shell echo Rivet-TVT-{Run-I,Run-II,300,630,900}-UE)
 	python/merge-TVT-Energy TVT
 	rivet-merge-CDF_2012_NOTE10874 TVT-300-Energy.yoda TVT-900-Energy.yoda TVT-1960-Energy.yoda
 	flat2yoda RatioPlots.dat -o TVT-RatioPlots.yoda
 	rm -rf Rivet-TVT-Jets
 	python/merge-TVT-Jets TVT
 	rivet-mkhtml -o Rivet-TVT-Jets TVT-Jets.yoda:Hw++
 
 Rivet-LHC-Jets: $(shell echo Rivet-LHC-7-Jets-{0..15} ) \
 	        $(shell echo Rivet-LHC-{900,2360,2760,7,8,13}-UE ) \
 	        $(shell echo Rivet-LHC-{900,7}-UE-Long ) \
 		$(shell echo Rivet-LHC-7-Charm-{1..5}) \
 		$(shell echo Rivet-LHC-7-Bottom-{0..8}) \
 		$(shell echo Rivet-LHC-7-Top-{L,SL,All})
 	rm -rf Rivet-LHC-Jets
 	python/merge-LHC-Jets
 	rivet-mkhtml -o Rivet-LHC-Jets LHC-Jets.yoda:Hw++
 
 Rivet-Star: $(shell echo Rivet-Star-{UE,Jets-{1..4}} ) 
 	rm -rf Rivet-Star
 	python/merge-Star Star
 	rivet-mkhtml -o Rivet-Star Star.yoda
 
 Rivet-SppS: $(shell echo Rivet-ISR-{30,44,53,62}-UE ) \
 	    $(shell echo Rivet-SppS-{53,63,200,500,900,546}-UE )
 	rm -rf Rivet-SppS
 	python/merge-SppS SppS
 	rivet-mkhtml -o Rivet-SppS SppS.yoda
 
 Rivet-LHC-EW: $(shell echo Rivet-LHC{,-Matchbox,-Powheg,-Dipole}-{13-Z-{e,mu},W-{e,mu},Z-{e,mu},Z-LowMass-{e,mu},Z-MedMass-e,WZ,WW-{emu,ll},ZZ-{ll,lv},W-Z-{e,mu},8-Z-mu}) \
 	      $(shell echo Rivet-LHC{,-Matchbox,-Dipole}-{7-W-Jet-{1..3}-e,7-Z-Jet-{0..3}-e,7-Z-Jet-0-mu}) \
 	      $(shell echo Rivet-LHC{-Matchbox,-Dipole}-{Z-b,Z-bb,W-b,8-Z-jj})
 	rm -rf Rivet-LHC-EW;
 	python/merge-LHC-EW LHC-{13-Z-{e,mu},W-{e,mu},Z-e,Z-mu,Z-LowMass-{e,mu},Z-MedMass-e,W-Z-{e,mu},WW-{emu,ll},WZ,ZZ-{ll,lv}}.yoda LHC-7-{W,Z}-Jet-{1,2,3}-e.yoda -o LHC-EW.yoda;
 	python/merge-LHC-EW LHC-Matchbox-{13-Z-{e,mu},W-{e,mu},Z-{e,mu},Z-LowMass-{e,mu},Z-MedMass-e,W-Z-{e,mu},WW-{emu,ll},WZ,ZZ-{ll,lv}}.yoda LHC-Matchbox-7-{W,Z}-Jet-{1,2,3}-e.yoda -o LHC-Matchbox-EW.yoda;
 	python/merge-LHC-EW LHC-Dipole-{13-Z-{e,mu},W-{e,mu},Z-{e,mu},Z-LowMass-{e,mu},Z-MedMass-e,W-Z-{e,mu},WW-{emu,ll},WZ,ZZ-{ll,lv}}.yoda LHC-Dipole-7-{W,Z}-Jet-{1,2,3}-e.yoda -o LHC-Dipole-EW.yoda;
 	python/merge-LHC-EW LHC-Powheg-{W-{e,mu},Z-{e,mu},Z-LowMass-{e,mu},Z-MedMass-e,W-Z-{e,mu},WW-{emu,ll},WZ,ZZ-{ll,lv}}.yoda -o LHC-Powheg-EW.yoda;
 	rivet-mkhtml -o Rivet-LHC-EW LHC-EW.yoda:Hw++ LHC-Powheg-EW.yoda:Hw++-Powheg LHC-Matchbox-EW.yoda:Hw++-Matchbox LHC-Matchbox-Z-b.yoda:Hw++-Matchbox-Zb \
                                      LHC-Matchbox-Z-bb.yoda:Hw++-Matchbox-Zbb LHC-Matchbox-W-b.yoda:Hw++-Matchbox-W-bb LHC-Dipole-EW.yoda:Hw++-Dipole \
                                      LHC-Dipole-Z-b.yoda:Hw++-Dipole-Zb LHC-Dipole-Z-bb.yoda:Hw++-Dipole-Zbb LHC-Dipole-W-b.yoda:Hw++-Dipole-W-bb;
 
-Rivet-LHC-Photon: $(shell echo Rivet-LHC-7-PromptPhoton-{1..4}) \
-	          Rivet-LHC-7-DiPhoton Rivet-LHC-GammaGamma-7
-	rm -rf Rivet-LHC-Photon  
-	python/merge-LHC-Photon -o LHC-Photon.yoda
-	rivet-mkhtml -o Rivet-LHC-Photon LHC-Photon.yoda:Hw++
+Rivet-LHC-Photon: $(shell echo Rivet-LHC-7-PromptPhoton-{1..4}) Rivet-LHC-GammaGamma-7 \
+	          $(shell echo Rivet-LHC{,-Powheg}-7-{DiPhoton-GammaGamma,DiPhoton-GammaJet})
+	rm -rf Rivet-LHC-Photon
+	python/merge-LHC-Photon LHC -o LHC-Photon.yoda
+	python/merge-LHC-Photon LHC-Powheg -o LHC-Powheg-Photon.yoda
+	rivet-mkhtml -o Rivet-LHC-Photon LHC-Photon.yoda:Hw LHC-Powheg-Photon.yoda:Hw-Powheg
 
 Rivet-LHC-Higgs:  $(shell echo Rivet-LHC{,-Powheg}-{ggH,VBF,WH,ZH})\
                   $(shell echo Rivet-LHC{,-Powheg}-8-{ggH,VBF,WH,ZH}{,-GammaGamma}) Rivet-LHC-ggHJet
 	rm -rf Rivet-LHC-Higgs
 	rivet-mkhtml -o Rivet-LHC-Higgs LHC-Powheg-ggH.yoda:gg-Powheg LHC-ggH.yoda:gg LHC-ggHJet.yoda:HJet \
                         LHC-Powheg-VBF.yoda:VBF-Powheg LHC-VBF.yoda:VBF LHC-WH.yoda:WH LHC-ZH.yoda:ZH \
                         LHC-Powheg-WH.yoda:WH-Powheg LHC-Powheg-ZH.yoda:ZH-Powheg
 
 tests-Rivet : Rivet-LEP Rivet-BFactory Rivet-DIS Rivet-TVT-WZ Rivet-TVT-Photon Rivet-TVT-Jets Rivet-LHC-Jets Rivet-Star Rivet-SppS Rivet-LHC-EW Rivet-LHC-Photon
 
 
 test-Gamma-% : Inputs/Gamma-%.in GammaTest.la
 	$(HWREAD) $<
 	$(HWRUN) $(notdir $(subst .in,.run,$<)) -N $${NUMEVENTS:-10000}
 
 test-DIS-% : Inputs/DIS-%.in DISTest.la
 	$(HWREAD) $<
 	$(HWRUN) $(notdir $(subst .in,.run,$<)) -N $${NUMEVENTS:-10000}
 
 if WANT_LIBFASTJET 
 test-LHC-% : Inputs/LHC-%.in HadronTest.la GammaTest.la HadronJetTest.la
 	$(HWREAD) $<
 	$(HWRUN) $(notdir $(subst .in,.run,$<)) -N $${NUMEVENTS:-10000}
 else
 test-LHC-% : Inputs/LHC-%.in HadronTest.la GammaTest.la
 	$(HWREAD) $<
 	$(HWRUN) $(notdir $(subst .in,.run,$<)) -N $${NUMEVENTS:-10000}
 endif
 
 clean-local:
 	rm -f *.out *.log *.tex *.top *.run *.dump *.mult *.Bmult *.yoda
diff --git a/Tests/python/make_input_files.py b/Tests/python/make_input_files.py
--- a/Tests/python/make_input_files.py
+++ b/Tests/python/make_input_files.py
@@ -1,1318 +1,1356 @@
 #! /usr/bin/env python
 import logging,sys,os
 from string import strip, Template
 
 import sys
 if sys.version_info[:3] < (2,4,0):
     print "rivet scripts require Python version >= 2.4.0... exiting"
     sys.exit(1)
 
 if __name__ == "__main__":
     import logging
     from optparse import OptionParser, OptionGroup
     parser = OptionParser(usage="%prog name [...]")
 
 (opts, args) = parser.parse_args()
 ## Check args
 if len(args) != 1:
     logging.error("Must specify at least input file")
     sys.exit(1)
 
 name=args[0]
 
 collider=""
 # select the template to load
 # collider
 parameters = {}
 if(name.find("BFactory")==0) :
     collider="BFactory"
 elif(name.find("LEP")==0) :
     collider="LEP"
 elif(name.find("DIS")==0) :
     collider="DIS"
 elif(name.find("TVT")==0) :
     collider="TVT"
 elif(name.find("LHC-GammaGamma")==0) :
     collider="LHC-GammaGamma"
 elif(name.find("LHC")==0) :
     collider="LHC"
 elif(name.find("ISR")==0) :
     collider="ISR"
 elif(name.find("SppS")==0) :
     collider="SppS"
 elif(name.find("Star")==0) :
     collider="Star"
 simulation=""
 istart = 1
 print name
 if(name.find("Matchbox-Powheg")>0) :
     istart = 3
     simulation="Matchbox"
     parameters["shower"] = "read Matchbox/Powheg-DefaultShower.in\n"
 elif(name.find("Matchbox")>0) :
     istart = 2
     simulation="Matchbox"
     parameters["shower"] = "read Matchbox/MCatNLO-DefaultShower.in\n"
 elif(name.find("Dipole")>0) :
     istart = 2
     simulation="Matchbox"
     parameters["shower"]  = "read Matchbox/MCatNLO-DipoleShower.in\n"
 elif(name.find("Powheg")>0) :
     istart = 2
     simulation="Powheg"
 
 if(simulation=="Matchbox") :
     parameters["bscheme"] = "read Matchbox/FiveFlavourScheme.in\n"
     if(parameters["shower"].find("Dipole")>=0) :
         parameters["bscheme"] += "read Matchbox/FiveFlavourNoBMassScheme.in\n"
     if(collider.find("DIS")<0) :
         parameters["nlo"] = "read Matchbox/MadGraph-OpenLoops.in\n"
 
 if(collider=="") :
     logging.error("Can\'t find collider")
     sys.exit(1)
 
 # find the template
 if(simulation=="") :
     if(collider.find("LHC-GammaGamma") >=0) :
         istart += 1
         templateName="Hadron-Gamma.in"
     elif(collider.find("TVT")>=0 or collider.find("LHC") >=0 or
        collider.find("ISR")>=0 or collider.find("SppS")>=0 or
        collider.find("Star")>=0) :
         templateName="Hadron.in"
     elif(collider.find("BFactory")<0) :
         templateName= "%s.in" % (collider)
     else :
         templateName= "LEP.in"
 else :
     if(collider.find("TVT")>=0 or collider.find("LHC") >=0 or
        collider.find("ISR")>=0 or collider.find("SppS")>=0 or
        collider.find("Star")>=0) :
         templateName= "Hadron-%s.in" % (simulation) 
     elif(collider.find("BFactory")<0) :
         templateName= "%s-%s.in" % (collider,simulation) 
     else :
         templateName= "LEP-%s.in" % (simulation) 
 with open(os.path.join("Rivet/Templates",templateName), 'r') as f:
     templateText = f.read()
 template = Template( templateText )
 # work out the name of the parameter file
 nameSplit=name.split("-")
 parameterName=nameSplit[istart]
 for i in range(istart+1,len(nameSplit)) :
     parameterName += "-%s" % nameSplit[i] 
 
 # work out the process and parameters
 process=""
 # Bfactory
 if(collider=="BFactory") :
     if(simulation=="") :
         process = "set /Herwig/MatrixElements/MEee2gZ2qq:MaximumFlavour 4"
         if(parameterName=="10.58") :
             process += "\ncreate Herwig::MEee2VectorMeson /Herwig/MatrixElements/MEUpsilon HwMELepton.so\nset /Herwig/MatrixElements/MEUpsilon:VectorMeson /Herwig/Particles/Upsilon(4S)\nset /Herwig/MatrixElements/MEUpsilon:Coupling 0.0004151809\ninsert /Herwig/MatrixElements/SimpleEE:MatrixElements 0 /Herwig/MatrixElements/MEUpsilon"
     elif(simulation=="Powheg") :
         process = "set /Herwig/MatrixElements/PowhegMEee2gZ2qq:MaximumFlavour 4"
         if(parameterName=="10.58") :
             process += "\ncreate Herwig::MEee2VectorMeson /Herwig/MatrixElements/MEUpsilon HwMELepton.so\nset /Herwig/MatrixElements/MEUpsilon:VectorMeson /Herwig/Particles/Upsilon(4S)\nset /Herwig/MatrixElements/MEUpsilon:Coupling 0.0004151809\ninsert /Herwig/MatrixElements/SimpleEE:MatrixElements 0 /Herwig/MatrixElements/MEUpsilon"
     elif(simulation=="Matchbox" ) :
         process = "do Factory:Process e- e+ -> u ubar\ndo Factory:Process e- e+ -> d dbar\ndo Factory:Process e- e+ -> c cbar\ndo Factory:Process e- e+ -> s sbar"
         if(parameterName=="10.58") :
             process += "\ninsert /Herwig/Generators/EventGenerator:EventHandler:SubProcessHandlers 0 /Herwig/MatrixElements/SimpleEE\ncreate Herwig::MEee2VectorMeson /Herwig/MatrixElements/MEUpsilon HwMELepton.so\nset /Herwig/MatrixElements/MEUpsilon:VectorMeson /Herwig/Particles/Upsilon(4S)\nset /Herwig/MatrixElements/MEUpsilon:Coupling 0.0004151809\ninsert /Herwig/MatrixElements/SimpleEE:MatrixElements 0 /Herwig/MatrixElements/MEUpsilon\n"
 # DIS
 elif(collider=="DIS") :
     if(simulation=="") :
         if(parameterName.find("NoME")>=0) :
             process = "set /Herwig/Shower/Evolver:MECorrMode 0"
             parameterName=parameterName.replace("NoME-","")
         else :
             process = ""
     elif(simulation=="Powheg") :
         process = ""
     elif(simulation=="Matchbox" ) :
         if(parameterName.find("e-")>=0) :
             process="do Factory:Process e- p -> e- j"
         else :
             process="do Factory:Process e+ p -> e+ j"
 # LEP
 elif(collider=="LEP") :
     if(simulation=="") :
         process=""
         if(parameterName=="10") :
             process="set /Herwig/MatrixElements/MEee2gZ2qq:MaximumFlavour 4"
     elif(simulation=="Powheg") :
         process=""
         if(parameterName=="10") :
             process="set /Herwig/MatrixElements/PowhegMEee2gZ2qq:MaximumFlavour 4"
     elif(simulation=="Matchbox" ) :
         if(parameterName=="10") :
             process="do Factory:Process e- e+ -> u ubar\ndo Factory:Process e- e+ -> d dbar\ndo Factory:Process e- e+ -> c cbar\ndo Factory:Process e- e+ -> s sbar"
         else :
             process="do Factory:Process e- e+ -> j j"
 # TVT
 elif(collider=="TVT") :
     process="set /Herwig/Generators/EventGenerator:EventHandler:BeamB /Herwig/Particles/pbar-\n"
     if(parameterName.find("Run-II")>=0) :
         process+="set /Herwig/Generators/EventGenerator:EventHandler:LuminosityFunction:Energy 1960.0\n"
     elif(parameterName.find("Run-I")>=0) :
         process+="set /Herwig/Generators/EventGenerator:EventHandler:LuminosityFunction:Energy 1800.0\n"
     elif(parameterName.find("900")>=0) :
         process+="set /Herwig/Generators/EventGenerator:EventHandler:LuminosityFunction:Energy 900.0\n"
     elif(parameterName.find("630")>=0) :
         process+="set /Herwig/Generators/EventGenerator:EventHandler:LuminosityFunction:Energy 630.0\n"
     elif(parameterName.find("300")>=0) :
         process+="set /Herwig/Generators/EventGenerator:EventHandler:LuminosityFunction:Energy 300.0\n"
 
     if(simulation=="") :
         if(parameterName.find("PromptPhoton")>=0) :
             process+="insert SimpleQCD:MatrixElements[0] MEGammaJet\n"
             process+="set /Herwig/Cuts/PhotonKtCut:MinKT 15.\n"
-        elif(parameterName.find("DiPhoton")>=0) :
+        elif(parameterName.find("DiPhoton-GammaGamma")>=0) :
             process+="insert SimpleQCD:MatrixElements[0] MEGammaGamma\n"
             process+="set /Herwig/Cuts/PhotonKtCut:MinKT 5.\n"
+            parameterName=parameterName.replace("-GammaGamma","")
+        elif(parameterName.find("DiPhoton-GammaJet")>=0) :
+            process+="insert SimpleQCD:MatrixElements[0] MEGammaJet\n"
+            process+="set /Herwig/Cuts/PhotonKtCut:MinKT 5.\n"
+            parameterName=parameterName.replace("-GammaJet","")
         elif(parameterName.find("UE")>=0) :
             process += "insert SimpleQCD:MatrixElements[0] MEMinBias\n"
             process += "set /Herwig/UnderlyingEvent/MPIHandler:IdenticalToUE 0\n"
             process += "set /Herwig/Generators/EventGenerator:EventHandler:Cuts /Herwig/Cuts/MinBiasCuts\n"
             process += "create Herwig::MPIXSecReweighter /Herwig/Generators/MPIXSecReweighter\n"
             process += "insert /Herwig/Generators/EventGenerator:EventHandler:PostSubProcessHandlers 0 /Herwig/Generators/MPIXSecReweighter\n"
             process += "set /Herwig/Decays/DecayHandler:LifeTimeOption 0\n"
             process += "set /Herwig/Decays/DecayHandler:MaxLifeTime 10*mm\n"
         elif(parameterName.find("Jets")>=0) :
             process+="insert SimpleQCD:MatrixElements[0] MEQCD2to2\n"
             process+="set /Herwig/UnderlyingEvent/MPIHandler:IdenticalToUE 0\n"
             if(parameterName.find("Run-II-Jets-10")>=0) :
                 process+="set /Herwig/Cuts/JetKtCut:MinKT 30.\n"
                 process+="set /Herwig/Cuts/QCDCuts:MHatMin 500.*GeV\n"
             elif(parameterName.find("Run-II-Jets-11")>=0) :
                 process+="set /Herwig/Cuts/JetKtCut:MinKT 30.\n"
                 process+="set /Herwig/Cuts/QCDCuts:MHatMin 900.*GeV\n"
             elif(parameterName.find("Run-I-Jets-1")>=0) :
                 process+="set /Herwig/Cuts/JetKtCut:MinKT 20.\n"
             elif(parameterName.find("Run-I-Jets-2")>=0) :
                 process+="set /Herwig/Cuts/JetKtCut:MinKT 40.\n"
             elif(parameterName.find("Run-I-Jets-3")>=0) :
                 process+="set /Herwig/Cuts/JetKtCut:MinKT 65.\n"
             elif(parameterName.find("Run-I-Jets-4")>=0) :
                 process+="set /Herwig/Cuts/JetKtCut:MinKT 90.\n"
             elif(parameterName.find("Run-I-Jets-5")>=0) :
                 process+="set /Herwig/Cuts/JetKtCut:MinKT 160.\n"
             elif(parameterName.find("Run-I-Jets-6")>=0) :
                 process+="set /Herwig/Cuts/JetKtCut:MinKT 30.\n"
                 process+="set /Herwig/Cuts/QCDCuts:MHatMin 100.*GeV\n"
             elif(parameterName.find("Run-I-Jets-7")>=0) :
                 process+="set /Herwig/Cuts/JetKtCut:MinKT 30.\n"
                 process+="set /Herwig/Cuts/QCDCuts:MHatMin 400.*GeV\n"
             elif(parameterName.find("Run-I-Jets-8")>=0) :
                 process+="set /Herwig/Cuts/JetKtCut:MinKT 30.\n"
                 process+="set /Herwig/Cuts/QCDCuts:MHatMin 700.*GeV\n"
             elif(parameterName.find("Run-II-Jets-0")>=0) :
                 process+="set /Herwig/Cuts/JetKtCut:MinKT 15.\n"
             elif(parameterName.find("Run-II-Jets-1")>=0) :
                 process+="set /Herwig/Cuts/JetKtCut:MinKT 25.\n"
             elif(parameterName.find("Run-II-Jets-2")>=0) :
                 process+="set /Herwig/Cuts/JetKtCut:MinKT 40.\n"
             elif(parameterName.find("Run-II-Jets-3")>=0) :
                 process+="set /Herwig/Cuts/JetKtCut:MinKT 60.\n"
             elif(parameterName.find("Run-II-Jets-4")>=0) :
                 process+="set /Herwig/Cuts/JetKtCut:MinKT 85.\n"
             elif(parameterName.find("Run-II-Jets-5")>=0) :
                 process+="set /Herwig/Cuts/JetKtCut:MinKT 110.\n"
             elif(parameterName.find("Run-II-Jets-6")>=0) :
                 process+="set /Herwig/Cuts/JetKtCut:MinKT 160.\n"
             elif(parameterName.find("Run-II-Jets-7")>=0) :
                 process+="set /Herwig/Cuts/JetKtCut:MinKT 250.\n"
             elif(parameterName.find("Run-II-Jets-8")>=0) :
                 process+="set /Herwig/Cuts/JetKtCut:MinKT 30.\n"
                 process+="set /Herwig/Cuts/QCDCuts:MHatMin 100.*GeV\n"
             elif(parameterName.find("Run-II-Jets-9")>=0) :
                 process+="set /Herwig/Cuts/JetKtCut:MinKT 30.\n"
                 process+="set /Herwig/Cuts/QCDCuts:MHatMin 300.*GeV\n"
             elif(parameterName.find("900-Jets-1")>=0) :
                 process+="set /Herwig/Cuts/JetKtCut:MinKT 10.\n"
             elif(parameterName.find("300-Jets-1")>=0) :
                 process+="set /Herwig/Cuts/JetKtCut:MinKT 6.\n"
             elif(parameterName.find("630-Jets-1")>=0) :
                 process+="set /Herwig/Cuts/JetKtCut:MinKT 20.\n"
             elif(parameterName.find("630-Jets-2")>=0) :
                 process+="set /Herwig/Cuts/JetKtCut:MinKT 40.\n"
             elif(parameterName.find("630-Jets-3")>=0) :
                 process+="set /Herwig/Cuts/JetKtCut:MinKT 75.\n"
             elif(parameterName.find("900-Jets-1")>=0) :
                 process+="set /Herwig/Cuts/JetKtCut:MinKT 10.\n"
         elif(parameterName.find("Run-I-WZ")>=0) :
             process+="insert SimpleQCD:MatrixElements[0] MEqq2W2ff\nset MEqq2W2ff:Process Electron\ninsert SimpleQCD:MatrixElements[0] MEqq2gZ2ff\nset MEqq2gZ2ff:Process Electron\n"
         elif(parameterName.find("Run-I-W")>=0 or parameterName.find("Run-II-W")>=0) :
             process+="insert SimpleQCD:MatrixElements[0] MEqq2W2ff\nset MEqq2W2ff:Process Electron\n"
         elif(parameterName.find("Run-I-Z")>=0 or parameterName.find("Run-II-Z-e")>=0) :
             process +="insert SimpleQCD:MatrixElements[0] MEqq2gZ2ff\nset MEqq2gZ2ff:Process Electron\n"
         elif(parameterName.find("Run-II-Z-LowMass-mu")>=0) :
             process +="insert SimpleQCD:MatrixElements[0] MEqq2gZ2ff\nset MEqq2gZ2ff:Process Muon\n"
             process+="set /Herwig/Cuts/LeptonPairMassCut:MinMass 25*GeV\nset /Herwig/Cuts/LeptonPairMassCut:MaxMass 70*GeV\n"
         elif(parameterName.find("Run-II-Z-HighMass-mu")>=0) :
             process +="insert SimpleQCD:MatrixElements[0] MEqq2gZ2ff\nset MEqq2gZ2ff:Process Muon\n"
             process+="set /Herwig/Cuts/LeptonPairMassCut:MinMass 150*GeV\nset /Herwig/Cuts/LeptonPairMassCut:MaxMass 600*GeV\n"
         elif(parameterName.find("Run-II-Z-mu")>=0) :
             process +="insert SimpleQCD:MatrixElements[0] MEqq2gZ2ff\nset MEqq2gZ2ff:Process Muon\n"
     elif(simulation=="Powheg") :
         if(parameterName.find("Run-I-WZ")>=0) :
             process+="insert SimpleQCD:MatrixElements[0] PowhegMEqq2W2ff\nset PowhegMEqq2W2ff:Process Electron\ninsert SimpleQCD:MatrixElements[0] PowhegMEqq2gZ2ff\nset PowhegMEqq2gZ2ff:Process Electron\n"
         elif(parameterName.find("Run-I-W")>=0 or parameterName.find("Run-II-W")>=0) :
             process+="insert SimpleQCD:MatrixElements[0] PowhegMEqq2W2ff\nset PowhegMEqq2W2ff:Process Electron\n"
         elif(parameterName.find("Run-I-Z")>=0 or parameterName.find("Run-II-Z-e")>=0) :
             process+="insert SimpleQCD:MatrixElements[0] PowhegMEqq2gZ2ff\nset PowhegMEqq2gZ2ff:Process Electron\n"
         elif(parameterName.find("Run-II-Z-LowMass-mu")>=0) :
             process+="insert SimpleQCD:MatrixElements[0] PowhegMEqq2gZ2ff\nset PowhegMEqq2gZ2ff:Process Muon\n"
             process+="set /Herwig/Cuts/LeptonPairMassCut:MinMass 25*GeV\nset /Herwig/Cuts/LeptonPairMassCut:MaxMass 70*GeV\n"
         elif(parameterName.find("Run-II-Z-HighMass-mu")>=0) :
             process+="insert SimpleQCD:MatrixElements[0] PowhegMEqq2gZ2ff\nset PowhegMEqq2gZ2ff:Process Muon\n"
             process+="set /Herwig/Cuts/LeptonPairMassCut:MinMass 150*GeV\nset /Herwig/Cuts/LeptonPairMassCut:MaxMass 600*GeV\n"
         elif(parameterName.find("Run-II-Z-mu")>=0) :
             process+="insert SimpleQCD:MatrixElements[0] PowhegMEqq2gZ2ff\nset PowhegMEqq2gZ2ff:Process Muon\n"
+        elif(parameterName.find("DiPhoton-GammaGamma")>=0) :
+            process+="insert SimpleQCD:MatrixElements[0] MEGammaGammaPowheg\n"
+            process+="set MEGammaGammaPowheg:Process GammaGamma\n"
+            process+="insert SimpleQCD:MatrixElements[0] MEGammaGamma\n"
+            process+="set MEGammaGamma:Process gg\n"
+            process+="set /Herwig/Cuts/PhotonKtCut:MinKT 5.\n"
+            process+="set /Herwig/Cuts/JetKtCut:MinKT 5.\n"
+            parameterName=parameterName.replace("-GammaGamma","")
+        elif(parameterName.find("DiPhoton-GammaJet")>=0) :
+            process+="insert SimpleQCD:MatrixElements[0] MEGammaGammaPowheg\n"
+            process+="set MEGammaGammaPowheg:Process VJet\n"
+            process+="set /Herwig/Cuts/PhotonKtCut:MinKT 5.\n"
+            process+="set /Herwig/Cuts/JetKtCut:MinKT 5.\n"
+            parameterName=parameterName.replace("-GammaJet","")
     elif(simulation=="Matchbox" ) :
         if(parameterName.find("Jets")>=0) :
             process+="set Factory:OrderInAlphaS 2\nset Factory:OrderInAlphaEW 0\n"
             process+="do Factory:Process p p j j\nset Factory:ScaleChoice /Herwig/MatrixElements/Matchbox/Scales/MaxJetPtScale\n"
             process+="set  /Herwig/Cuts/Cuts:JetFinder  /Herwig/Cuts/JetFinder\n"
             process+="insert  /Herwig/Cuts/Cuts:MultiCuts 0  /Herwig/Cuts/JetCuts\n"
             process+="insert  /Herwig/Cuts/JetCuts:JetRegions 0  /Herwig/Cuts/FirstJet\n"
             process+="set /Herwig/UnderlyingEvent/MPIHandler:IdenticalToUE 0\n"
             if(parameterName.find("Run-II-Jets-10")>=0) :
                 process+="insert /Herwig/Cuts/JetCuts:JetRegions 0  /Herwig/Cuts/SecondJet\n"
                 process+="set /Herwig/Cuts/FirstJet:PtMin 30.*GeV\n"
                 process+="set /Herwig/Cuts/SecondJet:PtMin 25.*GeV\n"
                 process+="create ThePEG::JetPairRegion /Herwig/Cuts/JetPairMass JetCuts.so\n"
                 process+="set /Herwig/Cuts/JetPairMass:FirstRegion /Herwig/Cuts/FirstJet\n"
                 process+="set /Herwig/Cuts/JetPairMass:SecondRegion /Herwig/Cuts/SecondJet\n"
                 process+="insert /Herwig/Cuts/JetCuts:JetPairRegions 0  /Herwig/Cuts/JetPairMass\n"
                 process+="set /Herwig/Cuts/JetPairMass:MassMin 500.*GeV\n"
             elif(parameterName.find("Run-II-Jets-11")>=0) :
                 process+="insert /Herwig/Cuts/JetCuts:JetRegions 0  /Herwig/Cuts/SecondJet\n"
                 process+="set /Herwig/Cuts/FirstJet:PtMin 30.*GeV\n"
                 process+="set /Herwig/Cuts/SecondJet:PtMin 25.*GeV\n"
                 process+="create ThePEG::JetPairRegion /Herwig/Cuts/JetPairMass JetCuts.so\n"
                 process+="set /Herwig/Cuts/JetPairMass:FirstRegion /Herwig/Cuts/FirstJet\n"
                 process+="set /Herwig/Cuts/JetPairMass:SecondRegion /Herwig/Cuts/SecondJet\n"
                 process+="insert /Herwig/Cuts/JetCuts:JetPairRegions 0  /Herwig/Cuts/JetPairMass\n"
                 process+="set /Herwig/Cuts/JetPairMass:MassMin 900.*GeV\n"
             elif(parameterName.find("Run-II-Jets-12")>=0) :
                 process+="insert /Herwig/Cuts/JetCuts:JetRegions 0  /Herwig/Cuts/SecondJet\n"
                 process+="set /Herwig/Cuts/FirstJet:PtMin 30.*GeV\n"
                 process+="set /Herwig/Cuts/SecondJet:PtMin 25.*GeV\n"
                 process+="create ThePEG::JetPairRegion /Herwig/Cuts/JetPairMass JetCuts.so\n"
                 process+="set /Herwig/Cuts/JetPairMass:FirstRegion /Herwig/Cuts/FirstJet\n"
                 process+="set /Herwig/Cuts/JetPairMass:SecondRegion /Herwig/Cuts/SecondJet\n"
                 process+="insert /Herwig/Cuts/JetCuts:JetPairRegions 0  /Herwig/Cuts/JetPairMass\n"
                 process+="set /Herwig/Cuts/JetPairMass:MassMin 300.*GeV\n"
             elif(parameterName.find("Run-I-Jets-1")>=0) :
                 process+="set /Herwig/Cuts/FirstJet:PtMin 20.\n"
             elif(parameterName.find("Run-I-Jets-2")>=0) :
                 process+="set /Herwig/Cuts/FirstJet:PtMin 40.\n"
             elif(parameterName.find("Run-I-Jets-3")>=0) :
                 process+="set /Herwig/Cuts/FirstJet:PtMin 65.\n"
             elif(parameterName.find("Run-I-Jets-4")>=0) :
                 process+="set /Herwig/Cuts/FirstJet:PtMin 90.\n"
             elif(parameterName.find("Run-I-Jets-5")>=0) :
                 process+="set /Herwig/Cuts/FirstJet:PtMin 160.\n"
             elif(parameterName.find("Run-I-Jets-6")>=0) :
                 process+="insert /Herwig/Cuts/JetCuts:JetRegions 0  /Herwig/Cuts/SecondJet\n"
                 process+="set /Herwig/Cuts/FirstJet:PtMin 30.*GeV\n"
                 process+="set /Herwig/Cuts/SecondJet:PtMin 25.*GeV\n"
                 process+="create ThePEG::JetPairRegion /Herwig/Cuts/JetPairMass JetCuts.so\n"
                 process+="set /Herwig/Cuts/JetPairMass:FirstRegion /Herwig/Cuts/FirstJet\n"
                 process+="set /Herwig/Cuts/JetPairMass:SecondRegion /Herwig/Cuts/SecondJet\n"
                 process+="insert /Herwig/Cuts/JetCuts:JetPairRegions 0  /Herwig/Cuts/JetPairMass\n"
                 process+="set /Herwig/Cuts/JetPairMass:MassMin 100.*GeV\n"
             elif(parameterName.find("Run-I-Jets-7")>=0) :
                 process+="insert /Herwig/Cuts/JetCuts:JetRegions 0  /Herwig/Cuts/SecondJet\n"
                 process+="set /Herwig/Cuts/FirstJet:PtMin 30.*GeV\n"
                 process+="set /Herwig/Cuts/SecondJet:PtMin 25.*GeV\n"
                 process+="create ThePEG::JetPairRegion /Herwig/Cuts/JetPairMass JetCuts.so\n"
                 process+="set /Herwig/Cuts/JetPairMass:FirstRegion /Herwig/Cuts/FirstJet\n"
                 process+="set /Herwig/Cuts/JetPairMass:SecondRegion /Herwig/Cuts/SecondJet\n"
                 process+="insert /Herwig/Cuts/JetCuts:JetPairRegions 0  /Herwig/Cuts/JetPairMass\n"
                 process+="set /Herwig/Cuts/JetPairMass:MassMin 400.*GeV\n"
             elif(parameterName.find("Run-I-Jets-8")>=0) :
                 process+="insert /Herwig/Cuts/JetCuts:JetRegions 0  /Herwig/Cuts/SecondJet\n"
                 process+="set /Herwig/Cuts/FirstJet:PtMin 30.*GeV\n"
                 process+="set /Herwig/Cuts/SecondJet:PtMin 25.*GeV\n"
                 process+="create ThePEG::JetPairRegion /Herwig/Cuts/JetPairMass JetCuts.so\n"
                 process+="set /Herwig/Cuts/JetPairMass:FirstRegion /Herwig/Cuts/FirstJet\n"
                 process+="set /Herwig/Cuts/JetPairMass:SecondRegion /Herwig/Cuts/SecondJet\n"
                 process+="insert /Herwig/Cuts/JetCuts:JetPairRegions 0  /Herwig/Cuts/JetPairMass\n"
                 process+="set /Herwig/Cuts/JetPairMass:MassMin 700.*GeV\n"
             elif(parameterName.find("Run-II-Jets-0")>=0) :
                 process+="set /Herwig/Cuts/FirstJet:PtMin 15.\n"
             elif(parameterName.find("Run-II-Jets-1")>=0) :
                 process+="set /Herwig/Cuts/FirstJet:PtMin 25.\n"
             elif(parameterName.find("Run-II-Jets-2")>=0) :
                 process+="set /Herwig/Cuts/FirstJet:PtMin 40.\n"
             elif(parameterName.find("Run-II-Jets-3")>=0) :
                 process+="set /Herwig/Cuts/FirstJet:PtMin 60.\n"
             elif(parameterName.find("Run-II-Jets-4")>=0) :
                 process+="set /Herwig/Cuts/FirstJet:PtMin 85.\n"
             elif(parameterName.find("Run-II-Jets-5")>=0) :
                 process+="set /Herwig/Cuts/FirstJet:PtMin 110.\n"
             elif(parameterName.find("Run-II-Jets-6")>=0) :
                 process+="set /Herwig/Cuts/FirstJet:PtMin 160.\n"
             elif(parameterName.find("Run-II-Jets-7")>=0) :
                 process+="set /Herwig/Cuts/FirstJet:PtMin 250.\n"
             elif(parameterName.find("Run-II-Jets-8")>=0) :
                 process+="insert /Herwig/Cuts/JetCuts:JetRegions 0  /Herwig/Cuts/SecondJet\n"
                 process+="set /Herwig/Cuts/FirstJet:PtMin 30.*GeV\n"
                 process+="set /Herwig/Cuts/SecondJet:PtMin 25.*GeV\n"
                 process+="create ThePEG::JetPairRegion /Herwig/Cuts/JetPairMass JetCuts.so\n"
                 process+="set /Herwig/Cuts/JetPairMass:FirstRegion /Herwig/Cuts/FirstJet\n"
                 process+="set /Herwig/Cuts/JetPairMass:SecondRegion /Herwig/Cuts/SecondJet\n"
                 process+="insert /Herwig/Cuts/JetCuts:JetPairRegions 0  /Herwig/Cuts/JetPairMass\n"
                 process+="set /Herwig/Cuts/JetPairMass:MassMin 100.*GeV\n"
             elif(parameterName.find("Run-II-Jets-9")>=0) :
                 process+="insert /Herwig/Cuts/JetCuts:JetRegions 0  /Herwig/Cuts/SecondJet\n"
                 process+="set /Herwig/Cuts/FirstJet:PtMin 30.*GeV\n"
                 process+="set /Herwig/Cuts/SecondJet:PtMin 25.*GeV\n"
                 process+="create ThePEG::JetPairRegion /Herwig/Cuts/JetPairMass JetCuts.so\n"
                 process+="set /Herwig/Cuts/JetPairMass:FirstRegion /Herwig/Cuts/FirstJet\n"
                 process+="set /Herwig/Cuts/JetPairMass:SecondRegion /Herwig/Cuts/SecondJet\n"
                 process+="insert /Herwig/Cuts/JetCuts:JetPairRegions 0  /Herwig/Cuts/JetPairMass\n"
                 process+="set /Herwig/Cuts/JetPairMass:MassMin 300.*GeV\n"
             elif(parameterName.find("900-Jets-1")>=0) :
                 process+="set /Herwig/Cuts/FirstJet:PtMin 10.\n"
             elif(parameterName.find("300-Jets-1")>=0) :
                 process+="set /Herwig/Cuts/FirstJet:PtMin 6.\n"
             elif(parameterName.find("630-Jets-1")>=0) :
                 process+="set /Herwig/Cuts/FirstJet:PtMin 20.\n"
             elif(parameterName.find("630-Jets-2")>=0) :
                 process+="set /Herwig/Cuts/FirstJet:PtMin 40.\n"
             elif(parameterName.find("630-Jets-3")>=0) :
                 process+="set /Herwig/Cuts/FirstJet:PtMin 75.\n"
             elif(parameterName.find("900-Jets-1")>=0) :
                 process+="set /Herwig/Cuts/FirstJet:PtMin 10.\n"
         elif(parameterName.find("Run-I-WZ")>=0) :
             process+="set Factory:OrderInAlphaS 0\nset Factory:OrderInAlphaEW 2\ndo Factory:Process p pbar e+ e-\ndo Factory:Process p pbar e+ nu\ndo Factory:Process p pbar e- nu\n"
             process+="set /Herwig/Cuts/LeptonPairMassCut:MinMass 60*GeV\nset /Herwig/Cuts/LeptonPairMassCut:MaxMass 120*GeV\n"
         elif(parameterName.find("Run-I-W")>=0 or parameterName.find("Run-II-W")>=0) :
             process+="set Factory:OrderInAlphaS 0\nset Factory:OrderInAlphaEW 2\ndo Factory:Process p pbar e+ nu\ndo Factory:Process p pbar e- nu\nset Factory:ScaleChoice /Herwig/MatrixElements/Matchbox/Scales/LeptonPairMassScale\n"
             process+="set /Herwig/Cuts/LeptonPairMassCut:MinMass 60*GeV\nset /Herwig/Cuts/LeptonPairMassCut:MaxMass 120*GeV\n"
         elif(parameterName.find("Run-I-Z")>=0 or parameterName.find("Run-II-Z-e")>=0) :
             process+="set Factory:OrderInAlphaS 0\nset Factory:OrderInAlphaEW 2\ndo Factory:Process p pbar e+ e-\nset Factory:ScaleChoice /Herwig/MatrixElements/Matchbox/Scales/LeptonPairMassScale\n"
             process+="set /Herwig/Cuts/LeptonPairMassCut:MinMass 60*GeV\nset /Herwig/Cuts/LeptonPairMassCut:MaxMass 120*GeV\n"
         elif(parameterName.find("Run-II-Z-LowMass-mu")>=0) :
             process+="set Factory:OrderInAlphaS 0\nset Factory:OrderInAlphaEW 2\ndo Factory:Process p pbar mu+ mu-\nset Factory:ScaleChoice /Herwig/MatrixElements/Matchbox/Scales/LeptonPairMassScale\n"
             process+="set /Herwig/Cuts/LeptonPairMassCut:MinMass 25*GeV\nset /Herwig/Cuts/LeptonPairMassCut:MaxMass 70*GeV\n"
         elif(parameterName.find("Run-II-Z-HighMass-mu")>=0) :
             process+="set Factory:OrderInAlphaS 0\nset Factory:OrderInAlphaEW 2\ndo Factory:Process p pbar mu+ mu-\nset Factory:ScaleChoice /Herwig/MatrixElements/Matchbox/Scales/LeptonPairMassScale\n"
             process+="set /Herwig/Cuts/LeptonPairMassCut:MinMass 150.*GeV\nset /Herwig/Cuts/LeptonPairMassCut:MaxMass 600*GeV\n"
         elif(parameterName.find("Run-II-Z-mu")>=0) :
             process+="set Factory:OrderInAlphaS 0\nset Factory:OrderInAlphaEW 2\ndo Factory:Process p pbar mu+ mu-\nset Factory:ScaleChoice /Herwig/MatrixElements/Matchbox/Scales/LeptonPairMassScale\n"
             process+="set /Herwig/Cuts/LeptonPairMassCut:MinMass 60*GeV\nset /Herwig/Cuts/LeptonPairMassCut:MaxMass 120*GeV\n"
 # Star
 elif(collider=="Star" ) :
     process = "set /Herwig/Decays/DecayHandler:LifeTimeOption 0\n"
     process+= "set /Herwig/Decays/DecayHandler:MaxLifeTime 10*mm\n"
     process+= "set /Herwig/Generators/EventGenerator:EventHandler:BeamB /Herwig/Particles/p+\n"
     process+= "set /Herwig/Generators/EventGenerator:EventHandler:LuminosityFunction:Energy 200.0\n"
     process+= "set /Herwig/Cuts/QCDCuts:X2Min 0.01\n"
     if(simulation=="") :
         if(parameterName.find("UE")>=0) :
             process += "insert SimpleQCD:MatrixElements[0] MEMinBias\n"
             process += "set /Herwig/UnderlyingEvent/MPIHandler:IdenticalToUE 0\n"
             process += "set /Herwig/Generators/EventGenerator:EventHandler:Cuts /Herwig/Cuts/MinBiasCuts\n"
             process += "create Herwig::MPIXSecReweighter /Herwig/Generators/MPIXSecReweighter\n"
             process += "insert /Herwig/Generators/EventGenerator:EventHandler:PostSubProcessHandlers 0 /Herwig/Generators/MPIXSecReweighter\n"
         else :
             process+="insert SimpleQCD:MatrixElements[0] MEQCD2to2\n"
             process+="set /Herwig/UnderlyingEvent/MPIHandler:IdenticalToUE 0\n"
             if(parameterName.find("Jets-1")>=0) :
                 process+="set /Herwig/Cuts/JetKtCut:MinKT 2.\n"
             elif(parameterName.find("Jets-2")>=0) :
                 process+="set /Herwig/Cuts/JetKtCut:MinKT 5.\n"
             elif(parameterName.find("Jets-3")>=0) :
                 process+="set /Herwig/Cuts/JetKtCut:MinKT 20.\n"
             elif(parameterName.find("Jets-4")>=0) :
                 process+="set /Herwig/Cuts/JetKtCut:MinKT 25.\n"
     else :
         logging.error("Star not supported for %s " % simulation)
         sys.exit(1)
 # ISR and SppS
 elif(collider=="ISR" or collider =="SppS" ) :
     process="set /Herwig/Decays/DecayHandler:LifeTimeOption 0\n"
     process+="set /Herwig/Decays/DecayHandler:MaxLifeTime 10*mm\n"
     if(collider=="SppS") :
         process ="set /Herwig/Generators/EventGenerator:EventHandler:BeamB /Herwig/Particles/pbar-\n"
     if(parameterName.find("30")>=0) :
         process+="set /Herwig/Generators/EventGenerator:EventHandler:LuminosityFunction:Energy 30.4\n"
     elif(parameterName.find("44")>=0) :
         process+="set /Herwig/Generators/EventGenerator:EventHandler:LuminosityFunction:Energy 44.4\n"
     elif(parameterName.find("53")>=0) :
         process+="set /Herwig/Generators/EventGenerator:EventHandler:LuminosityFunction:Energy 53.0\n"
     elif(parameterName.find("62")>=0) :
         process+="set /Herwig/Generators/EventGenerator:EventHandler:LuminosityFunction:Energy 62.2\n"
     elif(parameterName.find("63")>=0) :
         process+="set /Herwig/Generators/EventGenerator:EventHandler:LuminosityFunction:Energy 63.0\n"
     elif(parameterName.find("200")>=0) :
         process+="set /Herwig/Generators/EventGenerator:EventHandler:LuminosityFunction:Energy 200.0\n"
     elif(parameterName.find("500")>=0) :
         process+="set /Herwig/Generators/EventGenerator:EventHandler:LuminosityFunction:Energy 500.0\n"
     elif(parameterName.find("546")>=0) :
         process+="set /Herwig/Generators/EventGenerator:EventHandler:LuminosityFunction:Energy 546.0\n"
     elif(parameterName.find("900")>=0) :
         process+="set /Herwig/Generators/EventGenerator:EventHandler:LuminosityFunction:Energy 900.0\n"
     if(simulation=="") :
         process += "insert SimpleQCD:MatrixElements[0] MEMinBias\n"
         process += "set /Herwig/UnderlyingEvent/MPIHandler:IdenticalToUE 0\n"
         process += "set /Herwig/Generators/EventGenerator:EventHandler:Cuts /Herwig/Cuts/MinBiasCuts\n"
         process += "create Herwig::MPIXSecReweighter /Herwig/Generators/MPIXSecReweighter\n"
         process += "insert /Herwig/Generators/EventGenerator:EventHandler:PostSubProcessHandlers 0 /Herwig/Generators/MPIXSecReweighter\n"
     else :
         logging.error(" SppS and ISR not supported for %s " % simulation)
         sys.exit(1)
 # LHC
 elif(collider=="LHC") :
     if(parameterName.find("7-")==0) :
         process="set /Herwig/Generators/EventGenerator:EventHandler:LuminosityFunction:Energy 7000.0\n"
     elif(parameterName.find("8-")==0) :
         process="set /Herwig/Generators/EventGenerator:EventHandler:LuminosityFunction:Energy 8000.0\n"
     elif(parameterName.find("13-")==0) :
         process="set /Herwig/Generators/EventGenerator:EventHandler:LuminosityFunction:Energy 13000.0\n"
     elif(parameterName.find("900")==0) :
         process="set /Herwig/Generators/EventGenerator:EventHandler:LuminosityFunction:Energy 900.0\n"
     elif(parameterName.find("2360")==0) :
         process="set /Herwig/Generators/EventGenerator:EventHandler:LuminosityFunction:Energy 2360.0\n"
     elif(parameterName.find("2760")==0) :
         process="set /Herwig/Generators/EventGenerator:EventHandler:LuminosityFunction:Energy 2760.0\n"
     else :
         process="set /Herwig/Generators/EventGenerator:EventHandler:LuminosityFunction:Energy 7000.0\n"
     if(simulation=="") :
         if(parameterName.find("8-VBF")>=0) :
             process+="insert SimpleQCD:MatrixElements[0] MEPP2HiggsVBF\n"
         elif(parameterName.find("VBF")>=0) :
             process+="do /Herwig/Particles/h0:SelectDecayModes h0->tau-,tau+;\n"
             process+="set /Herwig/Particles/tau-:Stable Stable\n"
             process+="insert SimpleQCD:MatrixElements[0] MEPP2HiggsVBF\n"
         elif(parameterName.find("ggHJet")>=0) :
             process+="do /Herwig/Particles/h0:SelectDecayModes h0->tau-,tau+;\n"
             process+="set /Herwig/Particles/tau-:Stable Stable\n"
             process+="insert SimpleQCD:MatrixElements[0] MEHiggsJet\n"
         elif(parameterName.find("8-ggH")>=0) :
             process+="insert SimpleQCD:MatrixElements[0] MEHiggs\n"
             process+="insert SimpleQCD:MatrixElements[0] MEHiggsJet\n"
             process+="set MEHiggsJet:Process qqbar\n"
             process+="set /Herwig/Cuts/JetKtCut:MinKT 0.0*GeV\n"
         elif(parameterName.find("ggH")>=0) :
             process+="do /Herwig/Particles/h0:SelectDecayModes h0->tau-,tau+;\n"
             process+="set /Herwig/Particles/tau-:Stable Stable\n"
             process+="insert SimpleQCD:MatrixElements[0] MEHiggs\n"
             process+="insert SimpleQCD:MatrixElements[0] MEHiggsJet\n"
             process+="set MEHiggsJet:Process qqbar\n"
             process+="set /Herwig/Cuts/JetKtCut:MinKT 0.0*GeV\n"
         elif(parameterName.find("PromptPhoton")>=0) :
             process+="insert SimpleQCD:MatrixElements[0] MEGammaJet\n"
             if(parameterName.find("PromptPhoton-1")>=0) :
                 process+="set /Herwig/Cuts/PhotonKtCut:MinKT 5.\n"
             elif(parameterName.find("PromptPhoton-2")>=0) :
                 process+="set /Herwig/Cuts/PhotonKtCut:MinKT 25.\n"
             elif(parameterName.find("PromptPhoton-3")>=0) :
                 process+="set /Herwig/Cuts/PhotonKtCut:MinKT 80.\n"
             elif(parameterName.find("PromptPhoton-4")>=0) :
                 process+="set /Herwig/Cuts/PhotonKtCut:MinKT 150.\n"
-        elif(parameterName.find("DiPhoton")>=0) :
+        elif(parameterName.find("DiPhoton-GammaGamma")>=0) :
             process+="insert SimpleQCD:MatrixElements[0] MEGammaGamma\n"
             process+="set /Herwig/Cuts/PhotonKtCut:MinKT 5.\n"
+            parameterName=parameterName.replace("-GammaGamma","")
+        elif(parameterName.find("DiPhoton-GammaJet")>=0) :
+            process+="insert SimpleQCD:MatrixElements[0] MEGammaJet\n"
+            process+="set /Herwig/Cuts/PhotonKtCut:MinKT 5.\n"
+            parameterName=parameterName.replace("-GammaJet","")
         elif(parameterName.find("8-WH")>=0) :
             process+="insert SimpleQCD:MatrixElements[0] MEPP2WH\n"
             process+="set /Herwig/Cuts/JetKtCut:MinKT 0.0*GeV\n"
         elif(parameterName.find("8-ZH")>=0) :
             process+="insert SimpleQCD:MatrixElements[0] MEPP2ZH\n"
             process+="set /Herwig/Cuts/JetKtCut:MinKT 0.0*GeV\n"
         elif(parameterName.find("WH")>=0) :
             process+="do /Herwig/Particles/h0:SelectDecayModes h0->b,bbar;\n"
             process+="do /Herwig/Particles/W+:SelectDecayModes W+->nu_e,e+; W+->nu_mu,mu+;\n"
             process+="insert SimpleQCD:MatrixElements[0] MEPP2WH\n"
             process+="set /Herwig/Cuts/JetKtCut:MinKT 0.0*GeV\n"
         elif(parameterName.find("ZH")>=0) :
             process+="do /Herwig/Particles/h0:SelectDecayModes h0->b,bbar;\n"
             process+="do /Herwig/Particles/Z0:SelectDecayModes Z0->e-,e+; Z0->mu-,mu+;\n"
             process+="insert SimpleQCD:MatrixElements[0] MEPP2ZH\n"
             process+="set /Herwig/Cuts/JetKtCut:MinKT 0.0*GeV\n"
         elif(parameterName.find("UE")>=0) :
             process += "insert SimpleQCD:MatrixElements[0] MEMinBias\n"
             process += "set /Herwig/UnderlyingEvent/MPIHandler:IdenticalToUE 0\n"
             process += "set /Herwig/Generators/EventGenerator:EventHandler:Cuts /Herwig/Cuts/MinBiasCuts\n"
             process += "create Herwig::MPIXSecReweighter /Herwig/Generators/MPIXSecReweighter\n"
             process += "insert /Herwig/Generators/EventGenerator:EventHandler:PostSubProcessHandlers 0 /Herwig/Generators/MPIXSecReweighter\n"
             if(parameterName.find("Long")>=0) :
                 process += "set /Herwig/Decays/DecayHandler:MaxLifeTime 100*mm\n"
         elif(parameterName.find("7-Jets")>=0) :
             process+="insert SimpleQCD:MatrixElements[0] MEQCD2to2\n"
             process+="set MEQCD2to2:MaximumFlavour 5\n"
             process+="set /Herwig/UnderlyingEvent/MPIHandler:IdenticalToUE 0\n"
             if(parameterName.find("7-Jets-0")>=0) :
                 process+="set /Herwig/Cuts/JetKtCut:MinKT 5.\n"
             elif(parameterName.find("7-Jets-10")>=0) :
                 process+="set /Herwig/Cuts/JetKtCut:MinKT 20.\n"
                 process+="set /Herwig/Cuts/QCDCuts:MHatMin 200.*GeV\n"
             elif(parameterName.find("7-Jets-11")>=0) :
                 process+="set /Herwig/Cuts/JetKtCut:MinKT 20.\n"
                 process+="set /Herwig/Cuts/QCDCuts:MHatMin 600.*GeV\n"
             elif(parameterName.find("7-Jets-12")>=0) :
                 process+="set /Herwig/Cuts/JetKtCut:MinKT 20.\n"
                 process+="set /Herwig/Cuts/QCDCuts:MHatMin 1000.*GeV\n"
             elif(parameterName.find("7-Jets-13")>=0) :
                 process+="set /Herwig/Cuts/JetKtCut:MinKT 20.\n"
                 process+="set /Herwig/Cuts/QCDCuts:MHatMin 1600.*GeV\n"
             elif(parameterName.find("7-Jets-14")>=0) :
                 process+="set /Herwig/Cuts/JetKtCut:MinKT 20.\n"
                 process+="set /Herwig/Cuts/QCDCuts:MHatMin 2200.*GeV\n"
             elif(parameterName.find("7-Jets-15")>=0) :
                 process+="set /Herwig/Cuts/JetKtCut:MinKT 20.\n"
                 process+="set /Herwig/Cuts/QCDCuts:MHatMin 2800.*GeV\n"
             elif(parameterName.find("7-Jets-1")>=0) :
                 process+="set /Herwig/Cuts/JetKtCut:MinKT 10.\n"
             elif(parameterName.find("7-Jets-2")>=0) :
                 process+="set /Herwig/Cuts/JetKtCut:MinKT 20.\n"
             elif(parameterName.find("7-Jets-3")>=0) :
                 process+="set /Herwig/Cuts/JetKtCut:MinKT 40.\n"
             elif(parameterName.find("7-Jets-4")>=0) :
                 process+="set /Herwig/Cuts/JetKtCut:MinKT 70.\n"
             elif(parameterName.find("7-Jets-5")>=0) :
                 process+="set /Herwig/Cuts/JetKtCut:MinKT 150.\n"
             elif(parameterName.find("7-Jets-6")>=0) :
                 process+="set /Herwig/Cuts/JetKtCut:MinKT 200.\n"
             elif(parameterName.find("7-Jets-7")>=0) :
                 process+="set /Herwig/Cuts/JetKtCut:MinKT 300.\n"
             elif(parameterName.find("7-Jets-8")>=0) :
                 process+="set /Herwig/Cuts/JetKtCut:MinKT 500.\n"
             elif(parameterName.find("7-Jets-9")>=0) :
                 process+="set /Herwig/Cuts/JetKtCut:MinKT 20.\n"
                 process+="set /Herwig/Cuts/QCDCuts:MHatMin 90.*GeV\n"
         elif(parameterName.find("7-Charm")>=0 or \
              parameterName.find("7-Bottom")>=0) :
             if(parameterName.find("7-Bottom")>=0) :
                 process+="cp MEHeavyQuark MEBottom\n" 
                 process+="set MEBottom:QuarkType Bottom\n"
                 process+="insert SimpleQCD:MatrixElements[0] MEBottom\n"
             else : 
                 process+="cp MEHeavyQuark MECharm\n" 
                 process+="set MECharm:QuarkType Charm\n"
                 process+="insert SimpleQCD:MatrixElements[0] MECharm\n"
             process+="set /Herwig/UnderlyingEvent/MPIHandler:IdenticalToUE 0\n"
             if(parameterName.find("7-Heavy-0")>=0) :
                 if(parameterName.find("7-Bottom")>=0) :
                     process+="set MEBottom:Process Pair\n" 
                 process+="set /Herwig/Cuts/JetKtCut:MinKT 0.\n"
             elif(parameterName.find("-1")>=0) :
                 process+="set /Herwig/Cuts/JetKtCut:MinKT 5.\n"
             elif(parameterName.find("-2")>=0) :
                 process+="set /Herwig/Cuts/JetKtCut:MinKT 20.\n"
             elif(parameterName.find("-3")>=0) :
                 process+="set /Herwig/Cuts/JetKtCut:MinKT 50.\n"
             elif(parameterName.find("-4")>=0) :
                 process+="set /Herwig/Cuts/JetKtCut:MinKT 80.\n"
             elif(parameterName.find("-5")>=0) :
                 process+="set /Herwig/Cuts/JetKtCut:MinKT 110.\n"
             elif(parameterName.find("-6")>=0) :
                 process+="set /Herwig/Cuts/JetKtCut:MinKT 30.\n"
                 process+="set /Herwig/Cuts/QCDCuts:MHatMin 90.*GeV\n"
             elif(parameterName.find("-7")>=0) :
                 process+="set /Herwig/Cuts/JetKtCut:MinKT 30.\n"
                 process+="set /Herwig/Cuts/QCDCuts:MHatMin 340.*GeV\n"
             elif(parameterName.find("-8")>=0) :
                 process+="set /Herwig/Cuts/JetKtCut:MinKT 30.\n"
                 process+="set /Herwig/Cuts/QCDCuts:MHatMin 500.*GeV\n"
         elif(parameterName.find("7-Top-L")>=0) :
             process+="set MEHeavyQuark:QuarkType Top\n"
             process+="insert SimpleQCD:MatrixElements[0] MEHeavyQuark\n"
             process+="do /Herwig/Particles/t:SelectDecayModes t->nu_e,e+,b; t->nu_mu,mu+,b;\n"
             process+="create Herwig::BranchingRatioReweighter /Herwig/Generators/BRReweighter\n"
             process+="insert /Herwig/Generators/EventGenerator:EventHandler:PostHadronizationHandlers 0 /Herwig/Generators/BRReweighter\n"
         elif(parameterName.find("7-Top-SL")>=0) :
             process+="set MEHeavyQuark:QuarkType Top\n"
             process+="insert SimpleQCD:MatrixElements[0] MEHeavyQuark\n"
             process+="set /Herwig/Particles/t:Synchronized Not_synchronized\n"
             process+="set /Herwig/Particles/tbar:Synchronized Not_synchronized\n"
             process+="do /Herwig/Particles/t:SelectDecayModes t->nu_e,e+,b; t->nu_mu,mu+,b;\n"
             process+="do /Herwig/Particles/tbar:SelectDecayModes tbar->b,bbar,cbar; tbar->bbar,cbar,d; tbar->bbar,cbar,s; tbar->bbar,s,ubar; tbar->bbar,ubar,d;\n"
             process+="create Herwig::BranchingRatioReweighter /Herwig/Generators/BRReweighter\n"
             process+="insert /Herwig/Generators/EventGenerator:EventHandler:PostHadronizationHandlers 0 /Herwig/Generators/BRReweighter\n"
         elif(parameterName.find("7-Top-All")>=0) :
             process+="set MEHeavyQuark:QuarkType Top\n"
             process+="insert SimpleQCD:MatrixElements[0] MEHeavyQuark\n"
         elif(parameterName.find("WZ")>=0) :
             process+="insert SimpleQCD:MatrixElements[0] MEPP2VV\nset MEPP2VV:Process WZ\n"
             process+="do /Herwig/Particles/W+:SelectDecayModes /Herwig/Particles/W+/W+->nu_e,e+; /Herwig/Particles/W+/W+->nu_mu,mu+;\n"
             process+="do /Herwig/Particles/W-:SelectDecayModes /Herwig/Particles/W-/W-->nu_ebar,e-; /Herwig/Particles/W-/W-->nu_mubar,mu-;\n"
             process+="do /Herwig/Particles/Z0:SelectDecayModes /Herwig/Particles/Z0/Z0->e-,e+; /Herwig/Particles/Z0/Z0->mu-,mu+;\n"
             process+="create Herwig::BranchingRatioReweighter /Herwig/Generators/BRReweighter\n"
             process+="insert /Herwig/Generators/EventGenerator:EventHandler:PostHadronizationHandlers 0 /Herwig/Generators/BRReweighter\n"
         elif(parameterName.find("WW-emu")>=0) :
             process+="insert SimpleQCD:MatrixElements[0] MEPP2VV\nset MEPP2VV:Process WW\n"
             process+="set /Herwig/Particles/W+:Synchronized 0\n"
             process+="set /Herwig/Particles/W-:Synchronized 0\n"
             process+="do /Herwig/Particles/W+:SelectDecayModes /Herwig/Particles/W+/W+->nu_e,e+;\n"
             process+="do /Herwig/Particles/W-:SelectDecayModes /Herwig/Particles/W-/W-->nu_mubar,mu-;\n"
             process+="create Herwig::BranchingRatioReweighter /Herwig/Generators/BRReweighter\n"
             process+="insert /Herwig/Generators/EventGenerator:EventHandler:PostHadronizationHandlers 0 /Herwig/Generators/BRReweighter\n"
         elif(parameterName.find("WW-ll")>=0) :
             process+="insert SimpleQCD:MatrixElements[0] MEPP2VV\nset MEPP2VV:Process WW\n"
             process+="do /Herwig/Particles/W+:SelectDecayModes /Herwig/Particles/W+/W+->nu_e,e+; /Herwig/Particles/W+/W+->nu_mu,mu+; /Herwig/Particles/W+/W+->nu_tau,tau+;\n"
             process+="create Herwig::BranchingRatioReweighter /Herwig/Generators/BRReweighter\n"
             process+="insert /Herwig/Generators/EventGenerator:EventHandler:PostHadronizationHandlers 0 /Herwig/Generators/BRReweighter\n"
         elif(parameterName.find("ZZ-ll")>=0) :
             process+="insert SimpleQCD:MatrixElements[0] MEPP2VV\nset MEPP2VV:Process ZZ\n"
             process+="do /Herwig/Particles/Z0:SelectDecayModes /Herwig/Particles/Z0/Z0->e-,e+; /Herwig/Particles/Z0/Z0->mu-,mu+; /Herwig/Particles/Z0/Z0->tau-,tau+;\n"
             process+="create Herwig::BranchingRatioReweighter /Herwig/Generators/BRReweighter\n"
             process+="insert /Herwig/Generators/EventGenerator:EventHandler:PostHadronizationHandlers 0 /Herwig/Generators/BRReweighter\n"
         elif(parameterName.find("ZZ-lv")>=0) :
             process+="insert SimpleQCD:MatrixElements[0] MEPP2VV\nset MEPP2VV:Process ZZ\n"
             process+="do /Herwig/Particles/Z0:SelectDecayModes /Herwig/Particles/Z0/Z0->e-,e+; /Herwig/Particles/Z0/Z0->mu-,mu+; /Herwig/Particles/Z0/Z0->tau-,tau+; /Herwig/Particles/Z0/Z0->nu_e,nu_ebar; /Herwig/Particles/Z0/Z0->nu_mu,nu_mubar; /Herwig/Particles/Z0/Z0->nu_tau,nu_taubar;\n"
             process+="create Herwig::BranchingRatioReweighter /Herwig/Generators/BRReweighter\n"
             process+="insert /Herwig/Generators/EventGenerator:EventHandler:PostHadronizationHandlers 0 /Herwig/Generators/BRReweighter\n"
         elif(parameterName.find("W-Z-e")>=0) :
             process+="insert SimpleQCD:MatrixElements[0] MEqq2gZ2ff\nset MEqq2gZ2ff:Process Electron\n"
             process+="insert SimpleQCD:MatrixElements[0] MEqq2W2ff\nset MEqq2W2ff:Process Electron\n"
         elif(parameterName.find("W-Z-mu")>=0) :
             process+="insert SimpleQCD:MatrixElements[0] MEqq2gZ2ff\nset MEqq2gZ2ff:Process Muon\n"
             process+="insert SimpleQCD:MatrixElements[0] MEqq2W2ff\nset MEqq2W2ff:Process Muon\n"
         elif(parameterName.find("W-e")>=0) :
             process+="insert SimpleQCD:MatrixElements[0] MEqq2W2ff\nset MEqq2W2ff:Process Electron\n"
         elif(parameterName.find("W-mu")>=0) :
             process+="insert SimpleQCD:MatrixElements[0] MEqq2W2ff\nset MEqq2W2ff:Process Muon\n"
         elif(parameterName.find("Z-e")>=0) :
             process+="insert SimpleQCD:MatrixElements[0] MEqq2gZ2ff\nset MEqq2gZ2ff:Process Electron\n"
         elif(parameterName.find("Z-mu")>=0) :
             process+="insert SimpleQCD:MatrixElements[0] MEqq2gZ2ff\nset MEqq2gZ2ff:Process Muon\n"
         elif(parameterName.find("Z-LowMass-e")>=0) :
             process+="insert SimpleQCD:MatrixElements[0] MEqq2gZ2ff\nset MEqq2gZ2ff:Process Electron\n"
             process+="set /Herwig/Cuts/QCDCuts:MHatMin 20.*GeV\nset /Herwig/Cuts/MassCut:MinM 20.*GeV\nset /Herwig/Cuts/MassCut:MaxM 70.*GeV\n"
         elif(parameterName.find("Z-MedMass-e")>=0) :
             process+="insert SimpleQCD:MatrixElements[0] MEqq2gZ2ff\nset MEqq2gZ2ff:Process Electron\n"
             process+="set /Herwig/Cuts/QCDCuts:MHatMin 40.*GeV\nset /Herwig/Cuts/MassCut:MinM 40.*GeV\nset /Herwig/Cuts/MassCut:MaxM 130.*GeV\n"
         elif(parameterName.find("Z-LowMass-mu")>=0) :
             process+="insert SimpleQCD:MatrixElements[0] MEqq2gZ2ff\nset MEqq2gZ2ff:Process Muon\n"
             process+="set /Herwig/Cuts/QCDCuts:MHatMin 10.*GeV\nset /Herwig/Cuts/MassCut:MinM 10.*GeV\nset /Herwig/Cuts/MassCut:MaxM 70.*GeV\n"
         elif(parameterName.find("W-Jet")>=0) :
             process+="insert SimpleQCD:MatrixElements[0] MEWJet\nset MEWJet:WDecay Electron\n"
             if(parameterName.find("W-Jet-1-e")>=0) :
                 process+="set /Herwig/Cuts/WBosonKtCut:MinKT 100.0*GeV\n"
                 parameterName=parameterName.replace("W-Jet-1-e","W-Jet-e")
             elif(parameterName.find("W-Jet-2-e")>=0) :
                 process+="set /Herwig/Cuts/WBosonKtCut:MinKT 190.0*GeV\n"
                 parameterName=parameterName.replace("W-Jet-2-e","W-Jet-e")
             elif(parameterName.find("W-Jet-3-e")>=0) :
                 process+="set /Herwig/Cuts/WBosonKtCut:MinKT 270.0*GeV\n"
                 parameterName=parameterName.replace("W-Jet-3-e","W-Jet-e")
         elif(parameterName.find("Z-Jet")>=0) :
             if(parameterName.find("-e")>=0) :
                 process+="insert SimpleQCD:MatrixElements[0] MEZJet\nset MEZJet:ZDecay Electron\n"
                 if(parameterName.find("Z-Jet-0-e")>=0) :
                     process+="set /Herwig/Cuts/ZBosonKtCut:MinKT 35.0*GeV\n"
                     parameterName=parameterName.replace("Z-Jet-0-e","Z-Jet-e")
                 elif(parameterName.find("Z-Jet-1-e")>=0) :
                     process+="set /Herwig/Cuts/ZBosonKtCut:MinKT 100.0*GeV\n"
                     parameterName=parameterName.replace("Z-Jet-1-e","Z-Jet-e")
                 elif(parameterName.find("Z-Jet-2-e")>=0) :
                     process+="set /Herwig/Cuts/ZBosonKtCut:MinKT 190.0*GeV\n"
                     parameterName=parameterName.replace("Z-Jet-2-e","Z-Jet-e")
                 elif(parameterName.find("Z-Jet-3-e")>=0) :
                     process+="set /Herwig/Cuts/ZBosonKtCut:MinKT 270.0*GeV\n"
                     parameterName=parameterName.replace("Z-Jet-3-e","Z-Jet-e")
             else :
                 process+="insert SimpleQCD:MatrixElements[0] MEZJet\nset MEZJet:ZDecay Muon\n"
                 process+="set /Herwig/Cuts/ZBosonKtCut:MinKT 35.0*GeV\n"
                 parameterName=parameterName.replace("Z-Jet-0-mu","Z-Jet-mu")
         else :
             logging.error(" Process %s not supported for internal matrix elements" % name)
             sys.exit(1)
     elif(simulation=="Powheg") :
         if(parameterName.find("8-VBF")>=0) :
             process+="insert SimpleQCD:MatrixElements[0] PowhegMEPP2HiggsVBF\n"
         elif(parameterName.find("VBF")>=0) :
             process+="do /Herwig/Particles/h0:SelectDecayModes h0->tau-,tau+;\n"
             process+="set /Herwig/Particles/tau-:Stable Stable\n"
             process+="insert SimpleQCD:MatrixElements[0] PowhegMEPP2HiggsVBF\n"
         elif(parameterName.find("ggHJet")>=0) :
             logging.error(" Process %s not supported for POWHEG matrix elements" % name)
             sys.exit(1)
         elif(parameterName.find("8-ggH")>=0) :
             process+="insert SimpleQCD:MatrixElements[0] PowhegMEHiggs\n"
         elif(parameterName.find("ggH")>=0) :
             process+="do /Herwig/Particles/h0:SelectDecayModes h0->tau-,tau+;\n"
             process+="set /Herwig/Particles/tau-:Stable Stable\n"
             process+="insert SimpleQCD:MatrixElements[0] PowhegMEHiggs\n"
         elif(parameterName.find("8-WH")>=0) :
             process+="insert SimpleQCD:MatrixElements[0] PowhegMEPP2WH\n"
             process+="set /Herwig/Cuts/JetKtCut:MinKT 0.0*GeV\n"
         elif(parameterName.find("8-ZH")>=0) :
             process+="insert SimpleQCD:MatrixElements[0] PowhegMEPP2ZH\n"
             process+="set /Herwig/Cuts/JetKtCut:MinKT 0.0*GeV\n"
         elif(parameterName.find("WH")>=0) :
             process+="do /Herwig/Particles/h0:SelectDecayModes h0->b,bbar;\n"
             process+="do /Herwig/Particles/W+:SelectDecayModes W+->nu_e,e+; W+->nu_mu,mu+;\n"
             process+="insert SimpleQCD:MatrixElements[0] PowhegMEPP2WH\n"
             process+="set /Herwig/Cuts/JetKtCut:MinKT 0.0*GeV\n"
         elif(parameterName.find("ZH")>=0) :
             process+="do /Herwig/Particles/h0:SelectDecayModes h0->b,bbar;\n"
             process+="do /Herwig/Particles/Z0:SelectDecayModes Z0->e-,e+; Z0->mu-,mu+;\n"
             process+="insert SimpleQCD:MatrixElements[0] PowhegMEPP2ZH\n"
             process+="set /Herwig/Cuts/JetKtCut:MinKT 0.0*GeV\n"
         elif(parameterName.find("UE")>=0) :
             logging.error(" Process %s not supported for powheg matrix elements" % name)
             sys.exit(1)
         elif(parameterName.find("WZ")>=0) :
             process+="create Herwig::HwDecayHandler /Herwig/NewPhysics/DecayHandler\n"
             process+="set /Herwig/NewPhysics/DecayHandler:NewStep No\n"
             process+="insert /Herwig/NewPhysics/DecayHandler:Excluded 0 /Herwig/Particles/tau-\n"
             process+="insert /Herwig/NewPhysics/DecayHandler:Excluded 1 /Herwig/Particles/tau+\n"
             process+="insert /Herwig/Generators/EventGenerator:EventHandler:PreCascadeHandlers 0 /Herwig/NewPhysics/DecayHandler\n"
             process+="insert SimpleQCD:MatrixElements[0] PowhegMEPP2VV\nset PowhegMEPP2VV:Process WZ\n"
             process+="do /Herwig/Particles/W+:SelectDecayModes /Herwig/Particles/W+/W+->nu_e,e+; /Herwig/Particles/W+/W+->nu_mu,mu+;\n"
             process+="do /Herwig/Particles/W-:SelectDecayModes /Herwig/Particles/W-/W-->nu_ebar,e-; /Herwig/Particles/W-/W-->nu_mubar,mu-;\n"
             process+="do /Herwig/Particles/Z0:SelectDecayModes /Herwig/Particles/Z0/Z0->e-,e+; /Herwig/Particles/Z0/Z0->mu-,mu+;\n"
             process+="create Herwig::BranchingRatioReweighter /Herwig/Generators/BRReweighter\n"
             process+="insert /Herwig/Generators/EventGenerator:EventHandler:PostHadronizationHandlers 0 /Herwig/Generators/BRReweighter\n"
         elif(parameterName.find("WW-emu")>=0) :
             process+="create Herwig::HwDecayHandler /Herwig/NewPhysics/DecayHandler\n"
             process+="set /Herwig/NewPhysics/DecayHandler:NewStep No\n"
             process+="insert /Herwig/NewPhysics/DecayHandler:Excluded 0 /Herwig/Particles/tau-\n"
             process+="insert /Herwig/NewPhysics/DecayHandler:Excluded 1 /Herwig/Particles/tau+\n"
             process+="insert /Herwig/Generators/EventGenerator:EventHandler:PreCascadeHandlers 0 /Herwig/NewPhysics/DecayHandler\n"
             process+="insert SimpleQCD:MatrixElements[0] PowhegMEPP2VV\nset PowhegMEPP2VV:Process WW\n"
             process+="set /Herwig/Particles/W+:Synchronized 0\n"
             process+="set /Herwig/Particles/W-:Synchronized 0\n"
             process+="do /Herwig/Particles/W+:SelectDecayModes /Herwig/Particles/W+/W+->nu_e,e+;\n"
             process+="do /Herwig/Particles/W-:SelectDecayModes /Herwig/Particles/W-/W-->nu_mubar,mu-;\n"
             process+="create Herwig::BranchingRatioReweighter /Herwig/Generators/BRReweighter\n"
             process+="insert /Herwig/Generators/EventGenerator:EventHandler:PostHadronizationHandlers 0 /Herwig/Generators/BRReweighter\n"
         elif(parameterName.find("WW-ll")>=0) :
             process+="create Herwig::HwDecayHandler /Herwig/NewPhysics/DecayHandler\n"
             process+="set /Herwig/NewPhysics/DecayHandler:NewStep No\n"
             process+="insert /Herwig/NewPhysics/DecayHandler:Excluded 0 /Herwig/Particles/tau-\n"
             process+="insert /Herwig/NewPhysics/DecayHandler:Excluded 1 /Herwig/Particles/tau+\n"
             process+="insert /Herwig/Generators/EventGenerator:EventHandler:PreCascadeHandlers 0 /Herwig/NewPhysics/DecayHandler\n"
             process+="insert SimpleQCD:MatrixElements[0] PowhegMEPP2VV\nset PowhegMEPP2VV:Process WW\n"
             process+="do /Herwig/Particles/W+:SelectDecayModes /Herwig/Particles/W+/W+->nu_e,e+; /Herwig/Particles/W+/W+->nu_mu,mu+; /Herwig/Particles/W+/W+->nu_tau,tau+;\n"
             process+="create Herwig::BranchingRatioReweighter /Herwig/Generators/BRReweighter\n"
             process+="insert /Herwig/Generators/EventGenerator:EventHandler:PostHadronizationHandlers 0 /Herwig/Generators/BRReweighter\n"
         elif(parameterName.find("ZZ-ll")>=0) :
             process+="create Herwig::HwDecayHandler /Herwig/NewPhysics/DecayHandler\n"
             process+="set /Herwig/NewPhysics/DecayHandler:NewStep No\n"
             process+="insert /Herwig/NewPhysics/DecayHandler:Excluded 0 /Herwig/Particles/tau-\n"
             process+="insert /Herwig/NewPhysics/DecayHandler:Excluded 1 /Herwig/Particles/tau+\n"
             process+="insert /Herwig/Generators/EventGenerator:EventHandler:PreCascadeHandlers 0 /Herwig/NewPhysics/DecayHandler\n"
             process+="insert SimpleQCD:MatrixElements[0] PowhegMEPP2VV\nset PowhegMEPP2VV:Process ZZ\n"
             process+="do /Herwig/Particles/Z0:SelectDecayModes /Herwig/Particles/Z0/Z0->e-,e+; /Herwig/Particles/Z0/Z0->mu-,mu+; /Herwig/Particles/Z0/Z0->tau-,tau+;\n"
             process+="create Herwig::BranchingRatioReweighter /Herwig/Generators/BRReweighter\n"
             process+="insert /Herwig/Generators/EventGenerator:EventHandler:PostHadronizationHandlers 0 /Herwig/Generators/BRReweighter\n"
         elif(parameterName.find("ZZ-lv")>=0) :
             process+="create Herwig::HwDecayHandler /Herwig/NewPhysics/DecayHandler\n"
             process+="set /Herwig/NewPhysics/DecayHandler:NewStep No\n"
             process+="insert /Herwig/NewPhysics/DecayHandler:Excluded 0 /Herwig/Particles/tau-\n"
             process+="insert /Herwig/NewPhysics/DecayHandler:Excluded 1 /Herwig/Particles/tau+\n"
             process+="insert /Herwig/Generators/EventGenerator:EventHandler:PreCascadeHandlers 0 /Herwig/NewPhysics/DecayHandler\n"
             process+="insert SimpleQCD:MatrixElements[0] PowhegMEPP2VV\nset PowhegMEPP2VV:Process ZZ\n"
             process+="do /Herwig/Particles/Z0:SelectDecayModes /Herwig/Particles/Z0/Z0->e-,e+; /Herwig/Particles/Z0/Z0->mu-,mu+; /Herwig/Particles/Z0/Z0->tau-,tau+; /Herwig/Particles/Z0/Z0->nu_e,nu_ebar; /Herwig/Particles/Z0/Z0->nu_mu,nu_mubar; /Herwig/Particles/Z0/Z0->nu_tau,nu_taubar;\n"
             process+="create Herwig::BranchingRatioReweighter /Herwig/Generators/BRReweighter\n"
             process+="insert /Herwig/Generators/EventGenerator:EventHandler:PostHadronizationHandlers 0 /Herwig/Generators/BRReweighter\n"
         elif(parameterName.find("W-Z-e")>=0) :
             process+="insert SimpleQCD:MatrixElements[0] PowhegMEqq2gZ2ff\nset PowhegMEqq2gZ2ff:Process Electron\n"
             process+="insert SimpleQCD:MatrixElements[0] PowhegMEqq2W2ff\nset PowhegMEqq2W2ff:Process Electron\n"
         elif(parameterName.find("W-Z-mu")>=0) :
             process+="insert SimpleQCD:MatrixElements[0] MEqq2gZ2ff\nset MEqq2gZ2ff:Process Muon\n"
             process+="insert SimpleQCD:MatrixElements[0] MEqq2W2ff\nset MEqq2W2ff:Process Muon\n"
         elif(parameterName.find("W-e")>=0) :
             process+="insert SimpleQCD:MatrixElements[0] PowhegMEqq2W2ff\nset PowhegMEqq2W2ff:Process Electron\n"
         elif(parameterName.find("W-mu")>=0) :
             process+="insert SimpleQCD:MatrixElements[0] PowhegMEqq2W2ff\nset PowhegMEqq2W2ff:Process Muon\n"
         elif(parameterName.find("Z-e")>=0) :
             process+="insert SimpleQCD:MatrixElements[0] PowhegMEqq2gZ2ff\nset PowhegMEqq2gZ2ff:Process Electron\n"
         elif(parameterName.find("Z-mu")>=0) :
             process+="insert SimpleQCD:MatrixElements[0] PowhegMEqq2gZ2ff\nset PowhegMEqq2gZ2ff:Process Muon\n"
         elif(parameterName.find("Z-LowMass-e")>=0) :
             process+="insert SimpleQCD:MatrixElements[0] PowhegMEqq2gZ2ff\nset PowhegMEqq2gZ2ff:Process Electron\n"
             process+="set /Herwig/Cuts/QCDCuts:MHatMin 20.*GeV\nset /Herwig/Cuts/MassCut:MinM 20.*GeV\nset /Herwig/Cuts/MassCut:MaxM 70.*GeV\n"
         elif(parameterName.find("Z-MedMass-e")>=0) :
             process+="insert SimpleQCD:MatrixElements[0] PowhegMEqq2gZ2ff\nset PowhegMEqq2gZ2ff:Process Electron\n"
             process+="set /Herwig/Cuts/QCDCuts:MHatMin 40.*GeV\nset /Herwig/Cuts/MassCut:MinM 40.*GeV\nset /Herwig/Cuts/MassCut:MaxM 130.*GeV\n"
         elif(parameterName.find("Z-LowMass-mu")>=0) :
             process+="insert SimpleQCD:MatrixElements[0] PowhegMEqq2gZ2ff\nset PowhegMEqq2gZ2ff:Process Muon\n"
             process+="set /Herwig/Cuts/QCDCuts:MHatMin 10.*GeV\nset /Herwig/Cuts/MassCut:MinM 10.*GeV\nset /Herwig/Cuts/MassCut:MaxM 70.*GeV\n"
+        elif(parameterName.find("DiPhoton-GammaGamma")>=0) :
+            process+="insert SimpleQCD:MatrixElements[0] MEGammaGammaPowheg\n"
+            process+="set MEGammaGammaPowheg:Process GammaGamma\n"
+            process+="insert SimpleQCD:MatrixElements[0] MEGammaGamma\n"
+            process+="set MEGammaGamma:Process gg\n"
+            process+="set /Herwig/Cuts/PhotonKtCut:MinKT 5.\n"
+            process+="set /Herwig/Cuts/JetKtCut:MinKT 5.\n"
+            parameterName=parameterName.replace("-GammaGamma","")
+        elif(parameterName.find("DiPhoton-GammaJet")>=0) :
+            process+="insert SimpleQCD:MatrixElements[0] MEGammaGammaPowheg\n"
+            process+="set MEGammaGammaPowheg:Process VJet\n"
+            process+="set /Herwig/Cuts/PhotonKtCut:MinKT 5.\n"
+            process+="set /Herwig/Cuts/JetKtCut:MinKT 5.\n"
+            parameterName=parameterName.replace("-GammaJet","")
         else :
             logging.error(" Process %s not supported for internal POWHEG matrix elements" % name)
             sys.exit(1)
             
     elif(simulation=="Matchbox" ) :
         if(parameterName.find("8-VBF")>=0) :
             parameters["nlo"] = "read Matchbox/VBFNLO.in\n"
             process+="set Factory:OrderInAlphaS 0\nset Factory:OrderInAlphaEW 3\n"
             process+="insert Factory:DiagramGenerator:RestrictLines 0 /Herwig/Particles/Z0\n"
             process+="insert Factory:DiagramGenerator:RestrictLines 0 /Herwig/Particles/W+\n"
             process+="insert Factory:DiagramGenerator:RestrictLines 0 /Herwig/Particles/W-\n"
             process+="insert Factory:DiagramGenerator:RestrictLines 0 /Herwig/Particles/gamma\n"
             process+="do Factory:DiagramGenerator:TimeLikeRange 0 0\n"
             process+="do Factory:Process p p h0 j j\n"
             process+="set /Herwig/Particles/h0:HardProcessWidth 0.\n"
             process+="set Factory:ScaleChoice /Herwig/MatrixElements/Matchbox/Scales/FixedScale\n"
             process+="set /Herwig/MatrixElements/Matchbox/Scales/FixedScale:FixedScale 125.7\n"
         elif(parameterName.find("VBF")>=0) :
             process+="do /Herwig/Particles/h0:SelectDecayModes h0->tau-,tau+;\n"
             process+="set /Herwig/Particles/tau-:Stable Stable\n"
             parameters["nlo"] = "read Matchbox/VBFNLO.in\n"
             process+="set Factory:OrderInAlphaS 0\nset Factory:OrderInAlphaEW 3\n"
             process+="insert Factory:DiagramGenerator:RestrictLines 0 /Herwig/Particles/Z0\n"
             process+="insert Factory:DiagramGenerator:RestrictLines 0 /Herwig/Particles/W+\n"
             process+="insert Factory:DiagramGenerator:RestrictLines 0 /Herwig/Particles/W-\n"
             process+="insert Factory:DiagramGenerator:RestrictLines 0 /Herwig/Particles/gamma\n"
             process+="do Factory:DiagramGenerator:TimeLikeRange 0 0\n"
             process+="do Factory:Process p p h0 j j\n"
             process+="set /Herwig/Particles/h0:HardProcessWidth 0.\n"
             process+="set Factory:ScaleChoice /Herwig/MatrixElements/Matchbox/Scales/FixedScale\n"
             process+="set /Herwig/MatrixElements/Matchbox/Scales/FixedScale:FixedScale 125.7\n"
         elif(parameterName.find("ggHJet")>=0) :
             parameters["nlo"] = "read Matchbox/MadGraph-GoSam.in\nread Matchbox/HiggsEffective.in\n"
             process+="do /Herwig/Particles/h0:SelectDecayModes h0->tau-,tau+;\n"
             process+="set /Herwig/Particles/tau-:Stable Stable\n"
             process+="set Factory:OrderInAlphaS 3\nset Factory:OrderInAlphaEW 1\n"
             process+="set /Herwig/Particles/h0:HardProcessWidth 0.\n"
             process+="do Factory:Process p p h0 j\n"
             process+="set /Herwig/Cuts/Cuts:JetFinder /Herwig/Cuts/JetFinder\n"
             process+="insert /Herwig/Cuts/Cuts:MultiCuts 0 /Herwig/Cuts/JetCuts\n"
             process+="insert /Herwig/Cuts/JetCuts:JetRegions 0 /Herwig/Cuts/FirstJet\n"
             process+="set /Herwig/Cuts/FirstJet:PtMin 20.\n"
             process+="set Factory:ScaleChoice /Herwig/MatrixElements/Matchbox/Scales/FixedScale\n"
             process+="set /Herwig/MatrixElements/Matchbox/Scales/FixedScale:FixedScale 125.7\n"
         elif(parameterName.find("8-ggH")>=0) :
             parameters["nlo"] = "read Matchbox/MadGraph-GoSam.in\nread Matchbox/HiggsEffective.in\n"
             process+="set Factory:OrderInAlphaS 2\nset Factory:OrderInAlphaEW 1\n"
             process+="set /Herwig/Particles/h0:HardProcessWidth 0.\n"
             process+="do Factory:Process p p h0\n"
             process+="set Factory:ScaleChoice /Herwig/MatrixElements/Matchbox/Scales/FixedScale\n"
             process+="set /Herwig/MatrixElements/Matchbox/Scales/FixedScale:FixedScale 125.7\n"
         elif(parameterName.find("ggH")>=0) :
             parameters["nlo"] = "read Matchbox/MadGraph-GoSam.in\nread Matchbox/HiggsEffective.in\n"
             process+="do /Herwig/Particles/h0:SelectDecayModes h0->tau-,tau+;\n"
             process+="set /Herwig/Particles/tau-:Stable Stable\n"
             process+="set Factory:OrderInAlphaS 2\nset Factory:OrderInAlphaEW 1\n"
             process+="set /Herwig/Particles/h0:HardProcessWidth 0.\n"
             process+="do Factory:Process p p h0\n"
             process+="set Factory:ScaleChoice /Herwig/MatrixElements/Matchbox/Scales/FixedScale\n"
             process+="set /Herwig/MatrixElements/Matchbox/Scales/FixedScale:FixedScale 125.7\n"
         elif(parameterName.find("8-WH")>=0) :
             process+="set Factory:OrderInAlphaS 0\nset Factory:OrderInAlphaEW 2\n"
             process+="set /Herwig/Particles/h0:HardProcessWidth 0.\n"
             process+="do Factory:Process p p W+ h0\n"
             process+="do Factory:Process p p W- h0\n"
             process+="set /Herwig/Particles/W+:HardProcessWidth 0.\n"
             process+="set Factory:ScaleChoice /Herwig/MatrixElements/Matchbox/Scales/FixedScale\n"
             process+="set /Herwig/MatrixElements/Matchbox/Scales/FixedScale:FixedScale 125.7\n"
         elif(parameterName.find("8-ZH")>=0) :
             process+="set Factory:OrderInAlphaS 0\nset Factory:OrderInAlphaEW 2\n"
             process+="set /Herwig/Particles/h0:HardProcessWidth 0.\n"
             process+="set /Herwig/Particles/Z0:HardProcessWidth 0.\n"
             process+="do Factory:Process p p Z0 h0\n"
             process+="set Factory:ScaleChoice /Herwig/MatrixElements/Matchbox/Scales/FixedScale\n"
             process+="set /Herwig/MatrixElements/Matchbox/Scales/FixedScale:FixedScale 125.7\n"
         elif(parameterName.find("WH")>=0) :
             process+="do /Herwig/Particles/h0:SelectDecayModes h0->b,bbar;\n"
             process+="set Factory:OrderInAlphaS 0\nset Factory:OrderInAlphaEW 3\n"
             process+="set /Herwig/Particles/h0:HardProcessWidth 0.\n"
             process+="do Factory:Process p p e+ nu h0\n"
             process+="do Factory:Process p p e- nu h0\n"
             process+="do Factory:Process p p mu+ nu h0\n"
             process+="do Factory:Process p p mu- nu h0\n"
             process+="set Factory:ScaleChoice /Herwig/MatrixElements/Matchbox/Scales/LeptonPairMassScale\n"
             process+="set /Herwig/Cuts/LeptonPairMassCut:MinMass 60*GeV\nset /Herwig/Cuts/LeptonPairMassCut:MaxMass 120*GeV\n"
         elif(parameterName.find("ZH")>=0) :
             process+="do /Herwig/Particles/h0:SelectDecayModes h0->b,bbar;\n"
             process+="set Factory:OrderInAlphaS 0\nset Factory:OrderInAlphaEW 3\n"
             process+="set /Herwig/Particles/h0:HardProcessWidth 0.\n"
             process+="do Factory:Process p p e+ e- h0\n"
             process+="do Factory:Process p p mu+ mu- h0\n"
             process+="set Factory:ScaleChoice /Herwig/MatrixElements/Matchbox/Scales/LeptonPairMassScale\n"
             process+="set /Herwig/Cuts/LeptonPairMassCut:MinMass 60*GeV\nset /Herwig/Cuts/LeptonPairMassCut:MaxMass 120*GeV\n"
         elif(parameterName.find("UE")>=0) :
             logging.error(" Process %s not supported for Matchbox matrix elements" % name)
             sys.exit(1)
         elif(parameterName.find("7-Jets")>=0) :
             process+="set Factory:OrderInAlphaS 2\nset Factory:OrderInAlphaEW 0\n"
             process+="do Factory:Process p p j j\nset Factory:ScaleChoice /Herwig/MatrixElements/Matchbox/Scales/MaxJetPtScale\n"
             process+="set  /Herwig/Cuts/Cuts:JetFinder  /Herwig/Cuts/JetFinder\n"
             process+="insert  /Herwig/Cuts/Cuts:MultiCuts 0  /Herwig/Cuts/JetCuts\n"
             process+="insert  /Herwig/Cuts/JetCuts:JetRegions 0  /Herwig/Cuts/FirstJet\n"
             process+="set /Herwig/UnderlyingEvent/MPIHandler:IdenticalToUE 0\n"
             if(parameterName.find("7-Jets-0")>=0) :
                 process+="set /Herwig/Cuts/FirstJet:PtMin 5.\n"
             elif(parameterName.find("7-Jets-10")>=0) :
                 process+="insert /Herwig/Cuts/JetCuts:JetRegions 0  /Herwig/Cuts/SecondJet\n"
                 process+="set /Herwig/Cuts/FirstJet:PtMin 20.*GeV\n"
                 process+="set /Herwig/Cuts/SecondJet:PtMin 15.*GeV\n"
                 process+="create ThePEG::JetPairRegion /Herwig/Cuts/JetPairMass JetCuts.so\n"
                 process+="set /Herwig/Cuts/JetPairMass:FirstRegion /Herwig/Cuts/FirstJet\n"
                 process+="set /Herwig/Cuts/JetPairMass:SecondRegion /Herwig/Cuts/SecondJet\n"
                 process+="insert /Herwig/Cuts/JetCuts:JetPairRegions 0  /Herwig/Cuts/JetPairMass\n"
                 process+="set /Herwig/Cuts/JetPairMass:MassMin 200.*GeV\n"
             elif(parameterName.find("7-Jets-11")>=0) :
                 process+="insert /Herwig/Cuts/JetCuts:JetRegions 0  /Herwig/Cuts/SecondJet\n"
                 process+="set /Herwig/Cuts/FirstJet:PtMin 20.*GeV\n"
                 process+="set /Herwig/Cuts/SecondJet:PtMin 15.*GeV\n"
                 process+="create ThePEG::JetPairRegion /Herwig/Cuts/JetPairMass JetCuts.so\n"
                 process+="set /Herwig/Cuts/JetPairMass:FirstRegion /Herwig/Cuts/FirstJet\n"
                 process+="set /Herwig/Cuts/JetPairMass:SecondRegion /Herwig/Cuts/SecondJet\n"
                 process+="insert /Herwig/Cuts/JetCuts:JetPairRegions 0  /Herwig/Cuts/JetPairMass\n"
                 process+="set /Herwig/Cuts/JetPairMass:MassMin 600.*GeV\n"
             elif(parameterName.find("7-Jets-12")>=0) :
                 process+="insert /Herwig/Cuts/JetCuts:JetRegions 0  /Herwig/Cuts/SecondJet\n"
                 process+="set /Herwig/Cuts/FirstJet:PtMin 20.*GeV\n"
                 process+="set /Herwig/Cuts/SecondJet:PtMin 15.*GeV\n"
                 process+="create ThePEG::JetPairRegion /Herwig/Cuts/JetPairMass JetCuts.so\n"
                 process+="set /Herwig/Cuts/JetPairMass:FirstRegion /Herwig/Cuts/FirstJet\n"
                 process+="set /Herwig/Cuts/JetPairMass:SecondRegion /Herwig/Cuts/SecondJet\n"
                 process+="insert /Herwig/Cuts/JetCuts:JetPairRegions 0  /Herwig/Cuts/JetPairMass\n"
                 process+="set /Herwig/Cuts/JetPairMass:MassMin 1000.*GeV\n"
             elif(parameterName.find("7-Jets-13")>=0) :
                 process+="insert /Herwig/Cuts/JetCuts:JetRegions 0  /Herwig/Cuts/SecondJet\n"
                 process+="set /Herwig/Cuts/FirstJet:PtMin 20.*GeV\n"
                 process+="set /Herwig/Cuts/SecondJet:PtMin 15.*GeV\n"
                 process+="create ThePEG::JetPairRegion /Herwig/Cuts/JetPairMass JetCuts.so\n"
                 process+="set /Herwig/Cuts/JetPairMass:FirstRegion /Herwig/Cuts/FirstJet\n"
                 process+="set /Herwig/Cuts/JetPairMass:SecondRegion /Herwig/Cuts/SecondJet\n"
                 process+="insert /Herwig/Cuts/JetCuts:JetPairRegions 0  /Herwig/Cuts/JetPairMass\n"
                 process+="set /Herwig/Cuts/JetPairMass:MassMin 1600.*GeV\n"
             elif(parameterName.find("7-Jets-14")>=0) :
                 process+="insert /Herwig/Cuts/JetCuts:JetRegions 0  /Herwig/Cuts/SecondJet\n"
                 process+="set /Herwig/Cuts/FirstJet:PtMin 20.*GeV\n"
                 process+="set /Herwig/Cuts/SecondJet:PtMin 15.*GeV\n"
                 process+="create ThePEG::JetPairRegion /Herwig/Cuts/JetPairMass JetCuts.so\n"
                 process+="set /Herwig/Cuts/JetPairMass:FirstRegion /Herwig/Cuts/FirstJet\n"
                 process+="set /Herwig/Cuts/JetPairMass:SecondRegion /Herwig/Cuts/SecondJet\n"
                 process+="insert /Herwig/Cuts/JetCuts:JetPairRegions 0  /Herwig/Cuts/JetPairMass\n"
                 process+="set /Herwig/Cuts/JetPairMass:MassMin 2200.*GeV\n"
             elif(parameterName.find("7-Jets-15")>=0) :
                 process+="insert /Herwig/Cuts/JetCuts:JetRegions 0  /Herwig/Cuts/SecondJet\n"
                 process+="set /Herwig/Cuts/FirstJet:PtMin 20.*GeV\n"
                 process+="set /Herwig/Cuts/SecondJet:PtMin 15.*GeV\n"
                 process+="create ThePEG::JetPairRegion /Herwig/Cuts/JetPairMass JetCuts.so\n"
                 process+="set /Herwig/Cuts/JetPairMass:FirstRegion /Herwig/Cuts/FirstJet\n"
                 process+="set /Herwig/Cuts/JetPairMass:SecondRegion /Herwig/Cuts/SecondJet\n"
                 process+="insert /Herwig/Cuts/JetCuts:JetPairRegions 0  /Herwig/Cuts/JetPairMass\n"
                 process+="set /Herwig/Cuts/JetPairMass:MassMin 2800.*GeV\n"
             elif(parameterName.find("7-Jets-1")>=0) :
                 process+="set /Herwig/Cuts/FirstJet:PtMin 10.\n"
             elif(parameterName.find("7-Jets-2")>=0) :
                 process+="set /Herwig/Cuts/FirstJet:PtMin 20.\n"
             elif(parameterName.find("7-Jets-3")>=0) :
                 process+="set /Herwig/Cuts/FirstJet:PtMin 40.\n"
             elif(parameterName.find("7-Jets-4")>=0) :
                 process+="set /Herwig/Cuts/FirstJet:PtMin 70.\n"
             elif(parameterName.find("7-Jets-5")>=0) :
                 process+="set /Herwig/Cuts/FirstJet:PtMin 150.\n"
             elif(parameterName.find("7-Jets-6")>=0) :
                 process+="set /Herwig/Cuts/FirstJet:PtMin 200.\n"
             elif(parameterName.find("7-Jets-7")>=0) :
                 process+="set /Herwig/Cuts/FirstJet:PtMin 300.\n"
             elif(parameterName.find("7-Jets-8")>=0) :
                 process+="set /Herwig/Cuts/FirstJet:PtMin 500.\n"
             elif(parameterName.find("7-Jets-9")>=0) :
                 process+="insert /Herwig/Cuts/JetCuts:JetRegions 0  /Herwig/Cuts/SecondJet\n"
                 process+="set /Herwig/Cuts/FirstJet:PtMin 20.*GeV\n"
                 process+="set /Herwig/Cuts/SecondJet:PtMin 15.*GeV\n"
                 process+="create ThePEG::JetPairRegion /Herwig/Cuts/JetPairMass JetCuts.so\n"
                 process+="set /Herwig/Cuts/JetPairMass:FirstRegion /Herwig/Cuts/FirstJet\n"
                 process+="set /Herwig/Cuts/JetPairMass:SecondRegion /Herwig/Cuts/SecondJet\n"
                 process+="insert /Herwig/Cuts/JetCuts:JetPairRegions 0  /Herwig/Cuts/JetPairMass\n"
                 process+="set /Herwig/Cuts/JetPairMass:MassMin 90.*GeV\n"
         elif(parameterName.find("7-Charm")>=0 or \
              parameterName.find("7-Bottom")>=0) :
             parameters["bscheme"]="read Matchbox/FourFlavourScheme.in"
             process+="set /Herwig/Particles/b:HardProcessMass 4.2*GeV\n"
             process+="set /Herwig/Particles/bbar:HardProcessMass 4.2*GeV\n"
             process+="set Factory:OrderInAlphaS 2\nset Factory:OrderInAlphaEW 0\n"
             if(parameterName.find("7-Bottom")>=0) :
                 process+="do Factory:Process p p b bbar\n"
             else:
                 process+="do Factory:Process p p c cbar\n"
             process+="set Factory:ScaleChoice /Herwig/MatrixElements/Matchbox/Scales/MaxJetPtScale\n"
             process+="set  /Herwig/Cuts/Cuts:JetFinder  /Herwig/Cuts/JetFinder\n"
             process+="insert  /Herwig/Cuts/Cuts:MultiCuts 0  /Herwig/Cuts/JetCuts\n"
             process+="insert  /Herwig/Cuts/JetCuts:JetRegions 0  /Herwig/Cuts/FirstJet\n"
             process+="set /Herwig/UnderlyingEvent/MPIHandler:IdenticalToUE 0\n"
             if(parameterName.find("-0")>=0) :
                 process+="set /Herwig/Cuts/FirstJet:PtMin 0.\n"
             elif(parameterName.find("-1")>=0) :
                 process+="set /Herwig/Cuts/FirstJet:PtMin 5.\n"
             elif(parameterName.find("-2")>=0) :
                 process+="set /Herwig/Cuts/FirstJet:PtMin 20.\n"
             elif(parameterName.find("-3")>=0) :
                 process+="set /Herwig/Cuts/FirstJet:PtMin 50.\n"
             elif(parameterName.find("-4")>=0) :
                 process+="set /Herwig/Cuts/FirstJet:PtMin 80.\n"
             elif(parameterName.find("-5")>=0) :
                 process+="set /Herwig/Cuts/FirstJet:PtMin 110.\n"
             elif(parameterName.find("-6")>=0) :
                 process+="insert /Herwig/Cuts/JetCuts:JetRegions 0  /Herwig/Cuts/SecondJet\n"
                 process+="set /Herwig/Cuts/FirstJet:PtMin 30.\n"
                 process+="set /Herwig/Cuts/SecondJet:PtMin 25.\n"
                 process+="create ThePEG::JetPairRegion /Herwig/Cuts/JetPairMass JetCuts.so\n"
                 process+="set /Herwig/Cuts/JetPairMass:FirstRegion /Herwig/Cuts/FirstJet\n"
                 process+="set /Herwig/Cuts/JetPairMass:SecondRegion /Herwig/Cuts/SecondJet\n"
                 process+="insert /Herwig/Cuts/JetCuts:JetPairRegions 0  /Herwig/Cuts/JetPairMass\n"
                 process+="set /Herwig/Cuts/JetPairMass:MassMin 90.*GeV\n"
             elif(parameterName.find("-7")>=0) :
                 process+="insert /Herwig/Cuts/JetCuts:JetRegions 0  /Herwig/Cuts/SecondJet\n"
                 process+="set /Herwig/Cuts/FirstJet:PtMin 30.\n"
                 process+="set /Herwig/Cuts/SecondJet:PtMin 25.\n"
                 process+="create ThePEG::JetPairRegion /Herwig/Cuts/JetPairMass JetCuts.so\n"
                 process+="set /Herwig/Cuts/JetPairMass:FirstRegion /Herwig/Cuts/FirstJet\n"
                 process+="set /Herwig/Cuts/JetPairMass:SecondRegion /Herwig/Cuts/SecondJet\n"
                 process+="insert /Herwig/Cuts/JetCuts:JetPairRegions 0  /Herwig/Cuts/JetPairMass\n"
                 process+="set /Herwig/Cuts/JetPairMass:MassMin 340.*GeV\n"
             elif(parameterName.find("-8")>=0) :
                 process+="insert /Herwig/Cuts/JetCuts:JetRegions 0  /Herwig/Cuts/SecondJet\n"
                 process+="set /Herwig/Cuts/FirstJet:PtMin 30.\n"
                 process+="set /Herwig/Cuts/SecondJet:PtMin 25.\n"
                 process+="create ThePEG::JetPairRegion /Herwig/Cuts/JetPairMass JetCuts.so\n"
                 process+="set /Herwig/Cuts/JetPairMass:FirstRegion /Herwig/Cuts/FirstJet\n"
                 process+="set /Herwig/Cuts/JetPairMass:SecondRegion /Herwig/Cuts/SecondJet\n"
                 process+="insert /Herwig/Cuts/JetCuts:JetPairRegions 0  /Herwig/Cuts/JetPairMass\n"
                 process+="set /Herwig/Cuts/JetPairMass:MassMin 500.*GeV\n"
         elif(parameterName.find("7-Top-L")>=0) :
             process+="set /Herwig/Particles/t:HardProcessWidth 0.*GeV\n"
             process+="set /Herwig/Particles/tbar:HardProcessWidth 0.*GeV\n"
             process+="set Factory:OrderInAlphaS 2\nset Factory:OrderInAlphaEW 0\n"
             process+="do Factory:Process p p t tbar\n"
             process+="set Factory:ScaleChoice /Herwig/MatrixElements/Matchbox/Scales/TopPairMTScale\n"
             process+="do /Herwig/Particles/t:SelectDecayModes t->nu_e,e+,b; t->nu_mu,mu+,b;\n"
             process+="create Herwig::BranchingRatioReweighter /Herwig/Generators/BRReweighter\n"
             process+="insert /Herwig/Generators/EventGenerator:EventHandler:PostHadronizationHandlers 0 /Herwig/Generators/BRReweighter\n"
         elif(parameterName.find("7-Top-SL")>=0) :
             process+="set /Herwig/Particles/t:HardProcessWidth 0.*GeV\n"
             process+="set /Herwig/Particles/tbar:HardProcessWidth 0.*GeV\n"
             process+="set Factory:OrderInAlphaS 2\nset Factory:OrderInAlphaEW 0\n"
             process+="do Factory:Process p p t tbar\n"
             process+="set Factory:ScaleChoice /Herwig/MatrixElements/Matchbox/Scales/TopPairMTScale\n"
             process+="set /Herwig/Particles/t:Synchronized Not_synchronized\n"
             process+="set /Herwig/Particles/tbar:Synchronized Not_synchronized\n"
             process+="do /Herwig/Particles/t:SelectDecayModes t->nu_e,e+,b; t->nu_mu,mu+,b;\n"
             process+="do /Herwig/Particles/tbar:SelectDecayModes tbar->b,bbar,cbar; tbar->bbar,cbar,d; tbar->bbar,cbar,s; tbar->bbar,s,ubar; tbar->bbar,ubar,d;\n"
             process+="create Herwig::BranchingRatioReweighter /Herwig/Generators/BRReweighter\n"
             process+="insert /Herwig/Generators/EventGenerator:EventHandler:PostHadronizationHandlers 0 /Herwig/Generators/BRReweighter\n"
         elif(parameterName.find("7-Top-All")>=0) :
             process+="set /Herwig/Particles/t:HardProcessWidth 0.*GeV\n"
             process+="set /Herwig/Particles/tbar:HardProcessWidth 0.*GeV\n"
             process+="set Factory:OrderInAlphaS 2\nset Factory:OrderInAlphaEW 0\n"
             process+="do Factory:Process p p t tbar\n"
             process+="set Factory:ScaleChoice /Herwig/MatrixElements/Matchbox/Scales/TopPairMTScale\n"
         elif(parameterName.find("WZ")>=0) :
             process+="set /Herwig/Particles/W+:HardProcessWidth 0.*GeV\n"
             process+="set /Herwig/Particles/W-:HardProcessWidth 0.*GeV\n"
             process+="set /Herwig/Particles/Z0:HardProcessWidth 0.*GeV\n"
             process+="set Factory:OrderInAlphaS 0\nset Factory:OrderInAlphaEW 2\ndo Factory:Process p p W+ Z0\ndo Factory:Process p p W- Z0\n"
             process+="set /Herwig/MatrixElements/Matchbox/Scales/FixedScale:FixedScale 171.6*GeV\nset Factory:ScaleChoice /Herwig/MatrixElements/Matchbox/Scales/FixedScale\n\n"
             process+="do /Herwig/Particles/W+:SelectDecayModes /Herwig/Particles/W+/W+->nu_e,e+; /Herwig/Particles/W+/W+->nu_mu,mu+;\n"
             process+="do /Herwig/Particles/W-:SelectDecayModes /Herwig/Particles/W-/W-->nu_ebar,e-; /Herwig/Particles/W-/W-->nu_mubar,mu-;\n"
             process+="do /Herwig/Particles/Z0:SelectDecayModes /Herwig/Particles/Z0/Z0->e-,e+; /Herwig/Particles/Z0/Z0->mu-,mu+;\n"
             process+="create Herwig::BranchingRatioReweighter /Herwig/Generators/BRReweighter\n"
             process+="insert /Herwig/Generators/EventGenerator:EventHandler:PostHadronizationHandlers 0 /Herwig/Generators/BRReweighter\n"
             process+="set /Herwig/Cuts/LeptonPairMassCut:MinMass 60*GeV\nset /Herwig/Cuts/LeptonPairMassCut:MaxMass 120*GeV\n"
         elif(parameterName.find("WW-emu")>=0) :
             process+="set /Herwig/Particles/W+:HardProcessWidth 0.*GeV\n"
             process+="set /Herwig/Particles/W-:HardProcessWidth 0.*GeV\n"
             process+="set /Herwig/Particles/Z0:HardProcessWidth 0.*GeV\n"
             process+="set Factory:OrderInAlphaS 0\nset Factory:OrderInAlphaEW 2\ndo Factory:Process p p W+ W-\n"
             process+="set /Herwig/MatrixElements/Matchbox/Scales/FixedScale:FixedScale 160.8*GeV\nset Factory:ScaleChoice /Herwig/MatrixElements/Matchbox/Scales/FixedScale\n"
             process+="set /Herwig/Particles/W+:Synchronized 0\n"
             process+="set /Herwig/Particles/W-:Synchronized 0\n"
             process+="do /Herwig/Particles/W+:SelectDecayModes /Herwig/Particles/W+/W+->nu_e,e+;\n"
             process+="do /Herwig/Particles/W-:SelectDecayModes /Herwig/Particles/W-/W-->nu_mubar,mu-;\n"
             process+="create Herwig::BranchingRatioReweighter /Herwig/Generators/BRReweighter\n"
             process+="insert /Herwig/Generators/EventGenerator:EventHandler:PostHadronizationHandlers 0 /Herwig/Generators/BRReweighter\n"
             process+="set /Herwig/Cuts/LeptonPairMassCut:MinMass 60*GeV\nset /Herwig/Cuts/LeptonPairMassCut:MaxMass 120*GeV\n"
         elif(parameterName.find("WW-ll")>=0) :
             process+="set /Herwig/Particles/W+:HardProcessWidth 0.*GeV\n"
             process+="set /Herwig/Particles/W-:HardProcessWidth 0.*GeV\n"
             process+="set /Herwig/Particles/Z0:HardProcessWidth 0.*GeV\n"
             process+="set Factory:OrderInAlphaS 0\nset Factory:OrderInAlphaEW 2\ndo Factory:Process p p W+ W-\n"
             process+="set /Herwig/MatrixElements/Matchbox/Scales/FixedScale:FixedScale 160.8*GeV\nset Factory:ScaleChoice /Herwig/MatrixElements/Matchbox/Scales/FixedScale\n"
             process+="do /Herwig/Particles/W+:SelectDecayModes /Herwig/Particles/W+/W+->nu_e,e+; /Herwig/Particles/W+/W+->nu_mu,mu+; /Herwig/Particles/W+/W+->nu_tau,tau+;\n"
             process+="create Herwig::BranchingRatioReweighter /Herwig/Generators/BRReweighter\n"
             process+="insert /Herwig/Generators/EventGenerator:EventHandler:PostHadronizationHandlers 0 /Herwig/Generators/BRReweighter\n"
             process+="set /Herwig/Cuts/LeptonPairMassCut:MinMass 60*GeV\nset /Herwig/Cuts/LeptonPairMassCut:MaxMass 120*GeV\n"
         elif(parameterName.find("ZZ-ll")>=0) :
             process+="set /Herwig/Particles/W+:HardProcessWidth 0.*GeV\n"
             process+="set /Herwig/Particles/W-:HardProcessWidth 0.*GeV\n"
             process+="set /Herwig/Particles/Z0:HardProcessWidth 0.*GeV\n"
             process+="set Factory:OrderInAlphaS 0\nset Factory:OrderInAlphaEW 2\ndo Factory:Process p p Z0 Z0\n"
             process+="set /Herwig/MatrixElements/Matchbox/Scales/FixedScale:FixedScale 182.2*GeV\nset Factory:ScaleChoice /Herwig/MatrixElements/Matchbox/Scales/FixedScale\n"
             process+="do /Herwig/Particles/Z0:SelectDecayModes /Herwig/Particles/Z0/Z0->e-,e+; /Herwig/Particles/Z0/Z0->mu-,mu+; /Herwig/Particles/Z0/Z0->tau-,tau+;\n"
             process+="create Herwig::BranchingRatioReweighter /Herwig/Generators/BRReweighter\n"
             process+="insert /Herwig/Generators/EventGenerator:EventHandler:PostHadronizationHandlers 0 /Herwig/Generators/BRReweighter\n"
             process+="set /Herwig/Cuts/LeptonPairMassCut:MinMass 60*GeV\nset /Herwig/Cuts/LeptonPairMassCut:MaxMass 120*GeV\n"
         elif(parameterName.find("ZZ-lv")>=0) :
             process+="set /Herwig/Particles/W+:HardProcessWidth 0.*GeV\n"
             process+="set /Herwig/Particles/W-:HardProcessWidth 0.*GeV\n"
             process+="set /Herwig/Particles/Z0:HardProcessWidth 0.*GeV\n"
             process+="set Factory:OrderInAlphaS 0\nset Factory:OrderInAlphaEW 2\ndo Factory:Process p p Z0 Z0\n"
             process+="set /Herwig/MatrixElements/Matchbox/Scales/FixedScale:FixedScale 182.2*GeV\nset Factory:ScaleChoice /Herwig/MatrixElements/Matchbox/Scales/FixedScale\n"
             process+="do /Herwig/Particles/Z0:SelectDecayModes /Herwig/Particles/Z0/Z0->e-,e+; /Herwig/Particles/Z0/Z0->mu-,mu+; /Herwig/Particles/Z0/Z0->tau-,tau+; /Herwig/Particles/Z0/Z0->nu_e,nu_ebar; /Herwig/Particles/Z0/Z0->nu_mu,nu_mubar; /Herwig/Particles/Z0/Z0->nu_tau,nu_taubar;\n"
             process+="create Herwig::BranchingRatioReweighter /Herwig/Generators/BRReweighter\n"
             process+="insert /Herwig/Generators/EventGenerator:EventHandler:PostHadronizationHandlers 0 /Herwig/Generators/BRReweighter\n"
             process+="set /Herwig/Cuts/LeptonPairMassCut:MinMass 60*GeV\nset /Herwig/Cuts/LeptonPairMassCut:MaxMass 120*GeV\n"
         elif(parameterName.find("W-Z-e")>=0) :
             process+="set Factory:OrderInAlphaS 0\nset Factory:OrderInAlphaEW 2\n"
             process+="do Factory:Process p p e+ e-\ndo Factory:Process p p e+ nu\ndo Factory:Process p p e- nu\n"
             process+="set Factory:ScaleChoice /Herwig/MatrixElements/Matchbox/Scales/LeptonPairMassScale\n"
             process+="set /Herwig/Cuts/LeptonPairMassCut:MinMass 60*GeV\nset /Herwig/Cuts/LeptonPairMassCut:MaxMass 120*GeV\n"
         elif(parameterName.find("W-Z-mu")>=0) :
             process+="set Factory:OrderInAlphaS 0\nset Factory:OrderInAlphaEW 2\n"
             process+="do Factory:Process p p mu+ mu-\ndo Factory:Process p p mu+ nu\ndo Factory:Process p p mu- nu\n"
             process+="set Factory:ScaleChoice /Herwig/MatrixElements/Matchbox/Scales/LeptonPairMassScale\n"
             process+="set /Herwig/Cuts/LeptonPairMassCut:MinMass 60*GeV\nset /Herwig/Cuts/LeptonPairMassCut:MaxMass 120*GeV\n"
         elif(parameterName.find("W-e")>=0) :
             process+="set Factory:OrderInAlphaS 0\nset Factory:OrderInAlphaEW 2\ndo Factory:Process p p e+ nu\ndo Factory:Process p p e- nu\nset Factory:ScaleChoice /Herwig/MatrixElements/Matchbox/Scales/LeptonPairMassScale\n"
             process+="set /Herwig/Cuts/LeptonPairMassCut:MinMass 60*GeV\nset /Herwig/Cuts/LeptonPairMassCut:MaxMass 120*GeV\n"
         elif(parameterName.find("W-mu")>=0) :
             process+="set Factory:OrderInAlphaS 0\nset Factory:OrderInAlphaEW 2\ndo Factory:Process p p mu+ nu\ndo Factory:Process p p mu- nu\nset Factory:ScaleChoice /Herwig/MatrixElements/Matchbox/Scales/LeptonPairMassScale\n"
             process+="set /Herwig/Cuts/LeptonPairMassCut:MinMass 60*GeV\nset /Herwig/Cuts/LeptonPairMassCut:MaxMass 120*GeV\n"
         elif(parameterName.find("Z-e")>=0) :
             process+="set Factory:OrderInAlphaS 0\nset Factory:OrderInAlphaEW 2\ndo Factory:Process p p e+ e-\nset Factory:ScaleChoice /Herwig/MatrixElements/Matchbox/Scales/LeptonPairMassScale\n"
             process+="set /Herwig/Cuts/LeptonPairMassCut:MinMass 60*GeV\nset /Herwig/Cuts/LeptonPairMassCut:MaxMass 120*GeV\n"
         elif(parameterName.find("Z-mu")>=0) :
             process+="set Factory:OrderInAlphaS 0\nset Factory:OrderInAlphaEW 2\ndo Factory:Process p p mu+ mu-\nset Factory:ScaleChoice /Herwig/MatrixElements/Matchbox/Scales/LeptonPairMassScale\n"
             process+="set /Herwig/Cuts/LeptonPairMassCut:MinMass 60*GeV\nset /Herwig/Cuts/LeptonPairMassCut:MaxMass 120*GeV\n"
         elif(parameterName.find("Z-jj")>=0) :
             process+="set Factory:OrderInAlphaS 2\nset Factory:OrderInAlphaEW 2\n"
             process+="do Factory:Process p p e+ e- j j\n"
             process+="set Factory:ScaleChoice /Herwig/MatrixElements/Matchbox/Scales/LeptonPairMassScale\n"
             process+="set  /Herwig/Cuts/Cuts:JetFinder  /Herwig/Cuts/JetFinder\n"
             process+="insert  /Herwig/Cuts/Cuts:MultiCuts 0  /Herwig/Cuts/JetCuts\n"
             process+="insert  /Herwig/Cuts/JetCuts:JetRegions 0  /Herwig/Cuts/FirstJet\n"
             process+="insert  /Herwig/Cuts/JetCuts:JetRegions 0  /Herwig/Cuts/SecondJet\n"
             process+="set /Herwig/Cuts/FirstJet:PtMin 40.*GeV\n"
             process+="set /Herwig/Cuts/SecondJet:PtMin 30.*GeV\n"
             process+="set /Herwig/Cuts/LeptonPairMassCut:MinMass 60*GeV\nset /Herwig/Cuts/LeptonPairMassCut:MaxMass 120*GeV\n"
         elif(parameterName.find("Z-LowMass-e")>=0) :
             process+="set Factory:OrderInAlphaS 0\nset Factory:OrderInAlphaEW 2\ndo Factory:Process p p e+ e-\nset Factory:ScaleChoice /Herwig/MatrixElements/Matchbox/Scales/LeptonPairMassScale\n"
             process+="set /Herwig/Cuts/LeptonPairMassCut:MinMass 20*GeV\nset /Herwig/Cuts/LeptonPairMassCut:MaxMass 70*GeV\n"
         elif(parameterName.find("Z-MedMass-e")>=0) :
             process+="set Factory:OrderInAlphaS 0\nset Factory:OrderInAlphaEW 2\ndo Factory:Process p p e+ e-\nset Factory:ScaleChoice /Herwig/MatrixElements/Matchbox/Scales/LeptonPairMassScale\n"
             process+="set /Herwig/Cuts/LeptonPairMassCut:MinMass 40*GeV\nset /Herwig/Cuts/LeptonPairMassCut:MaxMass 130*GeV\n"
         elif(parameterName.find("Z-LowMass-mu")>=0) :
             process+="set Factory:OrderInAlphaS 0\nset Factory:OrderInAlphaEW 2\ndo Factory:Process p p mu+ mu-\nset Factory:ScaleChoice /Herwig/MatrixElements/Matchbox/Scales/LeptonPairMassScale\n"
             process+="set /Herwig/Cuts/LeptonPairMassCut:MinMass 10*GeV\nset /Herwig/Cuts/LeptonPairMassCut:MaxMass 70*GeV\n"
         elif(parameterName.find("W-Jet")>=0) :
             process+="set Factory:OrderInAlphaS 1\nset Factory:OrderInAlphaEW 2\ndo Factory:Process p p e+ nu j\ndo Factory:Process p p e- nu j\n\n"
             process+="set Factory:ScaleChoice /Herwig/MatrixElements/Matchbox/Scales/HTScale\n"
             process+="set /Herwig/Cuts/LeptonPairMassCut:MinMass 60*GeV\nset /Herwig/Cuts/LeptonPairMassCut:MaxMass 120*GeV\n"
             process+="set /Herwig/Cuts/Cuts:JetFinder /Herwig/Cuts/JetFinder\n"
             process+="insert /Herwig/Cuts/Cuts:MultiCuts 0 /Herwig/Cuts/JetCuts\n"
             process+="insert /Herwig/Cuts/JetCuts:JetRegions 0 /Herwig/Cuts/FirstJet\n"
             if(parameterName.find("W-Jet-1-e")>=0) :
                 process+="set /Herwig/Cuts/FirstJet:PtMin 100.*GeV\n"
                 parameterName=parameterName.replace("W-Jet-1-e","W-Jet-e")
             elif(parameterName.find("W-Jet-2-e")>=0) :
                 process+="set /Herwig/Cuts/FirstJet:PtMin 190.0*GeV\n"
                 parameterName=parameterName.replace("W-Jet-2-e","W-Jet-e")
             elif(parameterName.find("W-Jet-3-e")>=0) :
                 process+="set /Herwig/Cuts/FirstJet:PtMin 270.0*GeV\n"
                 parameterName=parameterName.replace("W-Jet-3-e","W-Jet-e")
         elif(parameterName.find("Z-Jet")>=0) :
             process+="set Factory:OrderInAlphaS 1\nset Factory:OrderInAlphaEW 2\n"
             if(parameterName.find("-e")>=0) :
                 process+="do Factory:Process p p e+ e- j\n"
                 if(parameterName.find("Z-Jet-0-e")>=0) :
                     process+="set /Herwig/Cuts/FirstJet:PtMin 35.*GeV\n"
                     parameterName=parameterName.replace("Z-Jet-0-e","Z-Jet-e")
                 elif(parameterName.find("Z-Jet-1-e")>=0) :
                     process+="set /Herwig/Cuts/FirstJet:PtMin 100.*GeV\n"
                     parameterName=parameterName.replace("Z-Jet-1-e","Z-Jet-e")
                 elif(parameterName.find("Z-Jet-2-e")>=0) :
                     process+="set /Herwig/Cuts/FirstJet:PtMin 190.0*GeV\n"
                     parameterName=parameterName.replace("Z-Jet-2-e","Z-Jet-e")
                 elif(parameterName.find("Z-Jet-3-e")>=0) :
                     process+="set /Herwig/Cuts/FirstJet:PtMin 270.0*GeV\n"
                     parameterName=parameterName.replace("Z-Jet-3-e","Z-Jet-e")
             else :
                 process+="do Factory:Process p p mu+ mu- j\n"
                 process+="set /Herwig/Cuts/FirstJet:PtMin 35.*GeV\n"
                 parameterName=parameterName.replace("Z-Jet-0-mu","Z-Jet-mu")
             process+="set /Herwig/Cuts/LeptonPairMassCut:MinMass 60*GeV\nset /Herwig/Cuts/LeptonPairMassCut:MaxMass 120*GeV\n"
             process+="set Factory:ScaleChoice /Herwig/MatrixElements/Matchbox/Scales/HTScale\n"
             process+="set /Herwig/Cuts/Cuts:JetFinder /Herwig/Cuts/JetFinder\n"
             process+="insert /Herwig/Cuts/Cuts:MultiCuts 0 /Herwig/Cuts/JetCuts\n"
             process+="insert /Herwig/Cuts/JetCuts:JetRegions 0 /Herwig/Cuts/FirstJet\n"
         elif(parameterName.find("Z-bb")>=0) :
             parameters["bscheme"]="read Matchbox/FourFlavourScheme.in"
             process+="set /Herwig/Particles/b:HardProcessMass 4.2*GeV\nset /Herwig/Particles/bbar:HardProcessMass 4.2*GeV\n"
             process+="set Factory:OrderInAlphaS 2\nset Factory:OrderInAlphaEW 2\ndo Factory:Process p p e+ e- b bbar\n"
             process+="set /Herwig/MatrixElements/Matchbox/Scales/FixedScale:FixedScale 91.2*GeV\nset Factory:ScaleChoice /Herwig/MatrixElements/Matchbox/Scales/FixedScale\n"
             process+="set /Herwig/Cuts/LeptonPairMassCut:MinMass 66*GeV\nset /Herwig/Cuts/LeptonPairMassCut:MaxMass 116*GeV\n"
             process+="set /Herwig/Cuts/Cuts:JetFinder /Herwig/Cuts/JetFinder\n"
             process+="insert  /Herwig/Cuts/Cuts:MultiCuts 0  /Herwig/Cuts/JetCuts\n"
             process+="insert  /Herwig/Cuts/JetCuts:JetRegions 0  /Herwig/Cuts/FirstJet\n"
             process+="insert  /Herwig/Cuts/JetCuts:JetRegions 0  /Herwig/Cuts/SecondJet\n"
             process+="set  /Herwig/Cuts/FirstJet:PtMin 18.*GeV\n"
             process+="set  /Herwig/Cuts/SecondJet:PtMin 15.*GeV\n"
             process+="set /Herwig/Cuts/LeptonPairMassCut:MinMass 60*GeV\nset /Herwig/Cuts/LeptonPairMassCut:MaxMass 120*GeV\n"
         elif(parameterName.find("Z-b")>=0) :
             process+="do Factory:StartParticleGroup bjet\n"
             process+="insert Factory:ParticleGroup 0 /Herwig/Particles/b\n"
             process+="insert Factory:ParticleGroup 0 /Herwig/Particles/bbar\n"
             process+="do Factory:EndParticleGroup\n"
             process+="set Factory:OrderInAlphaS 1\nset Factory:OrderInAlphaEW 2\ndo Factory:Process p p e+ e- bjet\n"
             process+="set /Herwig/MatrixElements/Matchbox/Scales/FixedScale:FixedScale 91.2*GeV\nset Factory:ScaleChoice /Herwig/MatrixElements/Matchbox/Scales/FixedScale\n"
             process+="set /Herwig/Cuts/LeptonPairMassCut:MinMass 60*GeV\nset /Herwig/Cuts/LeptonPairMassCut:MaxMass 120*GeV\n"
             process+="set /Herwig/Cuts/Cuts:JetFinder /Herwig/Cuts/JetFinder\n"
             process+="insert  /Herwig/Cuts/Cuts:MultiCuts 0  /Herwig/Cuts/JetCuts\n"
             process+="insert  /Herwig/Cuts/JetCuts:JetRegions 0  /Herwig/Cuts/FirstJet\n"
             process+="set  /Herwig/Cuts/FirstJet:PtMin 15.*GeV\n"
         elif(parameterName.find("W-b")>=0) :
             parameters["bscheme"]="read Matchbox/FourFlavourScheme.in"
             process += "set /Herwig/Particles/b:HardProcessMass 4.2*GeV\nset /Herwig/Particles/bbar:HardProcessMass 4.2*GeV\n"
             process += "set Factory:OrderInAlphaS 2\nset Factory:OrderInAlphaEW 2\n"
             process += "do Factory:Process p p e+  nu b bbar\ndo Factory:Process p p e-  nu b bbar\n"
             process += "do Factory:Process p p mu+ nu b bbar\ndo Factory:Process p p mu- nu b bbar\n"
             process += "set /Herwig/MatrixElements/Matchbox/Scales/FixedScale:FixedScale 80.4*GeV\nset Factory:ScaleChoice /Herwig/MatrixElements/Matchbox/Scales/FixedScale\n"
             process+="set /Herwig/Cuts/Cuts:JetFinder /Herwig/Cuts/JetFinder\n"
             process+="insert  /Herwig/Cuts/Cuts:MultiCuts 0  /Herwig/Cuts/JetCuts\n"
             process+="insert  /Herwig/Cuts/JetCuts:JetRegions 0  /Herwig/Cuts/FirstJet\n"
             process+="set  /Herwig/Cuts/FirstJet:PtMin 30.*GeV\n"
             process+="set /Herwig/Cuts/LeptonPairMassCut:MinMass 60*GeV\nset /Herwig/Cuts/LeptonPairMassCut:MaxMass 120*GeV\n"
         else :
             logging.error(" Process %s not supported for Matchbox matrix elements" % name)
             sys.exit(1)
 # Star
 elif(collider=="LHC-GammaGamma" ) :
     if(parameterName.find("-7-")>=0) :
         process="set /Herwig/Generators/EventGenerator:EventHandler:LuminosityFunction:Energy 7000.0\n"
     elif(parameterName.find("-8-")>=0) :
         process="set /Herwig/Generators/EventGenerator:EventHandler:LuminosityFunction:Energy 8000.0\n"
     else :
         process="set /Herwig/Generators/EventGenerator:EventHandler:LuminosityFunction:Energy 7000.0\n"
     if(simulation=="") :
         if(parameterName.find("7")>=0) :
             process += "insert SimpleQCD:MatrixElements 0 /Herwig/MatrixElements/MEgg2ff\n"
             process += "set /Herwig/MatrixElements/MEgg2ff:Process Muon\n"
         else :
             logging.error(" Process %s not supported for default matrix elements" % name)
             sys.exit(1)
     else :
         logging.error("LHC-GammaGamma not supported for %s " % simulation)
         sys.exit(1)
 
 
 parameters['parameterFile'] = os.path.join(collider,collider+"-"+parameterName+".in")
 parameters['runname'] = name
 parameters['process'] = process
 
 # write the file
 if(simulation=="Matchbox" ) :
     with open(os.path.join("Rivet",name+".in") ,'w') as f:
         f.write( template.substitute(parameters))
 else :
     with open(os.path.join("Rivet",name+".in") ,'w') as f:
         f.write( template.substitute(parameters))
 
 
 
 
 
 
diff --git a/Tests/python/merge-LHC-Photon b/Tests/python/merge-LHC-Photon
--- a/Tests/python/merge-LHC-Photon
+++ b/Tests/python/merge-LHC-Photon
@@ -1,252 +1,265 @@
 #! /usr/bin/env python
 import logging
 import sys
 import os, yoda
 
 """%prog
 
 Script for merging aida files
 
 """
 
 def fillAbove(scale,desthisto, sourcehistosbyptmin):
     pthigh= 1e100
     ptlow =-1e100
     for pt, h in sorted(sourcehistosbyptmin.iteritems(),reverse=True):
         ptlow=pt
         if(type(desthisto)==yoda.core.Scatter2D) :
             for i in range(0,h.numPoints) :
                 xMin = h.points[i].x-h.points[i].xErrs.minus
                 if( xMin*scale >= ptlow and 
                     xMin*scale <  pthigh ) :
                     desthisto.addPoint(h.points[i])
         elif(type(desthisto)==yoda.core.Profile1D) :
             for i in range(0,h.numBins) :
                 if(h.bins[i].xMin*scale  >= ptlow and 
                    h.bins[i].xMin*scale  <  pthigh ) :
                     desthisto.bins[i] += h.bins[i]
         elif(type(desthisto)==yoda.core.Histo1D) :
             for i in range(0,h.numBins) :
                 if(h.bins[i].xMin*scale  >= ptlow and 
                    h.bins[i].xMin*scale  <  pthigh ) :
                     desthisto.bins[i] += h.bins[i]
         else :
             logging.error("Can't merge %s, unknown type" % desthisto.path)
             sys.exit(1)
         pthigh=pt
 
 def mergeByPt(hpath, scale=1.):
     global inhistos
     global outhistos
     try:
         fillAbove(scale,outhistos[hpath], inhistos[hpath])
     except:
         pass
 
 def useOnePt(hpath, ptmin):
     global inhistos
     global outhistos
     try:
        ## Find best pT_min match
         ptmins = inhistos[hpath].keys()
         closest_ptmin = None
         for ptm in ptmins:
             if closest_ptmin is None or \
                     abs(ptm-float(ptmin)) < abs(closest_ptmin-float(ptmin)):
                 closest_ptmin = ptm
         if closest_ptmin != float(ptmin):
             logging.warning("Inexact match for requested pTmin=%s: " % ptmin + \
                                 "using pTmin=%e instead" % closest_ptmin)
         outhistos[hpath] =  inhistos[hpath][closest_ptmin]
     except:
         pass
 
 if sys.version_info[:3] < (2,4,0):
     print "rivet scripts require Python version >= 2.4.0... exiting"
     sys.exit(1)
 
 if __name__ == "__main__":
     import logging
     from optparse import OptionParser, OptionGroup
     parser = OptionParser(usage="%prog aidafile aidafile2 [...]")
     parser.add_option("-o", "--out", dest="OUTFILE", default="-")
     verbgroup = OptionGroup(parser, "Verbosity control")
     verbgroup.add_option("-v", "--verbose", action="store_const", const=logging.DEBUG, dest="LOGLEVEL",
                          default=logging.INFO, help="print debug (very verbose) messages")
     verbgroup.add_option("-q", "--quiet", action="store_const", const=logging.WARNING, dest="LOGLEVEL",
                          default=logging.INFO, help="be very quiet")
     parser.add_option_group(verbgroup)
     (opts, args) = parser.parse_args()
     logging.basicConfig(level=opts.LOGLEVEL, format="%(message)s")
 
+    ## Check args
+    if len(args) < 1:
+        logging.error("Must specify at least the name of the files")
+        sys.exit(1)
+
 files=["-7-PromptPhoton-1.yoda","-7-PromptPhoton-2.yoda",
        "-7-PromptPhoton-3.yoda","-7-PromptPhoton-4.yoda",
-       "-7-DiPhoton.yoda","-GammaGamma-7.yoda"]
+       "-7-DiPhoton-GammaGamma.yoda","-7-DiPhoton-GammaJet.yoda","-GammaGamma-7.yoda"]
 
 ## Get histos
 inhistos = {}
 outhistos={}
 for f in files:
-    file="LHC"+f
+    file=args[0]+f
     if not os.access(file, os.R_OK):
         logging.error("%s can not be read" % file)
-        break
+        continue
     try:
         aos = yoda.read(file)
     except:
         logging.error("%s can not be parsed as XML" % file)
         break
     if(file.find("PromptPhoton")>=0) :
         if(file.find("-7-PromptPhoton-1")>0) :
             ptmin=0.
         elif(file.find("-7-PromptPhoton-2")>0) :
             ptmin=35.
         elif(file.find("-7-PromptPhoton-3")>0) :
             ptmin=90.
         elif(file.find("-7-PromptPhoton-4")>0) :
             ptmin=170.
         ## Get histos from this YODA file
         for aopath, ao in aos.iteritems() :
             if not inhistos.has_key(aopath):
                 inhistos[aopath] = {}
             if (aopath.find("CMS_2013_I1258128")>0) :
                 if(aopath.find("d05")>0 or aopath.find("d06")>0 or
                    aopath.find("d07")>0 or aopath.find("d08")>0) :
                     inhistos[aopath][ptmin] = ao
             else :
                 inhistos[aopath][ptmin] = ao
     else : 
         ## Get histos from this YODA file
         for aopath, ao in aos.iteritems() :
-            outhistos[aopath] = ao
-
+            if(aopath.find("XSEC")>=0 or aopath.find("EVTCOUNT")>=0) : continue
+            print aopath
+            if ( aopath in outhistos ) :
+                aotype = type(ao)
+                if aotype in (yoda.Counter, yoda.Histo1D, yoda.Histo2D, yoda.Profile1D, yoda.Profile2D):
+                    outhistos[aopath] += ao
+                else :
+                    quit()
+            else:
+                outhistos[aopath] = ao
 
 for hpath,hsets in inhistos.iteritems():
     if( hpath.find("1263495")>0  or 
         hpath.find("1093738")>0 or 
         hpath.find("921594")>0 or 
         hpath.find("8914702")>0 or 
         hpath.find("1244522")>0 ) :
         if(type(hsets.values()[0])==yoda.core.Scatter2D) :
             outhistos[hpath] = yoda.core.Scatter2D(hsets.values()[0].path,
                                                    hsets.values()[0].title)
         elif(type(hsets.values()[0])==yoda.core.Profile1D) :
             outhistos[hpath] = yoda.core.Profile1D(hsets.values()[0].path,
                                                    hsets.values()[0].title)
             for i in range(0,hsets.values()[0].numBins) :
                 outhistos[hpath].addBin(hsets.values()[0].bins[i].xMin,
                                         hsets.values()[0].bins[i].xMax)
         elif(type(hsets.values()[0])==yoda.core.Histo1D) :
             outhistos[hpath] = yoda.core.Histo1D(hsets.values()[0].path,
                                                 hsets.values()[0].title)
             for i in range(0,hsets.values()[0].numBins) :
                 outhistos[hpath].addBin(hsets.values()[0].bins[i].xMin,
                                         hsets.values()[0].bins[i].xMax)
         else :
             logging.error("Histogram %s is of unknown type" % hpath)
             print hpath,type(hsets.values()[0])
             sys.exit(1)
 
 
 
 logging.info("Processing ATLAS_2013_I1263495")
 mergeByPt("/ATLAS_2013_I1263495/d01-x01-y01")
 mergeByPt("/ATLAS_2013_I1263495/d01-x01-y03")
 useOnePt("/ATLAS_2013_I1263495/d01-x02-y01", "90" )
 
 logging.info("Processing ATLAS_2012_I1093738")
 mergeByPt("/ATLAS_2012_I1093738/d01-x01-y01")
 mergeByPt("/ATLAS_2012_I1093738/d02-x01-y01")
 mergeByPt("/ATLAS_2012_I1093738/d03-x01-y01")
 mergeByPt("/ATLAS_2012_I1093738/d04-x01-y01")
 mergeByPt("/ATLAS_2012_I1093738/d05-x01-y01")
 mergeByPt("/ATLAS_2012_I1093738/d06-x01-y01")
 
 
 logging.info("Processing ATLAS_2011_I921594")
 mergeByPt("/ATLAS_2011_I921594/d01-x01-y01")
 mergeByPt("/ATLAS_2011_I921594/d01-x01-y02")
 mergeByPt("/ATLAS_2011_I921594/d01-x01-y04")
 mergeByPt("/ATLAS_2011_I921594/d01-x01-y05")
 
 logging.info("Processing ATLAS_2010_S8914702")
 mergeByPt("/ATLAS_2010_S8914702/d01-x01-y01")
 mergeByPt("/ATLAS_2010_S8914702/d01-x01-y02")
 mergeByPt("/ATLAS_2010_S8914702/d01-x01-y03")
 
 logging.info("Processing CMS_2013_I1258128")
 useOnePt("/CMS_2013_I1258128/d05-x01-y01", "35" )
 useOnePt("/CMS_2013_I1258128/d06-x01-y01", "35" )
 useOnePt("/CMS_2013_I1258128/d07-x01-y01", "35" )
 useOnePt("/CMS_2013_I1258128/d08-x01-y01", "35" )
 
 logging.info("Processing ATLAS_2013_I1244522")
 mergeByPt("/ATLAS_2013_I1244522/d01-x01-y01")
 mergeByPt("/ATLAS_2013_I1244522/d02-x01-y01")
 useOnePt("/ATLAS_2013_I1244522/d03-x01-y01", "35" )
 useOnePt("/ATLAS_2013_I1244522/d04-x01-y01", "35" )
 useOnePt("/ATLAS_2013_I1244522/d05-x01-y01", "35" )
 useOnePt("/ATLAS_2013_I1244522/d06-x01-y01", "35" )
 useOnePt("/ATLAS_2013_I1244522/d07-x01-y01", "35" )
 
 logging.info("Processing /MC_PHOTONJETS")
 useOnePt("/MC_PHOTONJETS/jet_HT","0")
 useOnePt("/MC_PHOTONJETS/jet_eta_1","0")
 useOnePt("/MC_PHOTONJETS/jet_eta_2","0")
 useOnePt("/MC_PHOTONJETS/jet_eta_3","0")
 useOnePt("/MC_PHOTONJETS/jet_eta_4","0")
 useOnePt("/MC_PHOTONJETS/jet_eta_pmratio_1","0")
 useOnePt("/MC_PHOTONJETS/jet_eta_pmratio_2","0")
 useOnePt("/MC_PHOTONJETS/jet_eta_pmratio_3","0")
 useOnePt("/MC_PHOTONJETS/jet_eta_pmratio_4","0")
 useOnePt("/MC_PHOTONJETS/jet_mass_1","0")
 useOnePt("/MC_PHOTONJETS/jet_mass_2","0")
 useOnePt("/MC_PHOTONJETS/jet_mass_3","0")
 useOnePt("/MC_PHOTONJETS/jet_mass_4","0")
 useOnePt("/MC_PHOTONJETS/jet_multi_exclusive","0")
 useOnePt("/MC_PHOTONJETS/jet_multi_inclusive","0")
 useOnePt("/MC_PHOTONJETS/jet_multi_ratio","0")
 useOnePt("/MC_PHOTONJETS/jet_pT_1","0")
 useOnePt("/MC_PHOTONJETS/jet_pT_2","0")
 useOnePt("/MC_PHOTONJETS/jet_pT_3","0")
 useOnePt("/MC_PHOTONJETS/jet_pT_4","0")
 useOnePt("/MC_PHOTONJETS/jet_y_1","0")
 useOnePt("/MC_PHOTONJETS/jet_y_2","0")
 useOnePt("/MC_PHOTONJETS/jet_y_3","0")
 useOnePt("/MC_PHOTONJETS/jet_y_4","0")
 useOnePt("/MC_PHOTONJETS/jet_y_pmratio_1","0")
 useOnePt("/MC_PHOTONJETS/jet_y_pmratio_2","0")
 useOnePt("/MC_PHOTONJETS/jet_y_pmratio_3","0")
 useOnePt("/MC_PHOTONJETS/jet_y_pmratio_4","0")
 useOnePt("/MC_PHOTONJETS/jets_dR_12","0")
 useOnePt("/MC_PHOTONJETS/jets_dR_13","0")
 useOnePt("/MC_PHOTONJETS/jets_dR_23","0")
 useOnePt("/MC_PHOTONJETS/jets_deta_12","0")
 useOnePt("/MC_PHOTONJETS/jets_deta_13","0")
 useOnePt("/MC_PHOTONJETS/jets_deta_23","0")
 useOnePt("/MC_PHOTONJETS/jets_dphi_12","0")
 useOnePt("/MC_PHOTONJETS/jets_dphi_13","0")
 useOnePt("/MC_PHOTONJETS/jets_dphi_23","0")
 useOnePt("/MC_PHOTONJETS/photon_jet1_dR","0")
 useOnePt("/MC_PHOTONJETS/photon_jet1_deta","0")
 useOnePt("/MC_PHOTONJETS/photon_jet1_dphi","0")
 useOnePt("/MC_PHOTONJETUE/gammajet-dR","0")
 useOnePt("/MC_PHOTONJETUE/gammajet-dphi","0")
 useOnePt("/MC_PHOTONJETUE/trans-maxnchg-gamma","0")
 useOnePt("/MC_PHOTONJETUE/trans-maxnchg-jet","0")
 useOnePt("/MC_PHOTONJETUE/trans-maxptsum-gamma","0")
 useOnePt("/MC_PHOTONJETUE/trans-maxptsum-jet","0")
 useOnePt("/MC_PHOTONJETUE/trans-minnchg-gamma","0")
 useOnePt("/MC_PHOTONJETUE/trans-minnchg-jet","0")
 useOnePt("/MC_PHOTONJETUE/trans-minptsum-gamma","0")
 useOnePt("/MC_PHOTONJETUE/trans-minptsum-jet","0")
 useOnePt("/MC_PHOTONJETUE/trans-nchg-gamma","0")
 useOnePt("/MC_PHOTONJETUE/trans-nchg-jet","0")
 useOnePt("/MC_PHOTONJETUE/trans-ptavg-gamma","0")
 useOnePt("/MC_PHOTONJETUE/trans-ptavg-jet","0")
 useOnePt("/MC_PHOTONJETUE/trans-ptsum-gamma","0")
 useOnePt("/MC_PHOTONJETUE/trans-ptsum-jet","0")
 
 # Choose output file
 yoda.writeYODA(outhistos,opts.OUTFILE)
 sys.exit(0)
diff --git a/Tests/python/merge-TVT-Photon b/Tests/python/merge-TVT-Photon
new file mode 100644
--- /dev/null
+++ b/Tests/python/merge-TVT-Photon
@@ -0,0 +1,65 @@
+#! /usr/bin/env python
+import logging
+import sys
+import os, yoda
+
+"""%prog
+
+Script for merging aida files
+
+"""
+
+if sys.version_info[:3] < (2,4,0):
+    print "rivet scripts require Python version >= 2.4.0... exiting"
+    sys.exit(1)
+
+if __name__ == "__main__":
+    import logging
+    from optparse import OptionParser, OptionGroup
+    parser = OptionParser(usage="%prog aidafile aidafile2 [...]")
+    parser.add_option("-o", "--out", dest="OUTFILE", default="-")
+    verbgroup = OptionGroup(parser, "Verbosity control")
+    verbgroup.add_option("-v", "--verbose", action="store_const", const=logging.DEBUG, dest="LOGLEVEL",
+                         default=logging.INFO, help="print debug (very verbose) messages")
+    verbgroup.add_option("-q", "--quiet", action="store_const", const=logging.WARNING, dest="LOGLEVEL",
+                         default=logging.INFO, help="be very quiet")
+    parser.add_option_group(verbgroup)
+    (opts, args) = parser.parse_args()
+    logging.basicConfig(level=opts.LOGLEVEL, format="%(message)s")
+
+    ## Check args
+    if len(args) < 1:
+        logging.error("Must specify at least the name of the files")
+        sys.exit(1)
+
+files=["-Run-II-PromptPhoton.yoda",
+       "-Run-II-DiPhoton-GammaGamma.yoda","-Run-II-DiPhoton-GammaJet.yoda"]
+
+## Get histos
+inhistos = {}
+outhistos={}
+for f in files:
+    file=args[0]+f
+    if not os.access(file, os.R_OK):
+        logging.error("%s can not be read" % file)
+        continue
+    try:
+        aos = yoda.read(file)
+    except:
+        logging.error("%s can not be parsed as XML" % file)
+        break
+    ## Get histos from this YODA file
+    for aopath, ao in aos.iteritems() :
+        if(aopath.find("XSEC")>=0 or aopath.find("EVTCOUNT")>=0) : continue
+        if ( aopath in outhistos ) :
+            aotype = type(ao)
+            if aotype in (yoda.Counter, yoda.Histo1D, yoda.Histo2D, yoda.Profile1D, yoda.Profile2D):
+                outhistos[aopath] += ao
+            else :
+                quit()
+        else:
+            outhistos[aopath] = ao
+
+# Choose output file
+yoda.writeYODA(outhistos,opts.OUTFILE)
+sys.exit(0)
diff --git a/src/defaults/MatrixElements.in b/src/defaults/MatrixElements.in
--- a/src/defaults/MatrixElements.in
+++ b/src/defaults/MatrixElements.in
@@ -1,254 +1,261 @@
 # -*- ThePEG-repository -*-
 
 ##############################################################################
 # Setup of default matrix elements.
 #
 # Only one ME is activated by default, but this file lists 
 # some alternatives. All available MEs can be found in the
 # 'include/Herwig/MatrixElements' subdirectory of your Herwig 
 # installation.
 #
 # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # 
 #
 # Instead of editing this file directly, you should reset 
 # the matrix elements in your own input files:
 #
 # - create your custom SubProcessHandler
 # - insert the MEs you need
 # - set your SubProcessHandler instead of the default (see HerwigDefaults.in)
 ##############################################################################
 mkdir /Herwig/MatrixElements
 cd /Herwig/MatrixElements
 library HwMELepton.so
 library HwMEHadron.so
 library HwMEDIS.so
 
 ############################################################
 #  e+e- matrix elements
 ############################################################
 # e+e- > q qbar
 create Herwig::MEee2gZ2qq MEee2gZ2qq
 newdef MEee2gZ2qq:MinimumFlavour 1
 newdef MEee2gZ2qq:MaximumFlavour 5
 newdef MEee2gZ2qq:AlphaQCD /Herwig/Shower/AlphaQCD
 newdef MEee2gZ2qq:AlphaQED /Herwig/Shower/AlphaQED
 
 # e+e- -> l+l-
 create Herwig::MEee2gZ2ll MEee2gZ2ll
 newdef MEee2gZ2ll:Allowed Charged
 set MEee2gZ2ll:AlphaQED /Herwig/Shower/AlphaQED
 
 # e+e- -> W+W- ZZ
 create Herwig::MEee2VV MEee2VV
 
 # e+e- -> ZH
 create Herwig::MEee2ZH MEee2ZH
 newdef MEee2ZH:Coupling /Herwig/Shower/AlphaQCD
 
 # e+e- -> e+e-H/nu_enu_ebarH
 create Herwig::MEee2HiggsVBF MEee2HiggsVBF
 
 ############################################################
 # NLO (POWHEG e+e- matrix elements
 ############################################################
 library HwPowhegMELepton.so 
 create Herwig::MEee2gZ2qqPowheg PowhegMEee2gZ2qq
 newdef PowhegMEee2gZ2qq:MinimumFlavour 1
 newdef PowhegMEee2gZ2qq:MaximumFlavour 5
 newdef PowhegMEee2gZ2qq:AlphaQCD /Herwig/Shower/AlphaQCD
 newdef PowhegMEee2gZ2qq:AlphaQED /Herwig/Shower/AlphaQED
 create Herwig::MEee2gZ2llPowheg PowhegMEee2gZ2ll
 newdef PowhegMEee2gZ2ll:Allowed Charged
 set PowhegMEee2gZ2ll:AlphaQED /Herwig/Shower/AlphaQED
 
 ############################################################
 #  hadron-hadron matrix elements
 ############################################################
 
 ###################################
 #  Electroweak processes
 ###################################
 # q qbar -> gamma/Z -> l+l-
 create Herwig::MEqq2gZ2ff MEqq2gZ2ff
 newdef MEqq2gZ2ff:Process 3
 newdef MEqq2gZ2ff:Coupling /Herwig/Shower/AlphaQCD
 
 # q qbar to W -> l nu
 create Herwig::MEqq2W2ff  MEqq2W2ff
 newdef MEqq2W2ff:Process 2
 newdef MEqq2W2ff:Coupling /Herwig/Shower/AlphaQCD
 
 # W+jet
 create Herwig::MEPP2WJet MEWJet
 newdef MEWJet:WDecay Leptons
 
 # Z+jet
 create Herwig::MEPP2ZJet MEZJet
 newdef MEZJet:ZDecay ChargedLeptons
 
 # PP->WW/WZ/ZZ
 create Herwig::MEPP2VV MEPP2VV
 
 # PP->WZ gamma
 create Herwig::MEPP2VGamma MEPP2VGamma
 
 ###################################
 #  Photon and jet processes
 ###################################
 
 # qqbar/gg -> gamma gamma
 create Herwig::MEPP2GammaGamma MEGammaGamma
 
 # hadron-hadron to gamma+jet
 create Herwig::MEPP2GammaJet   MEGammaJet
 
 # QCD 2-to-2
 create Herwig::MEQCD2to2       MEQCD2to2
 
 # MinBias
 create Herwig::MEMinBias MEMinBias
 
 ###################################
 #  Heavy Quark
 ###################################
 
 # qqbar/gg -> t tbar
 create Herwig::MEPP2QQ         MEHeavyQuark     
 
 create Herwig::MEPP2SingleTop MESingleTopTChannel
 set MESingleTopTChannel:Process tChannel
 
 create Herwig::MEPP2SingleTop MESingleTopSChannel
 set MESingleTopSChannel:Process sChannel
 
 create Herwig::MEPP2SingleTop MESingleTopTW
 set MESingleTopTW:Process tW
 
 ###################################
 #  Higgs processes
 ###################################
 
 # hadron-hadron to higgs
 create Herwig::MEPP2Higgs   MEHiggs
 newdef MEHiggs:ShapeScheme MassGenerator
 newdef MEHiggs:Process gg
 newdef MEHiggs:Coupling /Herwig/Shower/AlphaQCD
 
 # hadron-hadron to higgs+jet
 create Herwig::MEPP2HiggsJet   MEHiggsJet
 
 # PP->ZH
 create Herwig::MEPP2ZH MEPP2ZH
 newdef MEPP2ZH:Coupling /Herwig/Shower/AlphaQCD
 
 # PP->WH
 create Herwig::MEPP2WH MEPP2WH
 newdef MEPP2WH:Coupling /Herwig/Shower/AlphaQCD
 
 # PP -> Higgs via VBF
 create Herwig::MEPP2HiggsVBF MEPP2HiggsVBF
 newdef MEPP2HiggsVBF:ShowerAlphaQCD /Herwig/Shower/AlphaQCD
 
 # PP -> t tbar Higgs
 create Herwig::MEPP2QQHiggs MEPP2ttbarH
 newdef MEPP2ttbarH:QuarkType Top
 
 # PP -> b bbar Higgs
 create Herwig::MEPP2QQHiggs MEPP2bbbarH
 newdef MEPP2bbbarH:QuarkType Bottom
 
 ##########################################################
 # Hadron-Hadron NLO matrix elements in the Powheg scheme
 ##########################################################
 library HwPowhegMEHadron.so
 
 # q qbar -> gamma/Z -> l+l-
 create Herwig::MEqq2gZ2ffPowheg PowhegMEqq2gZ2ff
 newdef PowhegMEqq2gZ2ff:Process 3
 newdef PowhegMEqq2gZ2ff:Coupling /Herwig/Shower/AlphaQCD
 
 # q qbar to W -> l nu
 create Herwig::MEqq2W2ffPowheg PowhegMEqq2W2ff
 newdef PowhegMEqq2W2ff:Process 2
 newdef PowhegMEqq2W2ff:Coupling /Herwig/Shower/AlphaQCD
  
 # PP->ZH
 create Herwig::MEPP2ZHPowheg PowhegMEPP2ZH
 newdef PowhegMEPP2ZH:Coupling /Herwig/Shower/AlphaQCD
 
 # PP->WH
 create Herwig::MEPP2WHPowheg PowhegMEPP2WH
 newdef PowhegMEPP2WH:Coupling /Herwig/Shower/AlphaQCD
 
 # hadron-hadron to higgs
 create Herwig::MEPP2HiggsPowheg PowhegMEHiggs
 newdef PowhegMEHiggs:ShapeScheme MassGenerator
 newdef PowhegMEHiggs:Process gg
 newdef PowhegMEHiggs:Coupling /Herwig/Shower/AlphaQCD
 
 # PP->VV
 create Herwig::MEPP2VVPowheg PowhegMEPP2VV
 newdef PowhegMEPP2VV:Coupling /Herwig/Shower/AlphaQCD
 
 # PP -> Higgs via VBF
 create Herwig::MEPP2HiggsVBFPowheg PowhegMEPP2HiggsVBF
 newdef PowhegMEPP2HiggsVBF:ShowerAlphaQCD /Herwig/Shower/AlphaQCD
 
+# PP -> diphoton NLO
+create Herwig::MEPP2GammaGammaPowheg MEGammaGammaPowheg 
+set MEGammaGammaPowheg:Process 0
+set MEGammaGammaPowheg:Contribution 1
+set MEGammaGammaPowheg:ShowerAlphaQCD /Herwig/Shower/AlphaQCD
+set MEGammaGammaPowheg:ShowerAlphaQED /Herwig/Shower/AlphaQED
+
 ##########################################################
 # DIS matrix elements
 ##########################################################
 
 # neutral current
 create Herwig::MENeutralCurrentDIS MEDISNC
 newdef MEDISNC:Coupling /Herwig/Shower/AlphaQCD
 newdef MEDISNC:Contribution 0
 # charged current
 create Herwig::MEChargedCurrentDIS MEDISCC
 newdef MEDISCC:Coupling /Herwig/Shower/AlphaQCD
 newdef MEDISCC:Contribution 0
 
 # neutral current (POWHEG)
 create Herwig::MENeutralCurrentDIS PowhegMEDISNC
 newdef PowhegMEDISNC:Coupling /Herwig/Shower/AlphaQCD
 newdef PowhegMEDISNC:Contribution 1
 # charged current (POWHEG)
 create Herwig::MEChargedCurrentDIS PowhegMEDISCC
 newdef PowhegMEDISCC:Coupling /Herwig/Shower/AlphaQCD
 newdef PowhegMEDISCC:Contribution 1
 
 ##########################################################
 # Gamma-Gamma matrix elements
 ##########################################################
 
 # fermion-antiferimon
 create Herwig::MEGammaGamma2ff MEgg2ff HwMEGammaGamma.so
 
 # W+ W-
 create Herwig::MEGammaGamma2WW MEgg2WW HwMEGammaGamma.so
 
 ##########################################################
 # Gamma-Hadron matrix elements
 ##########################################################
 
 # gamma parton -> 2 jets
 create Herwig::MEGammaP2Jets MEGammaP2Jets HwMEGammaHadron.so
 
 ##########################################################
 # Set up the Subprocesses
 #
 # For e+e-
 ##########################################################
 create ThePEG::SubProcessHandler SimpleEE
 newdef SimpleEE:PartonExtractor /Herwig/Partons/EEExtractor
 
 ##########################################################
 # For hadron-hadron 
 ##########################################################
 create ThePEG::SubProcessHandler SimpleQCD
 newdef SimpleQCD:PartonExtractor /Herwig/Partons/QCDExtractor
 
 ##########################################################
 # For DIS 
 ##########################################################
 create ThePEG::SubProcessHandler SimpleDIS
 newdef SimpleDIS:PartonExtractor /Herwig/Partons/DISExtractor