diff --git a/Decay/Perturbative/SMTopDecayer.cc b/Decay/Perturbative/SMTopDecayer.cc
--- a/Decay/Perturbative/SMTopDecayer.cc
+++ b/Decay/Perturbative/SMTopDecayer.cc
@@ -1,1335 +1,1296 @@
 // -*- C++ -*-
 //
 // SMTopDecayer.cc is a part of Herwig - A multi-purpose Monte Carlo event generator
 // Copyright (C) 2002-2017 The Herwig Collaboration
 //
 // Herwig is licenced under version 3 of the GPL, see COPYING for details.
 // Please respect the MCnet academic guidelines, see GUIDELINES for details.
 //
 //
 // This is the implementation of the non-inlined, non-templated member
 // functions of the SMTopDecayer class.
 //
 
 #include "SMTopDecayer.h"
 #include "ThePEG/Utilities/DescribeClass.h"
 #include "ThePEG/Interface/ClassDocumentation.h"
 #include "ThePEG/Interface/ParVector.h"
 #include "ThePEG/Interface/Switch.h"
 #include "ThePEG/Interface/Reference.h"
 #include "ThePEG/Persistency/PersistentOStream.h"
 #include "ThePEG/Persistency/PersistentIStream.h"
 #include "ThePEG/PDT/DecayMode.h"
 #include "Herwig/Decay/DecayVertex.h"
 #include "ThePEG/Helicity/WaveFunction/VectorWaveFunction.h"
 #include "Herwig/PDT/ThreeBodyAllOn1IntegralCalculator.h"
 #include "Herwig/Shower/RealEmissionProcess.h"
 #include "Herwig/Shower/Core/Base/ShowerProgenitor.h"
 #include "Herwig/Shower/Core/Base/ShowerParticle.h"
 #include "Herwig/Shower/Core/Base/Branching.h"
 #include "Herwig/Decay/GeneralDecayMatrixElement.h"
 
 using namespace Herwig;
 using namespace ThePEG::Helicity;
 
 SMTopDecayer::SMTopDecayer() 
   : _wquarkwgt(6,0.),_wleptonwgt(3,0.), _xg_sampling(1.5), 
     _initialenhance(1.),  _finalenhance(2.3), _useMEforT2(true) {
   _wleptonwgt[0] = 0.302583;
   _wleptonwgt[1] = 0.301024;
   _wleptonwgt[2] = 0.299548;
   _wquarkwgt[0]  = 0.851719;
   _wquarkwgt[1]  = 0.0450162;
   _wquarkwgt[2]  = 0.0456962;
   _wquarkwgt[3]  = 0.859839;
   _wquarkwgt[4]  = 3.9704e-06;
   _wquarkwgt[5]  = 0.000489657; 
   generateIntermediates(true);
 }
   
 bool SMTopDecayer::accept(tcPDPtr parent, const tPDVector & children) const {
   if(abs(parent->id()) != ParticleID::t) return false;
   int id0(0),id1(0),id2(0);
   for(tPDVector::const_iterator it = children.begin();
       it != children.end();++it) {
     int id=(**it).id(),absid(abs(id));
     if(absid==ParticleID::b&&double(id)/double(parent->id())>0) {
       id0=id;
     }
     else {
       switch (absid) {
       case ParticleID::nu_e: 
       case ParticleID::nu_mu:
       case ParticleID::nu_tau:
 	id1 = id;
 	break;
       case ParticleID::eminus:
       case ParticleID::muminus:
       case ParticleID::tauminus:
 	id2 = id;
 	break;
       case ParticleID::b:
       case ParticleID::d:
       case ParticleID::s:
 	id1 = id;
 	break;
       case ParticleID::u:
       case ParticleID::c:
 	id2=id;
 	break;
       default :
 	break;
       }
     }
   }
   if(id0==0||id1==0||id2==0) return false;
   if(double(id1)/double(id2)>0) return false;
   return true;
 }
   
 ParticleVector SMTopDecayer::decay(const Particle & parent,
 				   const tPDVector & children) const {
   int id1(0),id2(0);
   for(tPDVector::const_iterator it = children.begin();
       it != children.end();++it) {
     int id=(**it).id(),absid=abs(id);
     if(absid == ParticleID::b && double(id)/double(parent.id())>0) continue;
     //leptons
     if(absid > 10 && absid%2==0) id1=absid;
     if(absid > 10 && absid%2==1) id2=absid;
     //quarks
     if(absid < 10 && absid%2==0) id2=absid;
     if(absid < 10 && absid%2==1) id1=absid;
   }
   unsigned int imode(0);
   if(id2 >=11 && id2<=16) imode = (id1-12)/2;
   else imode = id1+1+id2/2;
   bool cc = parent.id() == ParticleID::tbar;
   ParticleVector out(generate(true,cc,imode,parent));
   //arrange colour flow
   PPtr pparent=const_ptr_cast<PPtr>(&parent);
   out[1]->incomingColour(pparent,out[1]->id()<0);
   ParticleVector products = out[0]->children();
   if(products[0]->hasColour())
     products[0]->colourNeighbour(products[1],true);
   else if(products[0]->hasAntiColour())
     products[0]->colourNeighbour(products[1],false);
   return out;
 }   
  
 void SMTopDecayer::persistentOutput(PersistentOStream & os) const {
   os << FFWVertex_ << FFGVertex_ << FFPVertex_ << WWWVertex_
      << _wquarkwgt << _wleptonwgt << _wplus
      << _initialenhance << _finalenhance << _xg_sampling << _useMEforT2;
 }
   
 void SMTopDecayer::persistentInput(PersistentIStream & is, int) {
   is >> FFWVertex_ >> FFGVertex_ >> FFPVertex_ >> WWWVertex_
      >> _wquarkwgt >> _wleptonwgt >> _wplus
      >> _initialenhance >> _finalenhance >> _xg_sampling >> _useMEforT2;
 }
   
 // The following static variable is needed for the type
 // description system in ThePEG.
 DescribeClass<SMTopDecayer,PerturbativeDecayer>
 describeHerwigSMTopDecayer("Herwig::SMTopDecayer", "HwPerturbativeDecay.so");
   
 void SMTopDecayer::Init() {
     
   static ClassDocumentation<SMTopDecayer> documentation
     ("This is the implementation of the SMTopDecayer which "
      "decays top quarks into bottom quarks and either leptons  "
      "or quark-antiquark pairs including the matrix element for top decay",
      "The matrix element correction for top decay \\cite{Hamilton:2006ms}.",
      "%\\cite{Hamilton:2006ms}\n"
      "\\bibitem{Hamilton:2006ms}\n"
      "  K.~Hamilton and P.~Richardson,\n"
      "  ``A simulation of QCD radiation in top quark decays,''\n"
      "  JHEP {\\bf 0702}, 069 (2007)\n"
      "  [arXiv:hep-ph/0612236].\n"
      "  %%CITATION = JHEPA,0702,069;%%\n");
   
   static ParVector<SMTopDecayer,double> interfaceQuarkWeights
     ("QuarkWeights",
      "Maximum weights for the hadronic decays",
      &SMTopDecayer::_wquarkwgt, 6, 1.0, 0.0, 10.0,
      false, false, Interface::limited);
   
   static ParVector<SMTopDecayer,double> interfaceLeptonWeights
     ("LeptonWeights",
      "Maximum weights for the semi-leptonic decays",
      &SMTopDecayer::_wleptonwgt, 3, 1.0, 0.0, 10.0,
      false, false, Interface::limited);
 
   static Parameter<SMTopDecayer,double> interfaceEnhancementFactor
     ("InitialEnhancementFactor",
      "The enhancement factor for initial-state radiation in the shower to ensure"
      " the weight for the matrix element correction is less than one.",
      &SMTopDecayer::_initialenhance, 1.0, 1.0, 10000.0,
      false, false, Interface::limited);
 
   static Parameter<SMTopDecayer,double> interfaceFinalEnhancementFactor
     ("FinalEnhancementFactor",
      "The enhancement factor for final-state radiation in the shower to ensure"
      " the weight for the matrix element correction is less than one",
      &SMTopDecayer::_finalenhance, 1.6, 1.0, 1000.0,
      false, false, Interface::limited);
 
   static Parameter<SMTopDecayer,double> interfaceSamplingTopHardMEC
     ("SamplingTopHardMEC",
      "The importance sampling power for choosing an initial xg, "
      "to sample xg according to xg^-_xg_sampling",
      &SMTopDecayer::_xg_sampling, 1.5, 1.2, 2.0,
      false, false, Interface::limited);
 
   static Switch<SMTopDecayer,bool> interfaceUseMEForT2
     ("UseMEForT2",
      "Use the matrix element correction, if available to fill the T2"
      " region for the decay shower and don't fill using the shower",
      &SMTopDecayer::_useMEforT2, true, false, false);
   static SwitchOption interfaceUseMEForT2Shower
     (interfaceUseMEForT2,
      "Shower",
      "Use the shower to fill the T2 region",
      false);
   static SwitchOption interfaceUseMEForT2ME
     (interfaceUseMEForT2,
      "ME",
      "Use the Matrix element to fill the T2 region",
      true);
 }
 
 double SMTopDecayer::me2(const int, const Particle & inpart,
 			 const ParticleVector & decay,
 			 MEOption meopt) const {
   if(!ME())
     ME(new_ptr(GeneralDecayMatrixElement(PDT::Spin1Half,PDT::Spin1Half,
 					 PDT::Spin1Half,PDT::Spin1Half)));
   // spinors etc for the decaying particle
   if(meopt==Initialize) {
     // spinors and rho
     if(inpart.id()>0)
       SpinorWaveFunction   ::calculateWaveFunctions(_inHalf,_rho,
 						    const_ptr_cast<tPPtr>(&inpart),
 						    incoming);
     else
       SpinorBarWaveFunction::calculateWaveFunctions(_inHalfBar,_rho,
 						    const_ptr_cast<tPPtr>(&inpart),
 						    incoming);
   }
   // setup spin info when needed
   if(meopt==Terminate) {
     // for the decaying particle
     if(inpart.id()>0) {
       SpinorWaveFunction::
 	constructSpinInfo(_inHalf,const_ptr_cast<tPPtr>(&inpart),incoming,true);
       SpinorBarWaveFunction::constructSpinInfo(_inHalfBar,decay[0],outgoing,true);
       SpinorWaveFunction   ::constructSpinInfo(_outHalf   ,decay[1],outgoing,true);
       SpinorBarWaveFunction::constructSpinInfo(_outHalfBar,decay[2],outgoing,true);
     }
     else {
       SpinorBarWaveFunction::
 	constructSpinInfo(_inHalfBar,const_ptr_cast<tPPtr>(&inpart),incoming,true);
       SpinorWaveFunction::constructSpinInfo(_inHalf,decay[0],outgoing,true);
       SpinorBarWaveFunction::constructSpinInfo(_outHalfBar,decay[1],outgoing,true);
       SpinorWaveFunction   ::constructSpinInfo(_outHalf   ,decay[2],outgoing,true);
     }
   }
 
   if ( ( decay[1]->momentum() + decay[2]->momentum() ).m()
        < decay[1]->data().constituentMass() + decay[2]->data().constituentMass() )
     return 0.0;
 
   // spinors for the decay product
   if(inpart.id()>0) {
     SpinorBarWaveFunction::calculateWaveFunctions(_inHalfBar ,decay[0],outgoing);
     SpinorWaveFunction   ::calculateWaveFunctions(_outHalf   ,decay[1],outgoing);
     SpinorBarWaveFunction::calculateWaveFunctions(_outHalfBar,decay[2],outgoing);
   }
   else {
     SpinorWaveFunction   ::calculateWaveFunctions(_inHalf    ,decay[0],outgoing);
     SpinorBarWaveFunction::calculateWaveFunctions(_outHalfBar,decay[1],outgoing);
     SpinorWaveFunction   ::calculateWaveFunctions(_outHalf   ,decay[2],outgoing);
   }
   Energy2 scale(sqr(inpart.mass()));
   if(inpart.id() == ParticleID::t) {
     //Define intermediate vector wave-function for Wplus 
     tcPDPtr Wplus(getParticleData(ParticleID::Wplus));
     VectorWaveFunction inter;
     unsigned int thel,bhel,fhel,afhel;
     for(thel = 0;thel<2;++thel){
       for(bhel = 0;bhel<2;++bhel){	  
 	inter = FFWVertex_->evaluate(scale,1,Wplus,_inHalf[thel],
 				   _inHalfBar[bhel]);
 	for(afhel=0;afhel<2;++afhel){
 	  for(fhel=0;fhel<2;++fhel){
 	    (*ME())(thel,bhel,afhel,fhel) = 
 	      FFWVertex_->evaluate(scale,_outHalf[afhel],
 				 _outHalfBar[fhel],inter);
 	  }
 	}
       }
     }
   }
   else if(inpart.id() == ParticleID::tbar) {
     VectorWaveFunction inter;
     tcPDPtr Wminus(getParticleData(ParticleID::Wminus));
     unsigned int tbhel,bbhel,afhel,fhel;
     for(tbhel = 0;tbhel<2;++tbhel){
       for(bbhel = 0;bbhel<2;++bbhel){
 	inter = FFWVertex_->
 	  evaluate(scale,1,Wminus,_inHalf[bbhel],_inHalfBar[tbhel]);
 	for(afhel=0;afhel<2;++afhel){
 	  for(fhel=0;fhel<2;++fhel){
 	    (*ME())(tbhel,bbhel,fhel,afhel) = 
 	      FFWVertex_->evaluate(scale,_outHalf[afhel],
 				 _outHalfBar[fhel],inter);
 	  }
 	}
       }
     }
   }
   double output = (ME()->contract(_rho)).real();
   if(abs(decay[1]->id())<=6) output *=3.;
   return output;
 }
 
 void SMTopDecayer::doinit() {
   PerturbativeDecayer::doinit();
   //get vertices from SM object
   tcHwSMPtr hwsm = dynamic_ptr_cast<tcHwSMPtr>(standardModel());
   if(!hwsm) throw InitException() << "Must have Herwig::StandardModel in "
 				  << "SMTopDecayer::doinit()";
   FFWVertex_ = hwsm->vertexFFW();
   FFGVertex_ = hwsm->vertexFFG();
   FFPVertex_ = hwsm->vertexFFP();
   WWWVertex_ = hwsm->vertexWWW();
   //initialise
   FFWVertex_->init();
   FFGVertex_->init();
   FFPVertex_->init();
   WWWVertex_->init();
   //set up decay modes
   _wplus = getParticleData(ParticleID::Wplus);
   DecayPhaseSpaceModePtr mode;
   DecayPhaseSpaceChannelPtr Wchannel;
   tPDVector extpart(4);
   vector<double> wgt(1,1.0);
   extpart[0] = getParticleData(ParticleID::t);
   extpart[1] = getParticleData(ParticleID::b);
   //lepton modes
   for(int i=11; i<17;i+=2) {
     extpart[2] = getParticleData(-i);
     extpart[3] = getParticleData(i+1);
     mode = new_ptr(DecayPhaseSpaceMode(extpart,this));
     Wchannel = new_ptr(DecayPhaseSpaceChannel(mode));
     Wchannel->addIntermediate(extpart[0],0,0.0,-1,1);
     Wchannel->addIntermediate(_wplus,0,0.0,2,3);
     Wchannel->init();
     mode->addChannel(Wchannel);
     addMode(mode,_wleptonwgt[(i-11)/2],wgt);
   }
   //quark modes
   unsigned int iz=0;
   for(int ix=1;ix<6;ix+=2) {
     for(int iy=2;iy<6;iy+=2) {
       // check that the combination of particles is allowed
       if(FFWVertex_->allowed(-ix,iy,ParticleID::Wminus)) {
 	extpart[2] = getParticleData(-ix);
 	extpart[3] = getParticleData( iy);
 	mode = new_ptr(DecayPhaseSpaceMode(extpart,this));
 	Wchannel = new_ptr(DecayPhaseSpaceChannel(mode));
 	Wchannel->addIntermediate(extpart[0],0,0.0,-1,1);
 	Wchannel->addIntermediate(_wplus,0,0.0,2,3);
 	Wchannel->init();
 	mode->addChannel(Wchannel);
 	addMode(mode,_wquarkwgt[iz],wgt);
 	++iz;
       }
       else {
 	throw InitException() << "SMTopDecayer::doinit() the W vertex" 
 			      << "cannot handle all the quark modes" 
 			      << Exception::abortnow;
       }
     }
   }
 }
 
 void SMTopDecayer::dataBaseOutput(ofstream & os,bool header) const {
   if(header) os << "update decayers set parameters=\"";
   // parameters for the PerturbativeDecayer base class
   for(unsigned int ix=0;ix<_wquarkwgt.size();++ix) {
     os << "newdef " << name() << ":QuarkWeights " << ix << " "
 	   << _wquarkwgt[ix] << "\n";
   }
   for(unsigned int ix=0;ix<_wleptonwgt.size();++ix) {
     os << "newdef " << name() << ":LeptonWeights " << ix << " "
 	   << _wleptonwgt[ix] << "\n";
   }
   PerturbativeDecayer::dataBaseOutput(os,false);
   if(header) os << "\n\" where BINARY ThePEGName=\"" << fullName() << "\";" << endl;
 }
 
 void SMTopDecayer::doinitrun() {
   PerturbativeDecayer::doinitrun();
   if(initialize()) {
     for(unsigned int ix=0;ix<numberModes();++ix) {
       if(ix<3) _wleptonwgt[ix  ] = mode(ix)->maxWeight();
       else     _wquarkwgt [ix-3] = mode(ix)->maxWeight();
     }
   }
 }
 
 WidthCalculatorBasePtr SMTopDecayer::threeBodyMEIntegrator(const DecayMode & dm) const {
   // identify W decay products
   int sign = dm.parent()->id() > 0 ? 1 : -1;
   int iferm(0),ianti(0);
   for(ParticleMSet::const_iterator pit=dm.products().begin();
       pit!=dm.products().end();++pit) {
     int id = (**pit).id();
     if(id*sign != ParticleID::b) {
       if   (id*sign > 0 ) iferm = id*sign;
       else                ianti = id*sign;
     }
   }
   assert(iferm!=0&&ianti!=0);
   // work out which mode we are doing
   int imode(-1);
   for(unsigned int ix=0;ix<numberModes();++ix) {
     if(mode(ix)->externalParticles(2)->id() == ianti &&
        mode(ix)->externalParticles(3)->id() == iferm ) {
       imode = ix;
       break;
     }
   }
   assert(imode>=0);
   // get the masses we need
   Energy m[3] = {mode(imode)->externalParticles(1)->mass(),
 		 mode(imode)->externalParticles(3)->mass(),
 		 mode(imode)->externalParticles(2)->mass()};
   return 
     new_ptr(ThreeBodyAllOn1IntegralCalculator<SMTopDecayer>
 	    (3,_wplus->mass(),_wplus->width(),0.0,*this,imode,m[0],m[1],m[2]));
 }
 
 InvEnergy SMTopDecayer::threeBodydGammads(const int imode, const Energy2 mt2,
 					  const Energy2 mffb2, const Energy mb,
 					  const Energy mf, const Energy mfb) const {
   Energy mffb(sqrt(mffb2));
   Energy mw(_wplus->mass());
   Energy2 mw2(sqr(mw)),gw2(sqr(_wplus->width()));
   Energy mt(sqrt(mt2));
   Energy Eb  = 0.5*(mt2-mffb2-sqr(mb))/mffb;
   Energy Ef  = 0.5*(mffb2-sqr(mfb)+sqr(mf))/mffb;
   Energy Ebm = sqrt(sqr(Eb)-sqr(mb));
   Energy Efm = sqrt(sqr(Ef)-sqr(mf));
   Energy2 upp = sqr(Eb+Ef)-sqr(Ebm-Efm);
   Energy2 low = sqr(Eb+Ef)-sqr(Ebm+Efm);
   InvEnergy width=(dGammaIntegrand(mffb2,upp,mt,mb,mf,mfb,mw)-
 		   dGammaIntegrand(mffb2,low,mt,mb,mf,mfb,mw))
     /32./mt2/mt/8/pow(Constants::pi,3)/(sqr(mffb2-mw2)+mw2*gw2);
   // couplings
   width *= 0.25*sqr(4.*Constants::pi*generator()->standardModel()->alphaEM(mt2)/
 		    generator()->standardModel()->sin2ThetaW());
   width *= generator()->standardModel()->CKM(*mode(imode)->externalParticles(0),
 					     *mode(imode)->externalParticles(1));
   if(abs(mode(imode)->externalParticles(2)->id())<=6) {
     width *=3.;
     if(abs(mode(imode)->externalParticles(2)->id())%2==0)
       width *=generator()->standardModel()->CKM(*mode(imode)->externalParticles(2),
 						*mode(imode)->externalParticles(3));
     else
       width *=generator()->standardModel()->CKM(*mode(imode)->externalParticles(3),
 						*mode(imode)->externalParticles(2));
   }
   // final spin average
   assert(!std::isnan(double(width*MeV)));
   return 0.5*width;
 }
 
 Energy6 SMTopDecayer::dGammaIntegrand(Energy2 mffb2, Energy2 mbf2, Energy mt,
 				      Energy mb, Energy mf, Energy mfb, Energy mw) const {
   Energy2 mt2(sqr(mt)) ,mb2(sqr(mb)) ,mf2(sqr(mf )),mfb2(sqr(mfb )),mw2(sqr(mw ));
   Energy4 mt4(sqr(mt2)),mb4(sqr(mb2)),mf4(sqr(mf2)),mfb4(sqr(mfb2)),mw4(sqr(mw2));
   return -mbf2 * ( + 6 * mb2 * mf2 * mfb2 * mffb2    +   6 * mb2 * mt2 * mfb2 * mffb2 
 		   + 6 * mb2 * mt2 * mf2  * mffb2    +  12 * mb2 * mt2 * mf2 * mfb2 
 		   - 3  * mb2 * mfb4  * mffb2        +   3 * mb2 * mf2 * mffb2 * mffb2 
 		   - 3  * mb2 * mf4   * mffb2        -   6 * mb2 * mt2 * mfb4 
 		   - 6  * mb2 * mt2 * mf4            -   3 * mb4 * mfb2 * mffb2 
 		   - 3  * mb4 * mf2 * mffb2          -   6 * mb4 * mf2 * mfb2
 		   + 3  * mt4 * mf4                  +   3 * mb4 * mfb4 
 		   + 3  * mb4 * mf4                  +   3 * mt4 * mfb4
 		   + 3  * mb2 * mfb2 * mffb2 * mffb2 +   3 * mt2 * mfb2 * mffb2 * mffb2 
 		   - 3  * mt2 * mfb4 * mffb2         +   3 * mt2 * mf2 * mffb2 * mffb2 
 		   - 3  * mt2 * mf4 * mffb2          -   3 * mt4 * mfb2 * mffb2 
 		   - 3  * mt4 * mf2 * mffb2          -   6 * mt4 * mf2 * mfb2 
 		   + 6  * mt2 * mf2 * mfb2 * mffb2   +  12 * mt2 * mf2 * mw4 
 		   + 12 * mb2 * mfb2 * mw4           +  12 * mb2 * mt2 * mw4 
 		   + 6  * mw2 * mt2 * mfb2 * mbf2    -  12 * mw2 * mt2 * mf2 * mffb2 
 		   - 6  * mw2 * mt2 * mf2 * mbf2     -  12 * mw2 * mt2 * mf2 * mfb2 
 		   - 12 * mw2 * mb2  * mfb2 * mffb2  -   6 * mw2 * mb2 * mfb2 * mbf2 
 		   + 6  * mw2 * mb2  * mf2 * mbf2    -  12 * mw2 * mb2 * mf2 * mfb2 
 		   - 12 * mw2 * mb2 * mt2 * mfb2     -  12 * mw2 * mb2 * mt2 * mf2 
 		   + 12 * mf2 * mfb2 * mw4           +   4 * mbf2 * mbf2 * mw4 
 		   -  6 * mfb2 * mbf2 * mw4          -   6 * mf2 * mbf2 * mw4 
 		   -  6 * mt2 * mbf2 * mw4           -   6 * mb2 * mbf2 * mw4 
 		   + 12 * mw2 * mt2 * mf4            +  12 * mw2 * mt4 * mf2 
 		   + 12 * mw2 * mb2 * mfb4           +  12 * mw2 * mb4 * mfb2) /mw4 / 3.;
 }
 
 void SMTopDecayer::initializeMECorrection(RealEmissionProcessPtr born, double & initial,
 					  double & final) {
   // check the outgoing particles
   PPtr part[2];
   for(unsigned int ix=0;ix<born->bornOutgoing().size();++ix) {
     part[ix]= born->bornOutgoing()[ix];
   }
   // check the final-state particles and get the masses
   if(abs(part[0]->id())==ParticleID::Wplus&&abs(part[1]->id())==ParticleID::b) {
     _ma=part[0]->mass();
     _mc=part[1]->mass();
   }
   else if(abs(part[1]->id())==ParticleID::Wplus&&abs(part[0]->id())==ParticleID::b) {
     _ma=part[1]->mass();
     _mc=part[0]->mass();
   }
   else {
     return;
   }
   // set the top mass
   _mt=born->bornIncoming()[0]->mass();
   // set the gluon mass
   _mg=getParticleData(ParticleID::g)->constituentMass();
   // set the radiation enhancement factors
   initial = _initialenhance;
   final   = _finalenhance;
   // reduced mass parameters
   _a=sqr(_ma/_mt);
   _g=sqr(_mg/_mt);
   _c=sqr(_mc/_mt);
   double lambda = sqrt(1.+sqr(_a)+sqr(_c)-2.*_a-2.*_c-2.*_a*_c);
   _ktb = 0.5*(3.-_a+_c+lambda);
   _ktc = 0.5*(1.-_a+3.*_c+lambda);
   useMe();
 }
 
 RealEmissionProcessPtr SMTopDecayer::applyHardMatrixElementCorrection(RealEmissionProcessPtr born) {
   // Get b and a and put them in particle vector ba in that order...
   ParticleVector ba; 
   for(unsigned int ix=0;ix<born->bornOutgoing().size();++ix)
     ba.push_back(born->bornOutgoing()[ix]);
   if(abs(ba[0]->id())!=5) swap(ba[0],ba[1]);
   assert(born->bornIncoming().size()==1);
   // Now decide if we get an emission into the dead region.
   // If there is an emission newfs stores momenta for a,c,g 
   // according to NLO decay matrix element. 
   vector<Lorentz5Momentum> newfs = applyHard(ba,_ktb,_ktc);
   // If there was no gluon emitted return.
   if(newfs.size()!=3) return RealEmissionProcessPtr();
   // Sanity checks to ensure energy greater than mass etc :)
   bool check = true; 
   tcPDPtr gluondata=getParticleData(ParticleID::g);
   if (newfs[0].e()<ba[0]->data().constituentMass()) check = false;
   if (newfs[1].e()<ba[1]->mass())                   check = false;
   if (newfs[2].e()<gluondata->constituentMass())    check = false;
   // Return if insane:
   if (!check) return RealEmissionProcessPtr();
   // // Set masses in 5-vectors:
   newfs[0].setMass(ba[0]->mass());
   newfs[1].setMass(ba[1]->mass());
   newfs[2].setMass(ZERO);
   // The next part of this routine sets the colour structure.
   // To do this for decays we assume that the gluon comes from c!
   // First create new particle objects for c, a and gluon:
   PPtr newg = gluondata->produceParticle(newfs[2]);
   PPtr newc = ba[0]->data().produceParticle(newfs[0]);
   PPtr newa = ba[1]->data().produceParticle(newfs[1]);
   born->spectator(0);
   born->emitted(3);
   // decaying particle
   born->incoming().push_back(born->bornIncoming()[0]->dataPtr()->
 			     produceParticle(born->bornIncoming()[0]->momentum()));
   // colour flow
   newg->incomingColour(born->incoming()[0],ba[0]->id()<0);
   newg->colourConnect(newc                ,ba[0]->id()<0);
   if(born->bornOutgoing()[0]->id()==newc->id()) {
     born->outgoing().push_back(newc);
     born->outgoing().push_back(newa);
     born->emitter(1);
   }
   else {
     born->outgoing().push_back(newa);
     born->outgoing().push_back(newc);
     born->emitter(2);
   }
   born->outgoing().push_back(newg);
   // boost for the W
   LorentzRotation trans(ba[1]->momentum().findBoostToCM());
   trans.boost(newfs[1].boostVector());
   born->transformation(trans);
   if(!inTheDeadRegion(_xg,_xa,_ktb,_ktc)) {
     generator()->log()
       << "SMTopDecayer::applyHardMatrixElementCorrection()\n"
       << "Just found a point that escaped from the dead region!\n"
       << "   _xg: " << _xg << "   _xa: " << _xa 
       << "   newfs.size(): " << newfs.size() << endl;
   }
   born->interaction(ShowerInteraction::QCD);
   return born;
 }
 
 vector<Lorentz5Momentum> SMTopDecayer::
 applyHard(const ParticleVector &p,double ktb, double ktc) { 
   // ********************************* //
   // First we see if we get a dead     //
   // region event: _xa,_xg             //
   // ********************************* //
   vector<Lorentz5Momentum> fs; 
   // Return if there is no (NLO) gluon emission:
   
   double weight = getHard(ktb,ktc);
   if(weight>1.) {
     generator()->log() << "Weight greater than 1 for hard emission in "
 		       << "SMTopDecayer::applyHard xg = " << _xg 
 		       << " xa = " << _xa << "\n";
       weight=1.;
   }
   // Accept/Reject
   if (weight<UseRandom::rnd()||p.size()!= 2) return fs; 
    // Drop events if getHard returned a negative weight 
   // as in events that, somehow have escaped from the dead region
   // or, worse, the allowed region.
   if(weight<0.) return fs;
  
   // Calculate xc by momentum conservation:
   _xc = 2.-_xa-_xg;
 
   // ************************************ //
   // Now we get the boosts & rotations to //
   // go from lab to top rest frame with   //
   // a in the +z direction.               //
   // ************************************ //
   Lorentz5Momentum pa_lab,pb_lab,pc_lab,pg_lab;
   // Calculate momentum of b:
   pb_lab = p[0]->momentum() + p[1]->momentum(); 
    // Define/assign momenta of c,a and the gluon:
   if(abs(p[0]->id())==5) {
     pc_lab = p[0]->momentum(); 
     pa_lab = p[1]->momentum(); 
   } else {
     pc_lab = p[1]->momentum(); 
     pa_lab = p[0]->momentum(); 
   }
   // Calculate the boost to the b rest frame:
   SpinOneLorentzRotation rot0(pb_lab.findBoostToCM());
   // Calculate the rotation matrix to position a along the +z direction
   // in the rest frame of b and does a random rotation about z:
   SpinOneLorentzRotation    rot1 = rotateToZ(rot0*pa_lab);
   // Calculate the boost from the b rest frame back to the lab:
   // and the inverse of the random rotation about the z-axis and the 
   // rotation required to align a with +z:
   SpinOneLorentzRotation invrot = rot0.inverse()*rot1.inverse();
 
   // ************************************ //
   // Now we construct the momenta in the  //
   // b rest frame using _xa,_xg.          //
   // First we construct b, then c and g,  //
   // finally we generate a by momentum    //
   // conservation.                        //
   // ************************************ //
   Lorentz5Momentum pa_brf, pb_brf(_mt), pc_brf, pg_brf;
   // First we set the top quark to being on-shell and at rest.
   // Second we set the energies of c and g,
   pc_brf.setE(0.5*_mt*(2.-_xa-_xg));
   pg_brf.setE(0.5*_mt*_xg);
   // then their masses,
   pc_brf.setMass(_mc);
   pg_brf.setMass(ZERO);
   // Now set the z-component of c and g. For pg we simply start from
   // _xa and _xg, while for pc we assume it is equal to minus the sum
   // of the z-components of a (assumed to point in the +z direction) and g.
   double root=sqrt(_xa*_xa-4.*_a);
   pg_brf.setZ(_mt*(1.-_xa-_xg+0.5*_xa*_xg-_c+_a)/root);
   pc_brf.setZ(-1.*( pg_brf.z()+_mt*0.5*root));
   // Now set the y-component of c and g's momenta
   pc_brf.setY(ZERO);
   pg_brf.setY(ZERO);
   // Now set the x-component of c and g's momenta
   pg_brf.setX(sqrt(sqr(pg_brf.t())-sqr(pg_brf.z())));
   pc_brf.setX(-pg_brf.x());
   // Momenta b,c,g are now set. Now we obtain a from momentum conservation,
   pa_brf = pb_brf-pc_brf-pg_brf;
   pa_brf.setMass(pa_brf.m());
   pa_brf.rescaleEnergy();
  
   // ************************************ //
   // Now we orient the momenta and boost  //
   // them back to the original lab frame. //
   // ************************************ //
   // As in herwig6507 we assume that, in the rest frame
   // of b, we have aligned the W boson momentum in the 
   // +Z direction by rot1*rot0*pa_lab, therefore
   // we obtain the new pa_lab by applying:
   // invrot*pa_brf.
   pa_lab = invrot*pa_brf;    
   pb_lab = invrot*pb_brf;    
   pc_lab = invrot*pc_brf;    
   pg_lab = invrot*pg_brf;    
   fs.push_back(pc_lab); 
   fs.push_back(pa_lab); 
   fs.push_back(pg_lab); 
   return fs;
 }
 
 double SMTopDecayer::getHard(double ktb, double ktc) {
   // zero the variables
   _xg = 0.;    
   _xa = 0.;   
   _xc = 0.;
   // Get a phase space point in the dead region: 
   double volume_factor = deadRegionxgxa(ktb,ktc);
   // if outside region return -1
   if(volume_factor<0) return volume_factor;
   // Compute the weight for this phase space point:
   double weight = volume_factor*me(_xa,_xg)*(1.+_a-_c-_xa); 
   // Alpha_S and colour factors - this hard wired Alpha_S needs removing.
   weight *= (4./3.)/Constants::pi
     *(alphaS()->value(_mt*_mt*_xg*(1.-_xa+_a-_c)/(2.-_xg-_xa-_c)));
   return weight; 
 }
 
 bool SMTopDecayer::softMatrixElementVeto(ShowerProgenitorPtr initial,
 					 ShowerParticlePtr parent,Branching br) {
   // check if we need to apply the full correction
   long id[2]={abs(initial->progenitor()->id()),abs(parent->id())};
   // the initial-state correction
   if(id[0]==ParticleID::t&&id[1]==ParticleID::t) {
     Energy pt=br.kinematics->pT();
     // check if hardest so far
     // if not just need to remove effect of enhancement
     bool veto(false);
     // if not hardest so far
     if(pt<initial->highestpT())
       veto=!UseRandom::rndbool(1./_initialenhance);
     // if hardest so far do calculation
     else {
       // values of kappa and z
       double z(br.kinematics->z()),kappa(sqr(br.kinematics->scale()/_mt));
       // parameters for the translation
       double w(1.-(1.-z)*(kappa-1.)),u(1.+_a-_c-(1.-z)*kappa),v(sqr(u)-4.*_a*w*z);
       // veto if outside phase space
       if(v<0.) 
 	veto=true;
       // otherwise calculate the weight
       else {
 	v = sqrt(v);
 	double xa((0.5*(u+v)/w+0.5*(u-v)/z)),xg((1.-z)*kappa);
 	double f(me(xa,xg)),
 	  J(0.5*(u+v)/sqr(w)-0.5*(u-v)/sqr(z)+_a*sqr(w-z)/(v*w*z));
 	double wgt(f*J*2./kappa/(1.+sqr(z)-2.*z/kappa)/_initialenhance);
 	// This next `if' prevents the hardest emission from the 
 	// top shower ever entering the so-called T2 region of the
 	// phase space if that region is to be populated by the hard MEC.
 	if(_useMEforT2&&xg>xgbcut(_ktb)) wgt = 0.;
 	if(wgt>1.) {
 	  generator()->log() << "Violation of maximum for initial-state "
 			     << " soft veto in "
 			     << "SMTopDecayer::softMatrixElementVeto"
 			     << "xg = " << xg << " xa = " << xa 
 			     << "weight =  " << wgt << "\n";
 	  wgt=1.;
 	}
 	// compute veto from weight
 	veto = !UseRandom::rndbool(wgt);
       }
       // if not vetoed reset max
       if(!veto) initial->highestpT(pt);
     }
     // if vetoing reset the scale
     if(veto) parent->vetoEmission(br.type,br.kinematics->scale());
     // return the veto
     return veto;
   }
   // final-state correction
   else if(id[0]==ParticleID::b&&id[1]==ParticleID::b) {
     Energy pt=br.kinematics->pT();
     // check if hardest so far
     // if not just need to remove effect of enhancement
     bool veto(false);
     // if not hardest so far
     if(pt<initial->highestpT()) return !UseRandom::rndbool(1./_finalenhance);
     // if hardest so far do calculation
     // values of kappa and z
     double z(br.kinematics->z()),kappa(sqr(br.kinematics->scale()/_mt));
     // momentum fractions
     double xa(1.+_a-_c-z*(1.-z)*kappa),r(0.5*(1.+_c/(1.+_a-xa))),root(sqr(xa)-4.*_a);
     if(root<0.) {
       generator()->log() << "Imaginary root for final-state veto in "
 			 << "SMTopDecayer::softMatrixElementVeto"
 			 << "\nz =  " << z  << "\nkappa = " << kappa
 			 << "\nxa = " << xa 
 			 << "\nroot^2= " << root;
       parent->vetoEmission(br.type,br.kinematics->scale());
       return true;
     } 
     root=sqrt(root);
     double xg((2.-xa)*(1.-r)-(z-r)*root);
     // xfact (below) is supposed to equal xg/(1-z). 
     double xfact(z*kappa/2./(z*(1.-z)*kappa+_c)*(2.-xa-root)+root);
     // calculate the full result
     double f(me(xa,xg));
     // jacobian
     double J(z*root);
     double wgt(f*J*2.*kappa/(1.+sqr(z)-2.*_c/kappa/z)/sqr(xfact)/_finalenhance);
     if(wgt>1.) {
       generator()->log() << "Violation of maximum for final-state  soft veto in "
 			 << "SMTopDecayer::softMatrixElementVeto"
 			 << "xg = " << xg << " xa = " << xa 
 			 << "weight =  " << wgt << "\n";
       wgt=1.;
     }
     // compute veto from weight
     veto = !UseRandom::rndbool(wgt);
     // if vetoing reset the scale
     if(veto) parent->vetoEmission(br.type,br.kinematics->scale());
     // return the veto
     return veto;
   }
   // otherwise don't veto
   else return !UseRandom::rndbool(1./_finalenhance);
 }
 
 double SMTopDecayer::me(double xw,double xg) {
   double prop(1.+_a-_c-xw),xg2(sqr(xg));
   double lambda=sqrt(1.+_a*_a+_c*_c-2.*_a-2.*_c-2.*_a*_c);
   double denom=(1.-2*_a*_a+_a+_c*_a+_c*_c-2.*_c);
   double wgt=-_c*xg2/prop+(1.-_a+_c)*xg-(prop*(1 - xg)+xg2)
     +(0.5*(1.+2.*_a+_c)*sqr(prop-xg)*xg+2.*_a*prop*xg2)/denom;
   return wgt/(lambda*prop);
 }
 
 
 // This function is auxiliary to the xab function.
 double SMTopDecayer::xgbr(int toggle) { 
   return 1.+toggle*sqrt(_a)-_c*(1.-toggle*sqrt(_a))/(1.-_a);
 }
 
 // This function is auxiliary to the xab function.
 double SMTopDecayer::ktr(double xgb, int toggle) { 
   return 2.*xgb/
     (xgb+toggle*sqrt((1.-1./_a)
 		     *(xgb-xgbr( 1))
 		     *(xgb-xgbr(-1))));
 }
 
 // Function xab determines xa (2*W energy fraction) for a given value
 // of xg (2*gluon energy fraction) and kappa tilde (q tilde squared over
 // m_top squared). Hence this function allows you to draw 1: the total
 // phase space volume in the xa vs xg plane 2: for a given value of 
 // kappa tilde (i.e. starting evolution scale) the associated contour 
 // in the xa vs xg plane (and hence the regions that either shower can 
 // populate). This calculation is done assuming the emission came from
 // the top quark i.e. kappa tilde here is the q tilde squared of the TOP
 // quark divided by m_top squared. 
 double SMTopDecayer::xab(double xgb, double kt, int toggle) { 
   double xab;
   if(toggle==2) {
     // This applies for g==0.&&kt==ktr(a,c,0.,xgb,1).
     xab = -2.*_a*(xgb-2.)/(1.+_a-_c-xgb);
   } else if(toggle==1) {
     // This applies for kt==1&&g==0.
     double lambda = sqrt(sqr(xgb-1.+_a+_c)-4.*_a*_c);
     xab = (0.5/(kt-xgb))*(kt*(1.+_a-_c-xgb)-lambda)
       + (0.5/(kt+xgb*(1.-kt)))*(kt*(1.+_a-_c-xgb)+lambda);
   } else {
     // This is the form of xab FOR _g=0.
     double ktmktrpktmktrm = kt*kt - 4.*_a*(kt-1.)*xgb*xgb
                                   / (sqr(1.-_a-_c-xgb)-4.*_a*_c);
     if(fabs(kt-(2.*xgb-2.*_g)/(xgb-sqrt(xgb*xgb-4.*_g)))/kt>1.e-6) {
       double lambda = sqrt((sqr(1.-_a-_c-xgb)-4.*_a*_c)*ktmktrpktmktrm);
       xab = (0.5/(kt-xgb))*(kt*(1.+_a-_c-xgb)-lambda)
 	  + (0.5/(kt+xgb*(1.-kt)))*(kt*(1.+_a-_c-xgb)+lambda);
     }
     else {
       // This is the value of xa as a function of xb when kt->infinity. 
       // Where we take any kt > (2.*xgb-2.*_g)/(xgb-sqrt(xgb*xgb-4.*_g)) 
       // as being effectively infinite. This kt value is actually the 
       // maximum allowed value kt can have if the phase space is calculated  
       // without the approximation of _g=0 (massless gluon). This formula
       // for xab below is then valid for _g=0 AND kt=infinity only.
       xab = ( 2.*_c+_a*(xgb-2.)
 	    + 3.*xgb
 	    - xgb*(_c+xgb+sqrt(_a*_a-2.*(_c-xgb+1.)*_a+sqr(_c+xgb-1.)))
             - 2.
             )/2./(xgb-1.);
     }
   }
   if(std::isnan(xab)) {
     double ktmktrpktmktrm = ( sqr(xgb*kt-2.*(xgb-_g))
 			      -kt*kt*(1.-1./_a)*(xgb-xgbr( 1)-_g/(1.+sqrt(_a)))
 			      *(xgb-xgbr(-1)-_g/(1.-sqrt(_a)))
 			      )/
       (xgb*xgb-(1.-1./_a)*(xgb-xgbr( 1)-_g/(1.+sqrt(_a)))
        *(xgb-xgbr(-1)-_g/(1.-sqrt(_a)))
        );
     double lambda = sqrt((xgb-1.+sqr(sqrt(_a)+sqrt(_c-_g)))
 			 *(xgb-1.+sqr(sqrt(_a)-sqrt(_c-_g)))*
 			 ktmktrpktmktrm);
     xab = (0.5/(kt-xgb+_g))*(kt*(1.+_a-_c+_g-xgb)-lambda)
       + (0.5/(kt+xgb*(1.-kt)-_g))*(kt*(1.+_a-_c+_g-xgb)+lambda);
     if(std::isnan(xab)) 
 	throw Exception() << "TopMECorrection::xab complex x_a value.\n"
 			  << "  xgb    = " << xgb    << "\n"
 			  << "  xab    = " << xab    << "\n"
 			  << "  toggle = " << toggle << "\n"
 			  << "  ktmktrpktmktrm = "   << ktmktrpktmktrm 
 			  << Exception::eventerror;
   }
   return xab;
 }
 
 // xgbcut is the point along the xg axis where the upper bound on the 
 // top quark (i.e. b) emission phase space goes back on itself in the 
 // xa vs xg plane i.e. roughly mid-way along the xg axis in
 // the xa vs xg Dalitz plot.
 double SMTopDecayer::xgbcut(double kt) { 
   double lambda2 = 1.+_a*_a+_c*_c-2.*_a-2.*_c-2.*_a*_c; 
   double num1    = kt*kt*(1.-_a-_c);
   double num2    = 2.*kt*sqrt(_a*(kt*kt*_c+lambda2*(kt-1.)));
   return (num1-num2)/(kt*kt-4.*_a*(kt-1.));
 }
 
 double SMTopDecayer::xaccut(double kt) { 
     return 1.+_a-_c-0.25*kt;
 }
 
 double SMTopDecayer::z(double xac, double kt, 
 		       int toggle1, int toggle2) { 
   double z = -1.0;
   if(toggle2==0) { 
     z = (kt+toggle1*sqrt(kt*(kt-4.*(1.+_a-_c-xac))))/(2.*kt); 
   } else if(toggle2==1) {
     z = ((1.+_a+_c-xac)+toggle1*(1.+_a-_c-xac))
       /(2.*(1.+_a-xac));
   } else if(toggle2==2) {
     z = 0.5;
   } else {
     throw Exception() << "Cannot determine z in SMTopDecayer::z()"
 		      << Exception::eventerror;
   }
   return z;
 }
 
 double SMTopDecayer::xgc(double xac, double kt, 
 			 int toggle1, int toggle2) { 
   double tiny(1.e-6);
   double xaToMinBoundary(xac*xac-4.*_a);
   if(xaToMinBoundary<0) {
     if(fabs(xaToMinBoundary/(1.-_a)/(1.-_a))<tiny)
       xaToMinBoundary *= -1.;
     else
       throw Exception() << "SMTopDecayer::xgc xa not in phase space!"
 			<< Exception::eventerror;
   }
   return (2.-xac)*(1.-0.5*(1.+_c/(1.+_a-xac)))
         -(z(xac,kt,toggle1,toggle2)-0.5*(1.+_c/(1.+_a-xac)))
         *sqrt(xaToMinBoundary);
 }
 
 double SMTopDecayer::xginvc0(double xg , double kt) { 
   // The function xg(kappa_tilde_c,xa) surely, enough, draws a  
   // line of constant kappa_tilde_c in the xg, xa Dalitz plot. 
   // Such a function can therefore draw the upper and lower 
   // edges of the phase space for emission from c (the b-quark).
   // However, to sample the soft part of the dead zone effectively
   // we want to generate a value of xg first and THEN distribute
   // xa in the associated allowed part of the dead zone. Hence, the 
   // function we want, to define the dead zone in xa for a given
   // xg, is the inverse of xg(kappa_tilde_c,xa). The full expression 
   // for xg(kappa_tilde_c,xa) is complicated and, sure enough, 
   // does not invert. Therefore we try to overestimate the size
   // of the dead zone initially, rejecting events which do not 
   // fall exactly inside it afterwards, with the immediate aim 
   // of getting an approximate version of xg(kappa_tilde_c,xa) 
   // that can  be inverted. We do this by simply setting c=0 i.e.
   // the b-quark mass to zero (and the gluon mass of course), in 
   // the full expression xg(...). The result of inverting this 
   // function is the output of this routine (a value of xa) hence 
   // the name xginvc0. xginvc0 is calculated to be,
   // xginvc0 = (1./3.)*(1.+a+pow((U+sqrt(4.*V*V*V+U*U))/2.,1./3.)
   //                      -V*pow(2./(U+sqrt(4.*V*V*V+U*U)),1./3.)
   //                   )
   // U = 2.*a*a*a - 66.*a*a + 9.*a*kt*xg + 18.*a*kt
   //   - 66.*a + 27.*kt*xg*xg - 45.*kt*xg +18.*kt +2. ;
   // V = -1.-a*a-14.*a-3.kt*xg+3.*kt;
   // This function, as with many functions in this ME correction,
   // is plagued by cuts that have to handled carefully in numerical 
   // implementation. We have analysed the cuts and hence we implement 
   // it in the following way, with a series of 'if' statements. 
   //
   // A useful -definition- to know in deriving the v<0 terms is
   // that tanh^-1(z) = 0.5*(log(1.+z)-log(1.-z)).
   double u,v,output;
   u = 2.*_a*_a*_a-66.*_a*_a
      +9.*xg*kt*_a+18.*kt*_a
      -66.*_a+27.*xg*xg*kt
      -45.*xg*kt+18.*kt+2.;
   v = -_a*_a-14.*_a-3.*xg*kt+3.*kt-1.;
   double u2=u*u,v3=v*v*v;
   if(v<0.) {
     if(u>0.&&(4.*v3+u2)<0.)      output = cos(  atan(sqrt(-4.*v3-u2)/u)/3.);
     else if(u>0.&&(4.*v3+u2)>0.) output = cosh(atanh(sqrt( 4.*v3+u2)/u)/3.);
     else                         output = cos(( atan(sqrt(-4.*v3-u2)/u)
 					       +Constants::pi)/3.);
     output *= 2.*sqrt(-v);
   } else {
     output = sinh(log((u+sqrt(4.*v3+u2))/(2.*sqrt(v3)))/3.);
     output *= 2.*sqrt(v);
   }
   if(!isfinite(output)) {
       throw Exception() << "TopMECorrection::xginvc0:\n"
 	  << "possible numerical instability detected.\n"
 	  << "\n v = " <<  v << "   u = " << u << "\n4.*v3+u2 = " << 4.*v3+u2
 	  << "\n_a = " << _a << "  ma = " << sqrt(_a*_mt*_mt/GeV2) 
 	  << "\n_c = " << _c << "  mc = " << sqrt(_c*_mt*_mt/GeV2) 
 	  << "\n_g = " << _g << "  mg = " << sqrt(_g*_mt*_mt/GeV2) 
 	  << Exception::eventerror;
   }
   return ( 1.+_a +output)/3.;
 }
 
 double SMTopDecayer::approxDeadMaxxa(double xg,double ktb,double ktc) {
   double maxxa(0.);
   double x  = min(xginvc0(xg,ktc),
 		  xab(xg,(2.*xg-2.*_g)/(xg-sqrt(xg*xg-4.*_g)),0));
   double y(-9999999999.);
   if(xg>2.*sqrt(_g)&&xg<=xgbcut(ktb)) {
       y = max(xab(xg,ktb,0),xab(xg,1.,1));
   } else if(xg>=xgbcut(ktb)&&xg<=1.-sqr(sqrt(_a)+sqrt(_c))) {
       y = max(xab(xg,ktr(xg,1),2),xab(xg,1.,1));
   }
   if(xg>2.*sqrt(_g)&&xg<=1.-sqr(sqrt(_a)+sqrt(_c))) {
     if(x>=y) { maxxa =  x       ; }
     else     { maxxa = -9999999.; }
   } else {
     maxxa = -9999999.;
   }
   return maxxa;
 }
 
 double SMTopDecayer::approxDeadMinxa(double xg,double ktb,double ktc) {
   double minxa(0.);
   double x  = min(xginvc0(xg,ktc),
 		  xab(xg,(2.*xg-2.*_g)/(xg-sqrt(xg*xg-4.*_g)),0));
   double y(-9999999999.);
   if(xg>2.*sqrt(_g)&&xg<=xgbcut(ktb)) {
       y = max(xab(xg,ktb,0),xab(xg,1.,1));
   } else if(xg>=xgbcut(ktb)&&xg<=1.-sqr(sqrt(_a)+sqrt(_c))) {
       if(_useMEforT2) y = xab(xg,1.,1);
       else            y = max(xab(xg,ktr(xg,1),2),xab(xg,1.,1));
   }
   if(xg>2.*sqrt(_g)&&xg<=1.-sqr(sqrt(_a)+sqrt(_c))) {
       if(x>=y) { minxa =  y  ; }
       else     { minxa = 9999999.; }
   } else {
       minxa = 9999999.;
   }
   return minxa;
 }
 
 // This function returns true if the phase space point (xg,xa) is in the 
 // kinematically allowed phase space.
 bool SMTopDecayer::inTheAllowedRegion(double xg , double xa) {
     bool output(true);
     if(xg<2.*sqrt(_g)||xg>1.-sqr(sqrt(_a)+sqrt(_c)))      output = false;
     if(xa<xab(xg,1.,1))                                   output = false;
     if(xa>xab(xg,(2.*xg-2.*_g)/(xg-sqrt(xg*xg-4.*_g)),0)) output = false;
     return output;
 }
 
 // This function returns true if the phase space point (xg,xa) is in the 
 // approximate (overestimated) dead region.
 bool SMTopDecayer::inTheApproxDeadRegion(double xg , double xa,
 					 double ktb, double ktc) {
     bool output(true);
     if(!inTheAllowedRegion(xg,xa))       output = false;
     if(xa<approxDeadMinxa(xg,ktb,ktc))   output = false;
     if(xa>approxDeadMaxxa(xg,ktb,ktc))   output = false;
     return output;
 }
 
 // This function returns true if the phase space point (xg,xa) is in the 
 // dead region.
 bool SMTopDecayer::inTheDeadRegion(double xg , double xa,
 				   double ktb, double ktc) {
     bool output(true);
     if(!inTheApproxDeadRegion(xg,xa,ktb,ktc)) output = false;
     if(xa>xaccut(ktc)) {
 	if(xg<xgc(max(xaccut(ktc),2.*sqrt(_a)),ktc, 1,2)&&
            xg>xgc(xa,ktc, 1,0)) { output = false; } 
 	if(xg>xgc(max(xaccut(ktc),2.*sqrt(_a)),ktc,-1,2)&&
            xg<xgc(xa,ktc,-1,0)) { output = false; } 
     } 
     return output;
 }
 
 // This function attempts to generate a phase space point in the dead
 // region and returns the associated phase space volume factor needed for
 // the associated event weight.
 double SMTopDecayer::deadRegionxgxa(double ktb,double ktc) {
   _xg=0.;
   _xa=0.;
   // Here we set limits on xg and generate a value inside the bounds.
   double xgmin(2.*sqrt(_g)),xgmax(1.-sqr(sqrt(_a)+sqrt(_c)));
   // Generate _xg.
   if(_xg_sampling==2.) {
       _xg=xgmin*xgmax/(xgmin+UseRandom::rnd()*(xgmax-xgmin));
   } else {
       _xg=xgmin*xgmax/pow((  pow(xgmin,_xg_sampling-1.)
 			    + UseRandom::rnd()*(pow(xgmax,_xg_sampling-1.)
 					       -pow(xgmin,_xg_sampling-1.))
 			   ),1./(_xg_sampling-1.));
   }
   // Here we set the bounds on _xa for given _xg.
   if(_xg<xgmin||xgmin>xgmax) 
       throw Exception() << "TopMECorrection::deadRegionxgxa:\n"
 			<< "upper xg bound is less than the lower xg bound.\n"
 			<< "\n_xg         = " << _xg 
 			<< "\n2.*sqrt(_g) = " << 2.*sqrt(_g) 
 			<< "\n_a  = " << _a  << "  ma = " << sqrt(_a*_mt*_mt/GeV2) 
 			<< "\n_c  = " << _c  << "  mc = " << sqrt(_c*_mt*_mt/GeV2) 
 			<< "\n_g  = " << _g  << "  mg = " << sqrt(_g*_mt*_mt/GeV2) 
 			<< Exception::eventerror;
   double xamin(approxDeadMinxa(_xg,ktb,ktc));
   double xamax(approxDeadMaxxa(_xg,ktb,ktc));
   // Are the bounds sensible? If not return.
   if(xamax<=xamin) return -1.;
   _xa=1.+_a-(1.+_a-xamax)*pow((1.+_a-xamin)/(1.+_a-xamax),UseRandom::rnd());
   // If outside the allowed region return -1.
   if(!inTheDeadRegion(_xg,_xa,ktb,ktc)) return -1.;
   // The integration volume for the weight
   double xg_vol,xa_vol; 
   if(_xg_sampling==2.) {
       xg_vol = (xgmax-xgmin)
              / (xgmax*xgmin);
   } else {
       xg_vol = (pow(xgmax,_xg_sampling-1.)-pow(xgmin,_xg_sampling-1.))
 	     / ((_xg_sampling-1.)*pow(xgmax*xgmin,_xg_sampling-1.));
   }
   xa_vol = log((1.+_a-xamin)/(1.+_a-xamax));
   // Here we return the integral volume factor multiplied by the part of the 
   // weight left over which is not included in the BRACES function, i.e.
   // the part of _xg^-2 which is not absorbed in the integration measure.
   return xg_vol*xa_vol*pow(_xg,_xg_sampling-2.);
 }
 
 LorentzRotation SMTopDecayer::rotateToZ(Lorentz5Momentum v) {
   // compute the rotation matrix
   LorentzRotation trans;
   // rotate so in z-y plane
   trans.rotateZ(-atan2(v.y(),v.x()));
   // rotate so along Z
   trans.rotateY(-acos(v.z()/v.vect().mag()));
   // generate random rotation
   double c,s,cs;
   do
     {
       c = 2.*UseRandom::rnd()-1.;
       s = 2.*UseRandom::rnd()-1.;
       cs = c*c+s*s;
     }
   while(cs>1.||cs==0.);
   double cost=(c*c-s*s)/cs,sint=2.*c*s/cs;
   // apply random azimuthal rotation
   trans.rotateZ(atan2(sint,cost));
   return trans;
 }
 
-bool SMTopDecayer::deadZoneCheck(double xw, double xg){
-
-  //veto events not in the dead cone 
-  double Lambda = sqrt(1. + sqr(s2()) + sqr(e2()) - 2.*s2() - 2.*e2() - 2.*s2()*e2());
-  double kappa = e2() + 0.5*(1. - s2() + e2() + Lambda);
-  //invert xw for z values
-  double A =  1.;
-  double B = -1.;
-  double C =  (1.+s2()-e2()-xw)/kappa;
-  if((sqr(B) - 4.*A*C) >= 0.){
-    double z[2];
-    z[0] = (-B + sqrt(sqr(B) - 4.*A*C))/(2.*A);
-    z[1] = (-B - sqrt(sqr(B) - 4.*A*C))/(2.*A);
-    double r = 0.5*(1. + e2()/(1. + s2()- xw));
-    double xg_lims [2];
-    xg_lims[0] = (2. - xw)*(1.-r) - (z[0]-r)*sqrt(sqr(xw) - 4.*s2());
-    xg_lims[1] = (2. - xw)*(1.-r) - (z[1]-r)*sqrt(sqr(xw) - 4.*s2());
-    double xg_low_lim = min(xg_lims[0], xg_lims[1]);
-    double xg_upp_lim = max(xg_lims[0], xg_lims[1]);
-    if (xg>=xg_low_lim && xg<=xg_upp_lim) return false;
-  }
-
-  double kappa_t = 1. + 0.5*(1. - s2() + e2() + Lambda);
-  double z = 1. - xg/kappa_t; 
-  double u = 1. + s2() - e2() - (1.-z)*kappa_t;
-  double y = 1. - (1.-z)*(kappa_t-1.);
-  if (sqr(u) - 4.*s2()*y*z >= 0.){
-    double v = sqrt(sqr(u) - 4.*s2()*y*z);
-    double xw_lim = (u + v) / (2.*y) + (u - v) / (2.*z);
-    if (xw <= xw_lim) return false;
-  }
-  else if (sqr(u) - 4.*s2()*y*z < 0.){
-    double xg_lim = (8.*s2() -2.*xw*(1-e2()+s2()))/(4.*s2()-2.*xw);
-    if (xg>=xg_lim) return false;
-  }
-
-  return true;
-}
-
 double SMTopDecayer::loME(const Particle & inpart, const ParticleVector & decay) {
   // spinors
   vector<SpinorWaveFunction   > swave;
   vector<SpinorBarWaveFunction> awave;
   vector<VectorWaveFunction> vwave;
   // spinors 
   if(inpart.id()>0) {
     SpinorWaveFunction   ::calculateWaveFunctions(swave,const_ptr_cast<tPPtr>(&inpart),
 						  incoming);
     SpinorBarWaveFunction::calculateWaveFunctions(awave,decay[0],outgoing);
   }
   else {
     SpinorBarWaveFunction::calculateWaveFunctions(awave,const_ptr_cast<tPPtr>(&inpart),
 						  incoming);
     SpinorWaveFunction   ::calculateWaveFunctions(swave,decay[0],outgoing);
   }
   // polarization vectors
   VectorWaveFunction::calculateWaveFunctions(vwave,decay[1],outgoing,false);
   Energy2 scale(sqr(inpart.mass()));
   double me=0.;
   if(inpart.id() == ParticleID::t) {
     for(unsigned int thel = 0; thel < 2; ++thel) {
       for(unsigned int bhel = 0; bhel < 2; ++bhel) {
 	for(unsigned int whel = 0; whel < 3; ++whel) {
 	  Complex diag = FFWVertex_->evaluate(scale,swave[thel],awave[bhel],vwave[whel]);
 	  me += norm(diag);
 	}
       }
     }
   }
   else if(inpart.id() == ParticleID::tbar) {
     for(unsigned int thel = 0; thel < 2; ++thel) {
       for(unsigned int bhel = 0; bhel < 2; ++bhel){ 
 	for(unsigned int whel = 0; whel < 3; ++whel) {
 	  Complex diag = FFWVertex_->evaluate(scale,swave[bhel],awave[thel],vwave[whel]);
 	  me += norm(diag);
  	}
       }
     }
   }
   return me;
 }
 
 
 double SMTopDecayer::realME(const Particle & inpart, const ParticleVector & decay,
 			    ShowerInteraction inter) {
   // vertex for emission from fermions
   AbstractFFVVertexPtr vertex = inter==ShowerInteraction::QCD ? FFGVertex_ : FFPVertex_;
   // spinors
   vector<SpinorWaveFunction   > swave;
   vector<SpinorBarWaveFunction> awave;
   vector<VectorWaveFunction> vwave,gwave;
   // spinors 
   if(inpart.id()>0) {
     SpinorWaveFunction   ::calculateWaveFunctions(swave,const_ptr_cast<tPPtr>(&inpart),
 						  incoming);
     SpinorBarWaveFunction::calculateWaveFunctions(awave,decay[0],outgoing);
   }
   else {
     SpinorBarWaveFunction::calculateWaveFunctions(awave,const_ptr_cast<tPPtr>(&inpart),
 						  incoming);
     SpinorWaveFunction   ::calculateWaveFunctions(swave,decay[0],outgoing);
   }
   // polarization vectors
   VectorWaveFunction::calculateWaveFunctions(vwave,decay[1],outgoing,false);
   VectorWaveFunction::calculateWaveFunctions(gwave,decay[2],outgoing,true );
   Energy2 scale(sqr(inpart.mass()));
   double me=0.;
   vector<Complex> diag(3,0.);
   if(inpart.id() == ParticleID::t) {
     for(unsigned int thel = 0; thel < 2; ++thel) {
       for(unsigned int bhel = 0; bhel < 2; ++bhel) {
 	for(unsigned int whel = 0; whel < 3; ++whel) {
 	  for(unsigned int ghel =0; ghel <3; ghel+=2) {
 	    // emission from top
 	    SpinorWaveFunction interF = vertex->evaluate(scale,3,inpart.dataPtr(),swave[thel],gwave[ghel]);
 	    diag[0] = FFWVertex_->evaluate(scale,interF,awave[bhel],vwave[whel]);
 	    // emission from bottom
 	    SpinorBarWaveFunction  interB = vertex->evaluate(scale,3,decay[0]->dataPtr(),awave[bhel],gwave[ghel]);
 	    diag[1] = FFWVertex_->evaluate(scale,swave[thel],interB,vwave[whel]);
 	    // emission from W
 	    if(inter==ShowerInteraction::QED) {
 	      VectorWaveFunction interV = WWWVertex_->evaluate(scale,3,decay[1]->dataPtr()->CC(),vwave[whel],gwave[ghel]);
 	      diag[1] = FFWVertex_->evaluate(scale,swave[thel],awave[bhel],interV);
 	    }
 	    Complex sum = std::accumulate(diag.begin(),diag.end(),Complex(0.));
 	    me += norm(sum);
 	  }
 	}
       }
     }
   }
   else if(inpart.id() == ParticleID::tbar) {
     for(unsigned int thel = 0; thel < 2; ++thel) {
       for(unsigned int bhel = 0; bhel < 2; ++bhel){ 
 	for(unsigned int whel = 0; whel < 3; ++whel) {
 	  for(unsigned int ghel =0; ghel <3; ghel+=2) {
 	    // emission from top
 	    SpinorBarWaveFunction  interB = vertex->evaluate(scale,3,inpart.dataPtr(),awave[thel],gwave[ghel]);
 	    diag[1] = FFWVertex_->evaluate(scale,swave[bhel],interB,vwave[whel]);
 	    // emission from bottom
 	    SpinorWaveFunction interF = vertex->evaluate(scale,3,decay[0]->dataPtr(),swave[bhel],gwave[ghel]);
 	    diag[0] = FFWVertex_->evaluate(scale,interF,awave[thel],vwave[whel]);
 	    // emission from W
 	    if(inter==ShowerInteraction::QED) {
 	      VectorWaveFunction interV = WWWVertex_->evaluate(scale,3,decay[1]->dataPtr()->CC(),vwave[whel],gwave[ghel]);
 	      diag[1] = FFWVertex_->evaluate(scale,swave[bhel],awave[thel],interV);
 	    }
 	    Complex sum = std::accumulate(diag.begin(),diag.end(),Complex(0.));
 	    me += norm(sum);
 	  }
 	}
       }
     }
   }
   // divide out the coupling
   me /= norm(vertex->norm());
   // return the total
   return me;
 }
 
 double SMTopDecayer::matrixElementRatio(const Particle & inpart,
 					const ParticleVector & decay2,
 					const ParticleVector & decay3,
 					MEOption ,
 					ShowerInteraction inter) {
   double Nc = standardModel()->Nc();
   double Cf = (sqr(Nc) - 1.) / (2.*Nc);  
   // if(inter==ShowerInteraction::QED) return 0.;
   // double f  = (1. + sqr(e2()) - 2.*sqr(s2()) + s2() + s2()*e2() - 2.*e2());
   // 
   // 
   // double B  = f/s2();
   
   // Energy2 PbPg = decay3[0]->momentum()*decay3[2]->momentum();
   // Energy2 PtPg = inpart.momentum()*decay3[2]->momentum();
   // Energy2 PtPb = inpart.momentum()*decay3[0]->momentum();
 
   // double R = Cf *((-4.*sqr(mb())*f/s2()) * ((sqr(mb())*e2()/sqr(PbPg)) + 
   // 		  (sqr(mb())/sqr(PtPg)) - 2.*(PtPb/(PtPg*PbPg))) +
   // 		  (16. + 8./s2() + 8.*e2()/s2()) * ((PtPg/PbPg) + (PbPg/PtPg)) -
   // 		  (16./s2()) * (1. + e2()));
   // return R/B*Constants::pi;
   double Bnew = loME(inpart,decay2);
   double Rnew = realME(inpart,decay3,inter);
   double output = Rnew/Bnew*4.*Constants::pi*sqr(inpart.mass())*UnitRemoval::InvE2;
   if(inter==ShowerInteraction::QCD) output *= Cf;
   return output;
 }
diff --git a/Decay/Perturbative/SMTopDecayer.h b/Decay/Perturbative/SMTopDecayer.h
--- a/Decay/Perturbative/SMTopDecayer.h
+++ b/Decay/Perturbative/SMTopDecayer.h
@@ -1,522 +1,516 @@
 // -*- C++ -*-
 //
 // SMTopDecayer.h is a part of Herwig - A multi-purpose Monte Carlo event generator
 // Copyright (C) 2002-2017 The Herwig Collaboration
 //
 // Herwig is licenced under version 3 of the GPL, see COPYING for details.
 // Please respect the MCnet academic guidelines, see GUIDELINES for details.
 //
 #ifndef HERWIG_SMTopDecayer_H
 #define HERWIG_SMTopDecayer_H
 //
 // This is the declaration of the SMTopDecayer class.
 //
 
 #include "Herwig/Decay/PerturbativeDecayer.h"
 #include "ThePEG/Helicity/Vertex/AbstractFFVVertex.h"
 #include "ThePEG/Helicity/Vertex/AbstractVVVVertex.h"
 #include "Herwig/Decay/DecayPhaseSpaceMode.h"
 #include "Herwig/Models/StandardModel/StandardModel.h"
 #include "Herwig/Shower/Core/Couplings/ShowerAlpha.fh"
 
 namespace Herwig {
   using namespace ThePEG;
   using namespace ThePEG::Helicity;
   
 /**
  * \ingroup Decay
  *
  * The SMTopDecayer performs decays of the top quark into
  * the bottom quark and qqbar pairs or to the bottom quark and lepton 
  * neutrino pairs via W boson exchange.
  */
 class SMTopDecayer: public PerturbativeDecayer {
 
 public:
 
   /**
    * The default constructor.
    */
   SMTopDecayer();
 
 public:
 
   /**
    *  Virtual members to be overridden by inheriting classes
    *  which implement hard corrections 
    */
   //@{
   /**
    *  Has an old fashioned ME correction
    */
   virtual bool hasMECorrection() {return true;}
 
   /**
    *  Initialize the ME correction
    */
   virtual void initializeMECorrection(RealEmissionProcessPtr , double & ,
 				      double & );
 
   /**
    *  Apply the hard matrix element correction to a given hard process or decay
    */
   virtual RealEmissionProcessPtr applyHardMatrixElementCorrection(RealEmissionProcessPtr);
 
   /**
    * Apply the soft matrix element correction
    * @param initial The particle from the hard process which started the 
    * shower
    * @param parent The initial particle in the current branching
    * @param br The branching struct
    * @return If true the emission should be vetoed
    */
   virtual bool softMatrixElementVeto(ShowerProgenitorPtr initial,
 				     ShowerParticlePtr parent,Branching br);
 
   /**
    *  Has a POWHEG style correction
    */
   virtual POWHEGType hasPOWHEGCorrection() {return FSR;}
   //@}
 
 public:
 
   /**
    * Which of the possible decays is required
    */
   virtual int modeNumber(bool & , tcPDPtr , const tPDVector & ) const {return -1;}
 
   /**
    * Check if this decayer can perfom the decay for a particular mode.
    * Uses the modeNumber member but can be overridden
    * @param parent The decaying particle
    * @param children The decay products
    */
   virtual bool accept(tcPDPtr parent, const tPDVector & children) const;
 
   /**
    * For a given decay mode and a given particle instance, perform the
    * decay and return the decay products. As this is the base class this
    * is not implemented.
    * @return The vector of particles produced in the decay.
    */
   virtual ParticleVector decay(const Particle & parent,
 			       const tPDVector & children) const;
 
   /**
    * Return the matrix element squared for a given mode and phase-space channel.
    * @param ichan The channel we are calculating the matrix element for. 
    * @param part The decaying Particle.
    * @param decay The particles produced in the decay.
    * @param meopt Option for the calculation of the matrix element
    * @return The matrix element squared for the phase-space configuration.
    */
   virtual double me2(const int ichan, const Particle & part,
 		     const ParticleVector & decay, MEOption meopt) const;
 
   /**
    * Method to return an object to calculate the 3 (or higher body) partial width
    * @param dm The DecayMode
    * @return A pointer to a WidthCalculatorBase object capable of calculating the width
    */
   virtual WidthCalculatorBasePtr threeBodyMEIntegrator(const DecayMode & dm) const;
   
   /**
    * The differential three body decay rate with one integral performed.
    * @param imode The mode for which the matrix element is needed.
    * @param q2 The scale, \e i.e. the mass squared of the decaying particle.
    * @param s  The invariant mass which still needs to be integrate over.
    * @param m1 The mass of the first  outgoing particle.
    * @param m2 The mass of the second outgoing particle.
    * @param m3 The mass of the third  outgoing particle.
    * @return The differential rate \f$\frac{d\Gamma}{ds}\f$
    */
   virtual InvEnergy threeBodydGammads(const int imode, const Energy2 q2,
 				      const Energy2 s, const Energy m1,
 				      const Energy m2, const Energy m3) const;
 
   /**
    * Output the setup information for the particle database
    * @param os The stream to output the information to
    * @param header Whether or not to output the information for MySQL
    */
   virtual void dataBaseOutput(ofstream & os,bool header) 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:
 
   /**
    *  The integrand for the integrate partial width
    */
   Energy6 dGammaIntegrand(Energy2 mffb2, Energy2 mbf2, Energy mt, Energy mb, 
 			  Energy mf, Energy mfb, Energy mw) const;
 
 protected:
 
   /** @name Clone Methods. */
   //@{
   /**
    * Make a simple clone of this object.
    * @return a pointer to the new object.
    */
   virtual IBPtr clone() const {return new_ptr(*this);}
 
   /** 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 {return new_ptr(*this);}
   //@}
 
 protected:
 
   /** @name Standard Interfaced functions. */
   //@{
   /**
    * Initialize this object after the setup phase before saving and
    * 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();
   //@}
 
 protected:
 
   /**
    *  Apply the hard matrix element
    */
   vector<Lorentz5Momentum> applyHard(const ParticleVector &p,double,double);
 
   /**
    *  Get the weight for hard emission
    */
   double getHard(double, double);
 
   /**
    *  This function is auxiliary to the function \f$x_{a}\f$ (hXAB).
    */
   double xgbr(int);
 
   /**
    *  This function is auxiliary to the function \f$x_{a}\f$ (hXAB).
    */
   double ktr(double,int);
 
   /**
    *  This function determines \f$x_{a}\f$ as a function of \f$x_{g}\f$ 
    *  and \f$\kappa\f$ where \f$\kappa\f$ pertains to emissions from the 
    *  b.
    */
   double xab(double,double,int);
 
   /**
    *  This function determines the point (\f$x_{g}\f$) where the condition that 
    *  \f$x_{a}\f$ be real supersedes that due to the external input 
    *  \f$\tilde{\kappa}\f$ where, again, \f$\kappa\f$ pertains to emissions from the 
    *  b.
    */
   double xgbcut(double);
 
   /**
    *  This function determines the minimum value of \f$x_{a}\f$ 
    *  for a given \f$\tilde{\kappa}\f$ where \f$\kappa\f$ pertains to
    *  emissions from the c.
    */
   double xaccut(double);
 
   /**
    *  This function is auxiliary to the function \f$x_{g}\f$ (hXGC).
    */
   double z(double,double,int,int); 
 
   /**
    *  This function determines \f$x_{g}\f$ as a function of \f$x_{a}\f$ 
    *  and \f$\kappa\f$ where \f$\kappa\f$ pertains to emissions from the 
    *  c. It is multivalued, one selects a branch according to the
    *  second to last integer flag (+/-1). The last integer flag
    *  is used to select whether (1) or not (0) you wish to have the 
    *  function for the special case of the full phase space, in which
    *  case the fifth argument \f$\kappa\f$ is irrelevant.
    */
   double xgc(double,double,int,int); 
 
   /**
    *  This function, \f$x_{g,c=0}^{-1}\f$, returns \f$x_{a}\f$ as a function 
    *  of \f$x_{g}\f$ for the special case of c=0, for emissions from c 
    *  (the b-quark). The third input is \f$\tilde{\kappa}\f$ which pertains 
    *  to emissions from c.
    */
   double xginvc0(double,double); 
 
   /**
    *  For a given value of \f$x_{g}\f$ this returns the maximum value of \f$x_{a}\f$  
    *  in the dead region.
    */
   double approxDeadMaxxa(double,double,double); 
 
   /**
    *  For a given value of \f$x_{g}\f$ this returns the maximum value of \f$x_{a}\f$  
    *  in the dead region.
    */
   double approxDeadMinxa(double,double,double); 
 
   /**
    *  This function returns true or false according to whether the values
    *  xg,xa are in the allowed region, the kinematically accessible phase 
    *  space.
    */
   bool inTheAllowedRegion(double,double); 
 
   /**
    *  This function returns true or false according to whether the values
    *  xg,xa are exactly in the approximate dead region.
    */
   bool inTheApproxDeadRegion(double,double,
                                     double,double); 
 
   /**
    *  This function returns true or false according to whether the values
    *  xg,xa are exactly in the dead region.
    */
   bool inTheDeadRegion(double,double,
                               double,double); 
 
   /**
    *  This function returns values of (\f$x_{g}\f$,\f$x_{a}\f$) distributed 
    *  according to \f$\left(1+a-x_{a}\right)^{-1}x_{g}^{-2}\f$ in the 
    *  approximate dead region.  
    */
   double deadRegionxgxa(double,double); 
 
   /**
    *  This rotation takes a 5-momentum and returns a rotation matrix 
    *  such that it acts on the input 5-momentum so as to
    *  make it point in the +Z direction. Finally it performs a randomn
    *  rotation about the z-axis.
    */
   LorentzRotation rotateToZ(Lorentz5Momentum);
 
   /**
    *  Full matrix element with a factor of \f$\frac{\alpha_SC_F}{x_g^2\pi}\f$ removed.
    * @param xw The momentum fraction of the W boson
    * @param xg The momentum fraction of the gluon.
    */
   double me(double xw, double xg);
 
 protected:
- /**
-   *  check if event is in dead region
-   */
-  bool deadZoneCheck(double xw, double xg);
-
-protected:
 
   /**
    *  Calculate matrix element ratio R/B
    */
   virtual double matrixElementRatio(const Particle & inpart, const ParticleVector & decay2,
 				    const ParticleVector & decay3, MEOption meopt,
 				    ShowerInteraction inter);
 
   /**
    *  LO matrix element for \f$t\to b W^\pm\f$
    */
   double loME(const Particle & inpart, const ParticleVector & decay);
 
   /**
    *  LO matrix element for \f$t\to b W^\pm\f$
    */
   double realME(const Particle & inpart, const ParticleVector & decay,
 		ShowerInteraction inter);
   
 private:
 
   /**
    * The assignment operator is private and must never be called.
    * In fact, it should not even be implemented.
    */
   SMTopDecayer & operator=(const SMTopDecayer &);
   
   /**
    * Pointer to the W vertex
    */
   AbstractFFVVertexPtr FFWVertex_;
   
   /**
    * Pointer to the gluon vertex
    */
   AbstractFFVVertexPtr FFGVertex_;
   
   /**
    * Pointer to the photon vertex
    */
   AbstractFFVVertexPtr FFPVertex_;
   
   /**
    * Pointer to the photon vertex
    */
   AbstractVVVVertexPtr WWWVertex_;
   
   /**
    * Max weight for integration
    */
   //@{   
   /**
    * Weight \f$W\to q\bar{q}'\f$
    */
   vector<double> _wquarkwgt;
   
   /**
    * Weight \f$W\to \ell \nu\f$
    */
   vector<double> _wleptonwgt;
   //@}
 
   /**
    *  Pointer to the \f$W^\pm\f$
    */
   PDPtr _wplus;
 
   /**
    *  Spin density matrix for the decay
    */
   mutable RhoDMatrix _rho;
 
   /**
    *  1st spinor for the decay
    */
   mutable vector<SpinorWaveFunction   >   _inHalf;
 
   /**
    *  2nd spinor for the decay
    */
   mutable vector<SpinorWaveFunction   >   _outHalf;
 
   /**
    *  1st barred spinor for the decay
    */
   mutable vector<SpinorBarWaveFunction>   _inHalfBar;
 
   /**
    *  2nd barred spinor for the decay
    */
   mutable vector<SpinorBarWaveFunction>   _outHalfBar;
 
   /**
    *  The mass of the W boson
    */
   Energy _ma;
 
   /**
    *  The mass of the bottom quark
    */
   Energy _mc;
 
   /**
    *  The top mass
    */
   Energy _mt;
 
   /**
    *  The gluon mass.
    */
   Energy _mg;
 
   /**
    *  The mass ratio for the W.
    */
   double _a;
 
   /**
    *  The mass ratio for the bottom.
    */
   double _c;
 
   /**
    *  The mass ratio for the gluon.
    */
   double _g;
 
   /**
    *  Two times the energy fraction of a.
    */
   double _ktb;
 
   /**
    *  Two times the energy fraction of the gluon.
    */
   double _ktc;
 
   /**
    *  Two times the energy fraction of the gluon.
    */
   double _xg;
 
   /**
    *  Two times the energy fraction of a.
    */
   double _xa;
 
   /**
    *  Two times the energy fraction of c.
    */
   double _xc;
 
   /**
    *  This determines the hard matrix element importance 
    *  sampling in _xg. _xg_sampling=2.0 samples as 1/xg^2.
    */
   double _xg_sampling;
 
   /**
    *  The enhancement factor for initial-state radiation
    */
   double _initialenhance;
 
   /**
    *  The enhancement factor for final-state radiation
    */
   double _finalenhance;
 
   /**
    *  This flag determines whether the T2 region in the decay shower
    *  (JHEP12(2003)_045) is populated by the ME correction (true) or
    *  the shower from the decaying particle.
    */
   bool _useMEforT2;
 };
 
 }
 
 #endif /* HERWIG_SMTopDecayer_H */
diff --git a/Decay/PerturbativeDecayer.cc b/Decay/PerturbativeDecayer.cc
--- a/Decay/PerturbativeDecayer.cc
+++ b/Decay/PerturbativeDecayer.cc
@@ -1,822 +1,948 @@
 // -*- C++ -*-
 //
 // This is the implementation of the non-inlined, non-templated member
 // functions of the PerturbativeDecayer class.
 //
 
 #include "PerturbativeDecayer.h"
 #include "ThePEG/Interface/ClassDocumentation.h"
 #include "ThePEG/EventRecord/Particle.h"
 #include "ThePEG/Repository/UseRandom.h"
 #include "ThePEG/Repository/EventGenerator.h"
 #include "ThePEG/Utilities/DescribeClass.h"
 #include "ThePEG/Persistency/PersistentOStream.h"
 #include "ThePEG/Persistency/PersistentIStream.h"
 #include "ThePEG/Interface/Reference.h"
 #include "ThePEG/Interface/Parameter.h"
 #include "ThePEG/Interface/Switch.h"
 #include "ThePEG/Utilities/EnumIO.h"
 
 using namespace Herwig;
 
 void PerturbativeDecayer::persistentOutput(PersistentOStream & os) const {
   os << ounit(pTmin_,GeV) << oenum(inter_) << alphaS_ << alphaEM_; 
 }
 
 void PerturbativeDecayer::persistentInput(PersistentIStream & is, int) {
   is >> iunit(pTmin_,GeV) >> ienum(inter_) >> alphaS_ >> alphaEM_; 
 }
 
 
 // The following static variable is needed for the type
 // description system in ThePEG.
 DescribeAbstractClass<PerturbativeDecayer,DecayIntegrator>
 describeHerwigPerturbativeDecayer("Herwig::PerturbativeDecayer",
 				  "Herwig.so HwPerturbativeDecay.so");
 
 void PerturbativeDecayer::Init() {
 
   static ClassDocumentation<PerturbativeDecayer> documentation
     ("The PerturbativeDecayer class is the mase class for perturbative decays in Herwig");
 
   static Parameter<PerturbativeDecayer,Energy> interfacepTmin
     ("pTmin",
      "Minimum transverse momentum from gluon radiation",
      &PerturbativeDecayer::pTmin_, GeV, 1.0*GeV, 0.0*GeV, 10.0*GeV,
      false, false, Interface::limited);
 
   
   static Switch<PerturbativeDecayer,ShowerInteraction> interfaceInteractions
     ("Interactions",
      "which interactions to include for the hard corrections",
      &PerturbativeDecayer::inter_, ShowerInteraction::QCD, false, false);
   static SwitchOption interfaceInteractionsQCD
     (interfaceInteractions,
      "QCD",
      "QCD Only",
      ShowerInteraction::QCD);
   static SwitchOption interfaceInteractionsQED
     (interfaceInteractions,
      "QED",
      "QED only",
      ShowerInteraction::QED);
   static SwitchOption interfaceInteractionsQCDandQED
     (interfaceInteractions,
      "QCDandQED",
      "Both QCD and QED",
      ShowerInteraction::Both);
 
   static Reference<PerturbativeDecayer,ShowerAlpha> interfaceAlphaS
     ("AlphaS",
      "Object for the coupling in the generation of hard QCD radiation",
      &PerturbativeDecayer::alphaS_, false, false, true, true, false);
 
   static Reference<PerturbativeDecayer,ShowerAlpha> interfaceAlphaEM
     ("AlphaEM",
      "Object for the coupling in the generation of hard QED radiation",
      &PerturbativeDecayer::alphaEM_, false, false, true, true, false);
 
 }
 
 double PerturbativeDecayer::threeBodyME(const int , const Particle &,
 					const ParticleVector &,MEOption) {
   throw Exception() << "Base class PerturbativeDecayer::threeBodyME() "
 		    << "called, should have an implementation in the inheriting class"
 		    << Exception::runerror;
   return 0.;
 }
 
 double PerturbativeDecayer::matrixElementRatio(const Particle & , 
 					       const ParticleVector & ,
 					       const ParticleVector & , 
 					       MEOption ,
 					       ShowerInteraction ) {
   throw Exception() << "Base class PerturbativeDecayer::matrixElementRatio() "
 		    << "called, should have an implementation in the inheriting class"
 		    << Exception::runerror;
   return 0.;
 }
 
 RealEmissionProcessPtr PerturbativeDecayer::generateHardest(RealEmissionProcessPtr born) {
+  return getHardEvent(born,false,inter_);
+}
+
+RealEmissionProcessPtr PerturbativeDecayer::getHardEvent(RealEmissionProcessPtr born,
+							 bool inDeadZone,
+							 ShowerInteraction inter) {
   // check one incoming
   assert(born->bornIncoming().size()==1);
   // check exactly two outgoing particles
   assert(born->bornOutgoing().size()==2);  // search for coloured particles
   bool colouredParticles=born->bornIncoming()[0]->dataPtr()->coloured();
-  if(!colouredParticles) {
-    for(unsigned int ix=0;ix<born->bornOutgoing().size();++ix) {
-      if(born->bornOutgoing()[ix]->dataPtr()->coloured()) {
-  	colouredParticles=true;
-  	break;
-      }
-    }
+  bool chargedParticles=born->bornIncoming()[0]->dataPtr()->charged();
+  for(unsigned int ix=0;ix<born->bornOutgoing().size();++ix) {
+    if(born->bornOutgoing()[ix]->dataPtr()->coloured())
+      colouredParticles=true;
+    if(born->bornOutgoing()[ix]->dataPtr()->charged())
+      chargedParticles=true;
   }
-  // if no coloured particles return
-  if ( !colouredParticles && inter_==ShowerInteraction::QCD ) return RealEmissionProcessPtr();
+  // if no coloured/charged particles return
+  if ( !colouredParticles && !chargedParticles ) return RealEmissionProcessPtr();
+  if ( !colouredParticles && inter==ShowerInteraction::QCD ) return RealEmissionProcessPtr();
+  if ( ! chargedParticles && inter==ShowerInteraction::QED ) return RealEmissionProcessPtr();
   // for decay b -> a c 
   // set progenitors
   PPtr cProgenitor = born->bornOutgoing()[0];
   PPtr aProgenitor = born->bornOutgoing()[1];
   // get the decaying particle
   PPtr bProgenitor = born->bornIncoming()[0];
   // identify which dipoles are required
   vector<DipoleType> dipoles;
-  if(!identifyDipoles(dipoles,aProgenitor,bProgenitor,cProgenitor)) {
+  if(!identifyDipoles(dipoles,aProgenitor,bProgenitor,cProgenitor,inter)) {
     return RealEmissionProcessPtr();
   }
   Energy trialpT = pTmin_;
   LorentzRotation eventFrame;
   vector<Lorentz5Momentum> momenta;
   vector<Lorentz5Momentum> trialMomenta(4);
   PPtr finalEmitter, finalSpectator;
   PPtr trialEmitter, trialSpectator;
   DipoleType finalType(FFa,ShowerInteraction::QCD);
   for (int i=0; i<int(dipoles.size()); ++i) {
 
     // assign emitter and spectator based on current dipole
     if (dipoles[i].type==FFc || dipoles[i].type==IFc || dipoles[i].type==IFbc){
       trialEmitter   = cProgenitor;
       trialSpectator = aProgenitor;
     }
     else if (dipoles[i].type==FFa || dipoles[i].type==IFa || dipoles[i].type==IFba){
       trialEmitter   = aProgenitor;
       trialSpectator = cProgenitor;
     }
     
     // find rotation from lab to frame with the spectator along -z
     LorentzRotation trialEventFrame(bProgenitor->momentum().findBoostToCM());
     Lorentz5Momentum pspectator = (trialEventFrame*trialSpectator->momentum());
     trialEventFrame.rotateZ( -pspectator.phi() );
     trialEventFrame.rotateY( -pspectator.theta() - Constants::pi );
     // invert it
     trialEventFrame.invert();
     // try to generate an emission
     pT_ = pTmin_;
     vector<Lorentz5Momentum> trialMomenta 
-      = hardMomenta(bProgenitor, trialEmitter, trialSpectator, dipoles, i);
+      = hardMomenta(bProgenitor, trialEmitter, trialSpectator,
+		    dipoles, i, inDeadZone);
     // select dipole which gives highest pT emission
     if(pT_>trialpT) {
       trialpT        = pT_;
       momenta        = trialMomenta;
       eventFrame     = trialEventFrame;
       finalEmitter   = trialEmitter;
       finalSpectator = trialSpectator;
       finalType      = dipoles[i];
       if (dipoles[i].type==FFc || dipoles[i].type==FFa ) {
       	if((momenta[3]+momenta[1]).m2()-momenta[1].m2()>
 	   (momenta[3]+momenta[2]).m2()-momenta[2].m2()) {
       	  swap(finalEmitter,finalSpectator);
       	  swap(momenta[1],momenta[2]);
       	}
       }
     }
   }
   pT_ = trialpT;
   // if no emission return
   if(momenta.empty()) {
-    if(inter_==ShowerInteraction::Both || inter_==ShowerInteraction::QCD)
+    if(inter==ShowerInteraction::Both || inter==ShowerInteraction::QCD)
       born->pT()[ShowerInteraction::QCD] = pTmin_;
-    if(inter_==ShowerInteraction::Both || inter_==ShowerInteraction::QED)
+    if(inter==ShowerInteraction::Both || inter==ShowerInteraction::QED)
       born->pT()[ShowerInteraction::QED] = pTmin_;
     return born;
   }
 
   // rotate momenta back to the lab
   for(unsigned int ix=0;ix<momenta.size();++ix) {
     momenta[ix] *= eventFrame;
   }
  
   // set maximum pT for subsequent branchings
-  if(inter_==ShowerInteraction::Both || inter_==ShowerInteraction::QCD)
+  if(inter==ShowerInteraction::Both || inter==ShowerInteraction::QCD)
     born->pT()[ShowerInteraction::QCD] = pT_;
-  if(inter_==ShowerInteraction::Both || inter_==ShowerInteraction::QED)
+  if(inter==ShowerInteraction::Both || inter==ShowerInteraction::QED)
     born->pT()[ShowerInteraction::QED] = pT_;
 
   // get ParticleData objects
   tcPDPtr b = bProgenitor   ->dataPtr();
   tcPDPtr e = finalEmitter  ->dataPtr();
   tcPDPtr s = finalSpectator->dataPtr();
   
   tcPDPtr boson  = getParticleData(finalType.interaction==ShowerInteraction::QCD ?
 				   ParticleID::g : ParticleID::gamma);
 
   // create new ShowerParticles
   PPtr emitter   = e    ->produceParticle(momenta[1]);
   PPtr spectator = s    ->produceParticle(momenta[2]);
   PPtr gauge     = boson->produceParticle(momenta[3]);
   PPtr incoming  = b    ->produceParticle(bProgenitor->momentum());
 
   // insert the particles
   born->incoming().push_back(incoming);
   unsigned int iemit(0),ispect(0);
   for(unsigned int ix=0;ix<born->bornOutgoing().size();++ix) {
     if(born->bornOutgoing()[ix]==finalEmitter) {
       born->outgoing().push_back(emitter);
       iemit = born->outgoing().size();
     }
     else if(born->bornOutgoing()[ix]==finalSpectator) {
       born->outgoing().push_back(spectator);
       ispect = born->outgoing().size();
     }
   }
   born->outgoing().push_back(gauge);
   if(!spectator->dataPtr()->coloured() ||
      (finalType.type != FFa && finalType.type!=FFc) ) ispect = 0;
   born->emitter(iemit);
   born->spectator(ispect);
   born->emitted(3);
   // set the interaction
   born->interaction(finalType.interaction);
   // set up colour lines
   getColourLines(born);
   // return the tree
   return born;
 }
 
 bool PerturbativeDecayer::identifyDipoles(vector<DipoleType>  & dipoles,
 					  PPtr & aProgenitor,
 					  PPtr & bProgenitor,
-					  PPtr & cProgenitor) const {
+					  PPtr & cProgenitor,
+					  ShowerInteraction inter) const {
   // identify any QCD dipoles
-  if(inter_==ShowerInteraction::QCD ||
-     inter_==ShowerInteraction::Both) {
+  if(inter==ShowerInteraction::QCD ||
+     inter==ShowerInteraction::Both) {
     PDT::Colour bColour = bProgenitor->dataPtr()->iColour();
     PDT::Colour cColour = cProgenitor->dataPtr()->iColour();
     PDT::Colour aColour = aProgenitor->dataPtr()->iColour();
     
     // decaying colour singlet
     if    (bColour==PDT::Colour0 ) {
       if ((cColour==PDT::Colour3    && aColour==PDT::Colour3bar) ||
 	  (cColour==PDT::Colour3bar && aColour==PDT::Colour3)    ||
 	  (cColour==PDT::Colour8    && aColour==PDT::Colour8)){
 	dipoles.push_back(DipoleType(FFa,ShowerInteraction::QCD));
 	dipoles.push_back(DipoleType(FFc,ShowerInteraction::QCD));
       }
     }
     // decaying colour triplet
     else if (bColour==PDT::Colour3 ) {
       if (cColour==PDT::Colour3 && aColour==PDT::Colour0){
 	dipoles.push_back(DipoleType(IFbc,ShowerInteraction::QCD));
 	dipoles.push_back(DipoleType(IFc ,ShowerInteraction::QCD));
       }
       else if (cColour==PDT::Colour0 && aColour==PDT::Colour3){
 	dipoles.push_back(DipoleType(IFba,ShowerInteraction::QCD));
 	dipoles.push_back(DipoleType(IFa ,ShowerInteraction::QCD));
       }
       else if (cColour==PDT::Colour8 && aColour==PDT::Colour3){
 	dipoles.push_back(DipoleType(IFbc,ShowerInteraction::QCD));
 	dipoles.push_back(DipoleType(IFc ,ShowerInteraction::QCD));
 	dipoles.push_back(DipoleType(FFc ,ShowerInteraction::QCD));
 	dipoles.push_back(DipoleType(FFa ,ShowerInteraction::QCD));
       }
       else if (cColour==PDT::Colour3 && aColour==PDT::Colour8){
 	dipoles.push_back(DipoleType(IFba,ShowerInteraction::QCD));
 	dipoles.push_back(DipoleType(IFa ,ShowerInteraction::QCD));
 	dipoles.push_back(DipoleType(FFc ,ShowerInteraction::QCD));
 	dipoles.push_back(DipoleType(FFa ,ShowerInteraction::QCD));
       }
     }
     // decaying colour anti-triplet 
     else if (bColour==PDT::Colour3bar) {
       if ((cColour==PDT::Colour3bar && aColour==PDT::Colour0)){
 	dipoles.push_back(DipoleType(IFbc,ShowerInteraction::QCD));
 	dipoles.push_back(DipoleType(IFc ,ShowerInteraction::QCD));
       }
       else if ((cColour==PDT::Colour0 && aColour==PDT::Colour3bar)){
 	dipoles.push_back(DipoleType(IFba,ShowerInteraction::QCD));
 	dipoles.push_back(DipoleType(IFa ,ShowerInteraction::QCD));      
       }
       else if (cColour==PDT::Colour8 && aColour==PDT::Colour3bar){
 	dipoles.push_back(DipoleType(IFbc,ShowerInteraction::QCD));
 	dipoles.push_back(DipoleType(IFc ,ShowerInteraction::QCD));
 	dipoles.push_back(DipoleType(FFc ,ShowerInteraction::QCD));
 	dipoles.push_back(DipoleType(FFa ,ShowerInteraction::QCD));
       }
       else if (cColour==PDT::Colour3bar && aColour==PDT::Colour8){
 	dipoles.push_back(DipoleType(IFba,ShowerInteraction::QCD));
 	dipoles.push_back(DipoleType(IFa ,ShowerInteraction::QCD));
 	dipoles.push_back(DipoleType(FFc ,ShowerInteraction::QCD));
 	dipoles.push_back(DipoleType(FFa ,ShowerInteraction::QCD));
       }
     }
     // decaying colour octet
     else if (bColour==PDT::Colour8){
       if ((cColour==PDT::Colour3    && aColour==PDT::Colour3bar) ||
 	  (cColour==PDT::Colour3bar && aColour==PDT::Colour3)){
 	dipoles.push_back(DipoleType(IFba,ShowerInteraction::QCD));
 	dipoles.push_back(DipoleType(IFbc,ShowerInteraction::QCD));
 	dipoles.push_back(DipoleType(IFa,ShowerInteraction::QCD));
 	dipoles.push_back(DipoleType(IFc,ShowerInteraction::QCD));
       }
       else if (cColour==PDT::Colour8 && aColour==PDT::Colour0){
 	dipoles.push_back(DipoleType(IFbc,ShowerInteraction::QCD));
 	dipoles.push_back(DipoleType(IFc,ShowerInteraction::QCD));
       }
       else if (cColour==PDT::Colour0 && aColour==PDT::Colour8){
 	dipoles.push_back(DipoleType(IFba,ShowerInteraction::QCD));
 	dipoles.push_back(DipoleType(IFa,ShowerInteraction::QCD));
       }
     }
   }
   // QED dipoles
-  if(inter_==ShowerInteraction::Both ||
-     inter_==ShowerInteraction::QED) {
+  if(inter==ShowerInteraction::Both ||
+     inter==ShowerInteraction::QED) {
     const bool & bCharged = bProgenitor->dataPtr()->charged();
     const bool & cCharged = cProgenitor->dataPtr()->charged();
     const bool & aCharged = aProgenitor->dataPtr()->charged();
     // initial-final
     if(bCharged && aCharged) {
       dipoles.push_back(DipoleType(IFba,ShowerInteraction::QED));
       dipoles.push_back(DipoleType(IFa ,ShowerInteraction::QED));
     }
     if(bCharged && cCharged) {
       dipoles.push_back(DipoleType(IFbc,ShowerInteraction::QED));
       dipoles.push_back(DipoleType(IFc ,ShowerInteraction::QED));
     }
     // final-state
     if(aCharged && cCharged) {
       dipoles.push_back(DipoleType(FFa,ShowerInteraction::QED));
       dipoles.push_back(DipoleType(FFc,ShowerInteraction::QED));
     }
   }
   // check colour structure is allowed
   return !dipoles.empty();
 }
 
 vector<Lorentz5Momentum>  PerturbativeDecayer::hardMomenta(PPtr in, PPtr emitter, 
 							   PPtr spectator, 
 							   const vector<DipoleType>  &dipoles, 
-							   int i) {
+							   int i, bool inDeadZone) {
   double C    = 6.3;
   double ymax = 10.;
   double ymin = -ymax;
 
   // get masses of the particles
   mb_  = in       ->momentum().mass();
   e_   = emitter  ->momentum().mass()/mb_;
   s_   = spectator->momentum().mass()/mb_;
   e2_  = sqr(e_);
   s2_  = sqr(s_);
 
   vector<Lorentz5Momentum> particleMomenta (4);
   Energy2 lambda = sqr(mb_)*sqrt(1.+sqr(s2_)+sqr(e2_)-2.*s2_-2.*e2_-2.*s2_*e2_);    
 
   // calculate A
   double A = (ymax-ymin)*C/Constants::twopi;
   if(dipoles[i].interaction==ShowerInteraction::QCD)
     A *= alphaS() ->overestimateValue();
   else
     A *= alphaEM()->overestimateValue();
   
   Energy pTmax = mb_*(sqr(1.-s_)-e2_)/(2.*(1.-s_));
 
   // if no possible branching return
   if ( pTmax < pTmin_ ) {
     particleMomenta.clear(); 
     return particleMomenta;
   }
   while (pTmax >= pTmin_) {
     // generate pT, y and phi values
     Energy pT = pTmax*pow(UseRandom::rnd(),(1./A));
     if (pT < pTmin_) {
       particleMomenta.clear(); 
       break;
     }
 
     double phi = UseRandom::rnd()*Constants::twopi;
     double y   = ymin+UseRandom::rnd()*(ymax-ymin);
     double weight[2] = {0.,0.};
     double xs[2], xe[2], xe_z[2], xg;
  
     for (unsigned int j=0; j<2; j++) {
       // check if the momenta are physical
       if (!calcMomenta(j, pT, y, phi, xg, xs[j], xe[j], xe_z[j], particleMomenta)) 
 	continue;
 
       // check if point lies within phase space
       if (!psCheck(xg, xs[j])) 
 	continue;
-
+      // check if point lies within the dead-zone (if required)
+      if(inDeadZone) {
+	if(!inTotalDeadZone(xg,xs[j],dipoles,i)) continue;
+      }
       // decay products for 3 body decay
       PPtr inpart   = in        ->dataPtr()->produceParticle(particleMomenta[0]);     
       ParticleVector decay3;
       decay3.push_back(emitter  ->dataPtr()->produceParticle(particleMomenta[1]));
       decay3.push_back(spectator->dataPtr()->produceParticle(particleMomenta[2]));
       if(dipoles[i].interaction==ShowerInteraction::QCD)
 	decay3.push_back(getParticleData(ParticleID::g    )->produceParticle(particleMomenta[3]));
       else
 	decay3.push_back(getParticleData(ParticleID::gamma)->produceParticle(particleMomenta[3]));
 
 	
       // decay products for 2 body decay
       Lorentz5Momentum p1(ZERO,ZERO, lambda/2./mb_,(mb_/2.)*(1.+e2_-s2_),mb_*e_);
       Lorentz5Momentum p2(ZERO,ZERO,-lambda/2./mb_,(mb_/2.)*(1.+s2_-e2_),mb_*s_);
       ParticleVector decay2;
       decay2.push_back(emitter  ->dataPtr()->produceParticle(p1));
       decay2.push_back(spectator->dataPtr()->produceParticle(p2));
       if (dipoles[i].type==FFc || dipoles[i].type==IFc || dipoles[i].type==IFbc){
 	swap(decay2[0],decay2[1]);
 	swap(decay3[0],decay3[1]);
       }
       
       // calculate matrix element ratio R/B
       double meRatio = matrixElementRatio(*inpart,decay2,decay3,Initialize,dipoles[i].interaction);
       
       // calculate dipole factor
       InvEnergy2 dipoleSum = ZERO;
       InvEnergy2 numerator = ZERO;
       for (int k=0; k<int(dipoles.size()); ++k) {
 	// skip dipoles which are not of the interaction being considered
 	if(dipoles[k].interaction!=dipoles[i].interaction) continue;
 	InvEnergy2 dipole = abs(calculateDipole(dipoles[k],*inpart,decay3));
 	dipoleSum += dipole;
 	if (k==i) numerator = dipole;
       }
       meRatio *= numerator/dipoleSum;
       // calculate jacobian
       Energy2 denom = (mb_-particleMomenta[3].e())*particleMomenta[2].vect().mag() -
 	particleMomenta[2].e()*particleMomenta[3].z(); 
       InvEnergy2  J  = (particleMomenta[2].vect().mag2())/(lambda*denom);
       // calculate weight
       weight[j] = meRatio*fabs(sqr(pT)*J)/C/Constants::twopi;
       if(dipoles[i].interaction==ShowerInteraction::QCD)
 	weight[j] *= alphaS() ->ratio(pT*pT);
       else
 	weight[j] *= alphaEM()->ratio(pT*pT);
     }
     // accept point if weight > R
     if (weight[0] + weight[1] > UseRandom::rnd()) {
       if (weight[0] > (weight[0] + weight[1])*UseRandom::rnd()) {
 	particleMomenta[1].setE( (mb_/2.)*xe  [0]);
 	particleMomenta[1].setZ( (mb_/2.)*xe_z[0]);
 	particleMomenta[2].setE( (mb_/2.)*xs  [0]);
 	particleMomenta[2].setZ(-(mb_/2.)*sqrt(sqr(xs[0])-4.*s2_));
       }
       else {
 	particleMomenta[1].setE( (mb_/2.)*xe  [1]);
 	particleMomenta[1].setZ( (mb_/2.)*xe_z[1]);
 	particleMomenta[2].setE( (mb_/2.)*xs  [1]);
 	particleMomenta[2].setZ(-(mb_/2.)*sqrt(sqr(xs[1])-4.*s2_));
       }
       pT_ = pT;
       break;   
     }
     // if there's no branching lower the pT
     pTmax = pT;  
   }
   return particleMomenta;
 }
 
 bool PerturbativeDecayer::calcMomenta(int j, Energy pT, double y, double phi,
 					double& xg, double& xs, double& xe, double& xe_z,
 					vector<Lorentz5Momentum>& particleMomenta){
 
   // calculate xg
   xg = 2.*pT*cosh(y) / mb_;
   if (xg>(1. - sqr(e_ + s_)) || xg<0.) return false;
 
   // calculate the two values of xs
   double xT  = 2.*pT / mb_;
   double A   = 4.-4.*xg+sqr(xT);
   double B   = 4.*(3.*xg-2.+2.*e2_-2.*s2_-sqr(xg)-xg*e2_+xg*s2_);
   double L   = 1.+sqr(s2_)+sqr(e2_)-2.*s2_-2.*e2_-2.*s2_*e2_;
   double det = 16.*( -L*sqr(xT)+pow(xT,4)*s2_+2.*xg*sqr(xT)*(1.-s2_-e2_)+ 
 		      L*sqr(xg)-sqr(xg*xT)*(1.+s2_)+pow(xg,4)+ 
 		      2.*pow(xg,3)*(-1.+s2_+e2_) );
 
   if (det<0.) return false;
   if (j==0) xs = (-B+sqrt(det))/(2.*A);
   if (j==1) xs = (-B-sqrt(det))/(2.*A);  
   // check value of xs is physical
   if (xs>(1.+s2_-e2_) || xs<2.*s_) return false;
 
   // calculate xe
   xe = 2.-xs-xg;     
   // check value of xe is physical
   if (xe>(1.+e2_-s2_) || xe<2.*e_) return false;       
 
   // calculate xe_z
   double root1 = sqrt(max(0.,sqr(xs)-4.*s2_)), root2 = sqrt(max(0.,sqr(xe)-4.*e2_-sqr(xT)));
   double epsilon_p =  -root1+xT*sinh(y)+root2;
   double epsilon_m =  -root1+xT*sinh(y)-root2;
 
   // find direction of emitter
   if      (fabs(epsilon_p) < 1.e-10) xe_z =  sqrt(sqr(xe)-4.*e2_-sqr(xT));
   else if (fabs(epsilon_m) < 1.e-10) xe_z = -sqrt(sqr(xe)-4.*e2_-sqr(xT));
   else return false;
 
   // check the emitter is on shell
   if (fabs((sqr(xe)-sqr(xT)-sqr(xe_z)-4.*e2_))>1.e-10) return false;
 
   // calculate 4 momenta
   particleMomenta[0].setE   ( mb_);
   particleMomenta[0].setX   ( ZERO);
   particleMomenta[0].setY   ( ZERO);
   particleMomenta[0].setZ   ( ZERO);
   particleMomenta[0].setMass( mb_);
 
   particleMomenta[1].setE   ( mb_*xe/2.);
   particleMomenta[1].setX   (-pT*cos(phi));
   particleMomenta[1].setY   (-pT*sin(phi));
   particleMomenta[1].setZ   ( mb_*xe_z/2.);
   particleMomenta[1].setMass( mb_*e_);
 
   particleMomenta[2].setE   ( mb_*xs/2.);
   particleMomenta[2].setX   ( ZERO);
   particleMomenta[2].setY   ( ZERO);
   particleMomenta[2].setZ   (-mb_*sqrt(sqr(xs)-4.*s2_)/2.);
   particleMomenta[2].setMass( mb_*s_);
 
   particleMomenta[3].setE   ( pT*cosh(y));
   particleMomenta[3].setX   ( pT*cos(phi));
   particleMomenta[3].setY   ( pT*sin(phi));
   particleMomenta[3].setZ   ( pT*sinh(y));
   particleMomenta[3].setMass( ZERO);
 
   return true;
 }
 
 bool PerturbativeDecayer::psCheck(const double xg, const double xs) {
 
   // check is point is in allowed region of phase space
   double xe_star = (1.-s2_+e2_-xg)/sqrt(1.-xg);
   double xg_star = xg/sqrt(1.-xg);
 
   if ((sqr(xe_star)-4.*e2_) < 1e-10) return false;
   double xs_max = (4.+4.*s2_-sqr(xe_star+xg_star)+ 
 		   sqr(sqrt(sqr(xe_star)-4.*e2_)+xg_star))/ 4.;
   double xs_min = (4.+4.*s2_-sqr(xe_star+xg_star)+ 
 		   sqr(sqrt(sqr(xe_star)-4.*e2_)-xg_star))/ 4.;
 
   if (xs < xs_min || xs > xs_max) return false;
 
   return true;
 }
 
 InvEnergy2 PerturbativeDecayer::calculateDipole(const DipoleType & dipoleId,  
 						const Particle & inpart,
 						const ParticleVector & decay3) {
   // calculate dipole for decay b->ac
   InvEnergy2 dipole = ZERO;
   double x1 = 2.*decay3[0]->momentum().e()/mb_;
   double x2 = 2.*decay3[1]->momentum().e()/mb_;
   double xg = 2.*decay3[2]->momentum().e()/mb_;
   double mu12 = sqr(decay3[0]->mass()/mb_);
   double mu22 = sqr(decay3[1]->mass()/mb_);
   tcPDPtr part[3] = {inpart.dataPtr(),decay3[0]->dataPtr(),decay3[1]->dataPtr()};
   if(dipoleId.type==FFc || dipoleId.type == IFc || dipoleId.type == IFbc) {
     swap(part[1],part[2]);
     swap(x1,x2);
     swap(mu12,mu22);
   }
   // radiation from b with initial-final connection 
   if (dipoleId.type==IFba || dipoleId.type==IFbc) {
     dipole  = -2./sqr(mb_*xg);
     dipole *= colourCoeff(part[0],part[1],part[2],dipoleId);
   }
   // radiation from a/c with initial-final connection
   else if (dipoleId.type==IFa || dipoleId.type==IFc) {
     double z  = 1. - xg/(1.-mu22+mu12);
     dipole = (-2.*mu12/sqr(1.-x2+mu22-mu12)/sqr(mb_) + (1./(1.-x2+mu22-mu12)/sqr(mb_))*
 	      (2./(1.-z)-dipoleSpinFactor(part[1],z))); 
     dipole *= colourCoeff(part[1],part[0],part[2],dipoleId);
   }
   // radiation from a/c with final-final connection
   else if (dipoleId.type==FFa || dipoleId.type==FFc) {
     double z = 1. + ((x1-1.+mu22-mu12)/(x2-2.*mu22));
     double y = (1.-x2-mu12+mu22)/(1.-mu12-mu22);
     double vt = sqrt((1.-sqr(e_+s_))*(1.-sqr(e_-s_)))/(1.-mu12-mu22);
     double v  = sqrt(sqr(2.*mu22+(1.-mu12-mu22)*(1.-y))-4.*mu22)
       /(1.-y)/(1.-mu12-mu22);
     if(part[1]->iSpin()!=PDT::Spin1) {
       dipole = (1./(1.-x2+mu22-mu12)/sqr(mb_))*
 	((2./(1.-z*(1.-y)))-vt/v*(dipoleSpinFactor(part[1],z)+(2.*mu12/(1.+mu22-mu12-x2))));
     }
     else {
       dipole = (1./(1.-x2+mu22-mu12)/sqr(mb_))*
 	(1./(1.-z*(1.-y))+1./(1.-(1.-z)*(1.-y))+(z*(1.-z)-2.)/v-vt/v*(2.*mu12/(1.+mu22-mu12-x2)));
     }
     dipole *= colourCoeff(part[1],part[2],part[0],dipoleId);
   }
   // coupling prefactors
   dipole *= 8.*Constants::pi;
   if(dipoleId.interaction==ShowerInteraction::QCD)
     dipole *= alphaS() ->value(mb_*mb_);
   else
     dipole *= alphaEM()->value(mb_*mb_);
   // return the answer
   return dipole;
 }
 
 double PerturbativeDecayer::dipoleSpinFactor(tcPDPtr part, double z){
   // calculate the spin dependent component of the dipole  
   if      (part->iSpin()==PDT::Spin0)
     return 2.;
   else if (part->iSpin()==PDT::Spin1Half)
     return (1. + z);
   else if (part->iSpin()==PDT::Spin1)
     return -(z*(1.-z) - 1./(1.-z) + 1./z -2.);
   return 0.;
 }
 
 double PerturbativeDecayer::colourCoeff(tcPDPtr emitter,
 					tcPDPtr spectator,
 					tcPDPtr other,
 					DipoleType dipole) {
   if(dipole.interaction==ShowerInteraction::QCD) {
     // calculate the colour factor of the dipole
     double numerator=1.;
     double denominator=1.;
     if (emitter->iColour()!=PDT::Colour0 &&
 	spectator->iColour()!=PDT::Colour0 &&
 	other->iColour()!=PDT::Colour0) {
       if      (emitter->iColour()  ==PDT::Colour3 ||
 	       emitter->iColour()  ==PDT::Colour3bar) numerator=-4./3;
       else if (emitter->iColour()  ==PDT::Colour8)    numerator=-3.  ;
       denominator=-1.*numerator;
       if      (spectator->iColour()==PDT::Colour3 ||
 	       spectator->iColour()==PDT::Colour3bar) numerator-=4./3;
       else if (spectator->iColour()==PDT::Colour8)    numerator-=3.  ;
       if      (other->iColour()    ==PDT::Colour3 ||
 	       other->iColour()    ==PDT::Colour3bar) numerator+=4./3;
       else if (other->iColour()    ==PDT::Colour8)    numerator+=3.  ;
       numerator*=(-1./2.);				  
     }
     
     if      (emitter->iColour()==PDT::Colour3 ||
 	     emitter->iColour()==  PDT::Colour3bar) numerator*=4./3.;
     else if (emitter->iColour()==PDT::Colour8 &&
 	     spectator->iColour()!=PDT::Colour8)    numerator*=3.;
     else if (emitter->iColour()==PDT::Colour8 &&
 	     spectator->iColour()==PDT::Colour8)    numerator*=6.;
     
     return (numerator/denominator);
   }
   else {
     double val = double(emitter->iCharge()*spectator->iCharge())/9.;
     // FF dipoles
     if(dipole.type==FFa || dipole.type == FFc) {
       return val;
     }
     else {
       return -val;
     }
   }
 }
 
 void PerturbativeDecayer::getColourLines(RealEmissionProcessPtr real) {
   // extract the particles
   vector<PPtr> branchingPart;
   branchingPart.push_back(real->incoming()[0]);
   for(unsigned int ix=0;ix<real->outgoing().size();++ix) {
     branchingPart.push_back(real->outgoing()[ix]);
   }
 
   vector<unsigned int> sing,trip,atrip,oct;
   for (size_t ib=0;ib<branchingPart.size()-1;++ib) {
     if     (branchingPart[ib]->dataPtr()->iColour()==PDT::Colour0   ) sing. push_back(ib);
     else if(branchingPart[ib]->dataPtr()->iColour()==PDT::Colour3   ) trip. push_back(ib);
     else if(branchingPart[ib]->dataPtr()->iColour()==PDT::Colour3bar) atrip.push_back(ib);
     else if(branchingPart[ib]->dataPtr()->iColour()==PDT::Colour8   ) oct.  push_back(ib);
   }
   // decaying colour singlet
   if (branchingPart[0]->dataPtr()->iColour()==PDT::Colour0) {
     // 0 -> 3 3bar
     if (trip.size()==1 && atrip.size()==1) {
       if(real->interaction()==ShowerInteraction::QCD) {
 	branchingPart[atrip[0]]->colourConnect(branchingPart[   3   ]);
 	branchingPart[    3   ]->colourConnect(branchingPart[trip[0]]);
       }
       else {
 	branchingPart[atrip[0]]->colourConnect(branchingPart[trip[0]]);
       }
     }
     // 0 -> 8 8
     else if (oct.size()==2 ) {
       if(real->interaction()==ShowerInteraction::QCD) {
 	bool col = UseRandom::rndbool();
 	branchingPart[oct[0]]->colourConnect(branchingPart[   3  ],col);
 	branchingPart[   3  ]->colourConnect(branchingPart[oct[1]],col);
 	branchingPart[oct[1]]->colourConnect(branchingPart[oct[0]],col);
       }
       else {
 	branchingPart[oct[0]]->colourConnect(branchingPart[oct[1]]);
 	branchingPart[oct[1]]->colourConnect(branchingPart[oct[0]]);
       }
     }
     else 
       assert(real->interaction()==ShowerInteraction::QED);
   }
   // decaying colour triplet
   else if (branchingPart[0]->dataPtr()->iColour()==PDT::Colour3 ){
     // 3 -> 3 0
     if (trip.size()==2 && sing.size()==1) {
       if(real->interaction()==ShowerInteraction::QCD) {
 	branchingPart[3]->incomingColour(branchingPart[trip[0]]);
 	branchingPart[3]-> colourConnect(branchingPart[trip[1]]);
       }
       else {
 	branchingPart[trip[1]]->incomingColour(branchingPart[trip[0]]);
       }
     }    // 3 -> 3 8
     else if (trip.size()==2 && oct.size()==1) {
       if(real->interaction()==ShowerInteraction::QCD) {
 	// 8 emit incoming partner
 	if(real->emitter()==oct[0]&&real->spectator()==0) {
 	  branchingPart[  3   ]->incomingColour(branchingPart[trip[0]]);
 	  branchingPart[  3   ]-> colourConnect(branchingPart[oct[0] ]);
 	  branchingPart[oct[0]]-> colourConnect(branchingPart[trip[1]]);
 	}
 	// 8 emit final spectator or vice veras
 	else {
 	  branchingPart[oct[0]]->incomingColour(branchingPart[trip[0]]);
 	  branchingPart[oct[0]]-> colourConnect(branchingPart[   3   ]);
 	  branchingPart[   3  ]-> colourConnect(branchingPart[trip[1]]);
 	}
       }
       else {
 	branchingPart[oct[0]]->incomingColour(branchingPart[trip[0]]);
 	branchingPart[oct[0]]-> colourConnect(branchingPart[trip[1]]);
       }
     }
     else
       assert(false);
   }
   // decaying colour anti-triplet
   else if (branchingPart[0]->dataPtr()->iColour()==PDT::Colour3bar) {
     // 3bar -> 3bar 0
     if (atrip.size()==2 && sing.size()==1) {
       if(real->interaction()==ShowerInteraction::QCD) {
 	branchingPart[3]->incomingColour(branchingPart[atrip[0]],true);
 	branchingPart[3]-> colourConnect(branchingPart[atrip[1]],true);
       }
       else {
 	branchingPart[atrip[1]]->incomingColour(branchingPart[atrip[0]],true);
       }
     }
     // 3 -> 3 8
     else if (atrip.size()==2 && oct.size()==1){
       if(real->interaction()==ShowerInteraction::QCD) {
 	// 8 emit incoming partner
 	if(real->emitter()==oct[0]&&real->spectator()==0) {
 	  branchingPart[   3  ]->incomingColour(branchingPart[atrip[0]],true);
 	  branchingPart[   3  ]-> colourConnect(branchingPart[oct[0]  ],true);
 	  branchingPart[oct[0]]-> colourConnect(branchingPart[atrip[1]],true);
 	}
 	// 8 emit final spectator or vice veras
 	else {
 	  if(real->interaction()==ShowerInteraction::QCD) {
 	    branchingPart[oct[0]]->incomingColour(branchingPart[atrip[0]],true);
 	    branchingPart[oct[0]]-> colourConnect(branchingPart[   3    ],true);
 	    branchingPart[3]-> colourConnect(branchingPart[atrip[1]]     ,true);
 	  }
 	}
       }
       else {
 	branchingPart[oct[0]]->incomingColour(branchingPart[atrip[0]],true);
 	branchingPart[oct[0]]-> colourConnect(branchingPart[atrip[1]],true);
       }
     }
     else
       assert(false);
   }
   // decaying colour octet
   else if(branchingPart[0]->dataPtr()->iColour()==PDT::Colour8 ) {
     // 8 -> 3 3bar
     if (trip.size()==1 && atrip.size()==1) {
       if(real->interaction()==ShowerInteraction::QCD) {
 	// 3 emits
 	if(trip[0]==real->emitter()) {
 	  branchingPart[3]       ->incomingColour(branchingPart[oct[0]] );
 	  branchingPart[3]       -> colourConnect(branchingPart[trip[0]]);
 	  branchingPart[atrip[0]]->incomingColour(branchingPart[oct[0]],true);
 	}
 	// 3bar emits
 	else {
 	  branchingPart[3]       ->incomingColour(branchingPart[oct[0]]  ,true);
 	  branchingPart[3]       -> colourConnect(branchingPart[atrip[0]],true);
 	  branchingPart[trip[0]]->incomingColour(branchingPart[oct[0]]  );
 	}
       }
       else {
 	branchingPart[trip[0]]->incomingColour(branchingPart[oct[0]] );
 	branchingPart[atrip[0]]->incomingColour(branchingPart[oct[0]],true);
       }
     }
     // 8 -> 8 0 
     else if (sing.size()==1 && oct.size()==2) {
       if(real->interaction()==ShowerInteraction::QCD) {
 	bool col = UseRandom::rndbool();
 	branchingPart[   3  ]->colourConnect (branchingPart[oct[1]], col);
 	branchingPart[   3  ]->incomingColour(branchingPart[oct[0]], col);
 	branchingPart[oct[1]]->incomingColour(branchingPart[oct[0]],!col);
       }
       else {
 	branchingPart[oct[1]]->incomingColour(branchingPart[oct[0]]);
 	branchingPart[oct[1]]->incomingColour(branchingPart[oct[0]],true);
       }
     }
     else
       assert(false);
   }
 }
+
+PerturbativeDecayer::phaseSpaceRegion
+PerturbativeDecayer::inInitialFinalDeadZone(double xg, double xa,
+					    double a, double c) const {
+  double lam    = sqrt(1.+a*a+c*c-2.*a-2.*c-2.*a*c);
+  double kappab = 1.+0.5*(1.-a+c+lam);
+  double kappac = kappab-1.+c;
+  double kappa(0.);
+  // check whether or not in the region for emission from c
+  double r = 0.5;
+  if(c!=0.) r += 0.5*c/(1.+a-xa);
+  double pa = sqrt(sqr(xa)-4.*a);
+  double z = ((2.-xa)*(1.-r)+r*pa-xg)/pa;
+  if(z<1. && z>0.) {
+    kappa = (1.+a-c-xa)/(z*(1.-z));
+    if(kappa<kappac)
+      return emissionFromC;
+  }
+  // check in region for emission from b (T1)
+  double cq = sqr(1.+a-c)-4*a;
+  double bq = -2.*kappab*(1.-a-c);
+  double aq = sqr(kappab)-4.*a*(kappab-1);
+  double dis = sqr(bq)-4.*aq*cq;
+  z=1.-(-bq-sqrt(dis))/2./aq;
+  double w = 1.-(1.-z)*(kappab-1.);
+  double xgmax = (1.-z)*kappab;
+  // possibly in T1 region
+  if(xg<xgmax) {
+    z = 1.-xg/kappab;
+    kappa=kappab;
+  }
+  // possibly in T2 region
+  else {
+    aq = 4.*a;
+    bq = -4.*a*(2.-xg);
+    cq = sqr(1.+a-c-xg);
+    dis = sqr(bq)-4.*aq*cq;
+    z = (-bq-sqrt(dis))/2./aq;
+    kappa = xg/(1.-z);
+  }
+  // compute limit on xa
+  double u = 1.+a-c-(1.-z)*kappa;
+  w = 1.-(1.-z)*(kappa-1.);
+  double v = sqr(u)-4.*z*a*w;
+  if(v<0. && v>-1e-10) v= 0.;
+  v = sqrt(v);
+  if(xa<0.5*((u+v)/w+(u-v)/z))
+    return xg<xgmax ? emissionFromA1 : emissionFromA2;
+  else
+    return deadZone;
+}
+
+PerturbativeDecayer::phaseSpaceRegion
+PerturbativeDecayer::inFinalFinalDeadZone(double xb, double xc,
+					  double b, double c) const {
+  // basic kinematics
+  double lam = sqrt(1.+b*b+c*c-2.*b-2.*c-2.*b*c);
+  // check whether or not in the region for emission from b
+  double r = 0.5;
+  if(b!=0.) r+=0.5*b/(1.+c-xc);
+  double pc = sqrt(sqr(xc)-4.*c);
+  double z = -((2.-xc)*r-r*pc-xb)/pc;
+  if(z<1. and z>0.) {
+    if((1.-b+c-xc)/(z*(1.-z))<0.5*(1.+b-c+lam)) return emissionFromB;
+  }
+  // check whether or not in the region for emission from c
+  r = 0.5;
+  if(c!=0.) r+=0.5*c/(1.+b-xb);
+  double pb = sqrt(sqr(xb)-4.*b);
+  z = -((2.-xb)*r-r*pb-xc)/pb;
+  if(z<1. and z>0.) {
+    if((1.-c+b-xb)/(z*(1.-z))<0.5*(1.-b+c+lam)) return emissionFromC;
+  }
+  return deadZone;
+}
+
+bool PerturbativeDecayer::inTotalDeadZone(double xg, double xs,
+					  const vector<DipoleType>  & dipoles,
+					  int i) {
+  double xb,xc,b,c;
+  if(dipoles[i].type==FFa || dipoles[i].type == IFa || dipoles[i].type == IFba) {
+    xc = xs;
+    xb = 2.-xg-xs;
+    b = e2_;
+    c = s2_;
+  }
+  else {
+    xb = xs;
+    xc = 2.-xg-xs;
+    b = s2_;
+    c = e2_;
+  }
+  for(unsigned int ix=0;ix<dipoles.size();++ix) {
+    if(dipoles[ix].interaction!=dipoles[i].interaction)
+      continue;
+    // should also remove negative QED dipoles but shouldn't be an issue unless we
+    // support QED ME corrections
+    switch (dipoles[ix].type) {
+    case FFa :
+      if(inFinalFinalDeadZone(xb,xc,b,c)!=deadZone) return false;
+      break;
+    case FFc :
+      if(inFinalFinalDeadZone(xc,xb,c,b)!=deadZone) return false;
+      break;
+    case IFa : case IFba:
+      if(inInitialFinalDeadZone(xg,xc,c,b)!=deadZone) return false;
+      break;
+    case IFc : case IFbc:
+      if(inInitialFinalDeadZone(xg,xb,b,c)!=deadZone) return false;
+      break;
+    }
+  }
+  return true;
+}
diff --git a/Decay/PerturbativeDecayer.h b/Decay/PerturbativeDecayer.h
--- a/Decay/PerturbativeDecayer.h
+++ b/Decay/PerturbativeDecayer.h
@@ -1,279 +1,310 @@
 // -*- C++ -*-
 #ifndef Herwig_PerturbativeDecayer_H
 #define Herwig_PerturbativeDecayer_H
 //
 // This is the declaration of the PerturbativeDecayer class.
 //
 
 #include "Herwig/Decay/DecayIntegrator.h"
 #include "Herwig/Shower/Core/Couplings/ShowerAlpha.h"
 #include "Herwig/Shower/Core/ShowerInteraction.h"
 
 namespace Herwig {
 
 using namespace ThePEG;
 
 /**
  * The PerturbativeDecayer class is the base class for perturbative decays in
  * Herwig and implements the functuality for the POWHEG corrections
  *
  * @see \ref PerturbativeDecayerInterfaces "The interfaces"
  * defined for PerturbativeDecayer.
  */
 class PerturbativeDecayer: public DecayIntegrator {
 
 protected:
   
   /**
    * Type of dipole
    */
   enum dipoleType {FFa, FFc, IFa, IFc, IFba, IFbc};
 
   /**
+   *   Phase-space region for an emission (assumes \f$a\to b,c\f$
+   */
+  enum phaseSpaceRegion {emissionFromB,emissionFromC,emissionFromA1,emissionFromA2,deadZone};
+
+  /**
    *  Type of dipole
    */
   struct DipoleType {
 
     DipoleType() {}
 
     DipoleType(dipoleType a, ShowerInteraction b)
       : type(a), interaction(b)
     {}
     
     dipoleType type;
 
     ShowerInteraction interaction;
   };
 
 public:
 
   /**
    * The default constructor.
    */
   PerturbativeDecayer() : inter_(ShowerInteraction::QCD),
 			  pTmin_(GeV), pT_(ZERO), mb_(ZERO),
 			  e_(0.), s_(0.), e2_(0.), s2_(0.)
   {}
 
   /**
    *  Has a POWHEG style correction
    */
   virtual POWHEGType hasPOWHEGCorrection() {return No;}
 
   /**
    *  Member to generate the hardest emission in the POWHEG scheme
    */
   virtual RealEmissionProcessPtr generateHardest(RealEmissionProcessPtr);
 
 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:
 
   /**
    *  Three-body matrix element including additional QCD radiation
    */
   virtual double threeBodyME(const int , const Particle & inpart,
 			     const ParticleVector & decay, MEOption meopt);
 
   /**
    *  Calculate matrix element ratio \f$\frac{M^2}{\alpha_S}\frac{|\overline{\rm{ME}}_3|}{|\overline{\rm{ME}}_2|}\f$
    */
   virtual double matrixElementRatio(const Particle & inpart, const ParticleVector & decay2,
 				    const ParticleVector & decay3, MEOption meopt,
 				    ShowerInteraction inter);
 
   /**
    *  Work out the type of process
    */
   bool identifyDipoles(vector<DipoleType> & dipoles,
 		       PPtr & aProgenitor,
 		       PPtr & bProgenitor,
-		       PPtr & cProgenitor) const;
+		       PPtr & cProgenitor,
+		       ShowerInteraction inter) const;
 
   /**
    *  Coupling for the generation of hard QCD radiation
    */
   ShowerAlphaPtr alphaS() {return alphaS_;}
 
   /**
    *  Coupling for the generation of hard QED radiation
    */
   ShowerAlphaPtr alphaEM() {return alphaEM_;}
 
   /**
    *  Return the momenta including the hard emission
    */
   vector<Lorentz5Momentum> hardMomenta(PPtr in, PPtr emitter, 
   				       PPtr spectator, 
-  				       const vector<DipoleType>  & dipoles, int i);
+  				       const vector<DipoleType>  & dipoles,
+				       int i, bool inDeadZone);
 
   /**
    *  Calculate momenta of all the particles
    */
   bool calcMomenta(int j, Energy pT, double y, double phi, double& xg, 
 		   double& xs, double& xe, double& xe_z, 
 		   vector<Lorentz5Momentum>& particleMomenta);
 
   /**
    *  Check the calculated momenta are physical
    */
   bool psCheck(const double xg, const double xs);
 
   /**
    * Return dipole corresponding to the DipoleType dipoleId
    */
   InvEnergy2 calculateDipole(const DipoleType & dipoleId,   const Particle & inpart,
 			     const ParticleVector & decay3);
 
   /**
    * Return contribution to dipole that depends on the spin of the emitter
    */
   double dipoleSpinFactor(tcPDPtr emitter, double z);
 
   /**
    *  Return the colour coefficient of the dipole
    */
   double colourCoeff(tcPDPtr emitter, tcPDPtr spectator,
 		     tcPDPtr other, DipoleType dipole);
   
   /**
    * Set up the colour lines
    */
   void getColourLines(RealEmissionProcessPtr real);
 
+  /**
+   *  Generate a hard emission
+   */
+  RealEmissionProcessPtr getHardEvent(RealEmissionProcessPtr born,
+				      bool inDeadZone,
+				      ShowerInteraction inter);
+
+  /**
+   *  Is the \f$x_g,x_s\f$ point in the dead-zone for all the dipoles
+   */
+  bool inTotalDeadZone(double xg, double xs,
+		       const vector<DipoleType>  & dipoles,
+		       int i);
+
+  /**
+   *  Is the \f$x_g,x_a\f$ point in the dead-zone for an initial-final colour connection
+   */
+  phaseSpaceRegion inInitialFinalDeadZone(double xg, double xa, double a, double c) const;
+
+  /**
+   *  Is the \f$x_b,x_c\f$ point in the dead-zone for a final-final colour connection
+   */
+  phaseSpaceRegion inFinalFinalDeadZone(double xb, double xc, double b, double c) const;
+
 protected:
 
   /**
    *  Access to the kinematics for inheriting classes
    */
   //@{
   /**
    *  Transverse momentum of the emission
    */
   const Energy & pT() const { return pT_;}
 
   /**
    *  Mass of decaying particle
    */
   const Energy & mb() const {return mb_;}
 
   /**
    *  Reduced mass of emitter child particle
    */
   const double & e() const {return e_;}
 
   /**
    * Reduced mass of spectator child particle
    */
   const double & s() const {return s_;}
 
   /**
    *  Reduced mass of emitter child particle squared
    */
   const double & e2() const {return e2_;}
 
   /**
    * Reduced mass of spectator child particle squared
    */
   const double & s2() const {return s2_;}
   //@}
 private:
 
   /**
    * The assignment operator is private and must never be called.
    * In fact, it should not even be implemented.
    */
   PerturbativeDecayer & operator=(const PerturbativeDecayer &);
 
 private:
 
   /**
    *  Members for the generation of the hard radiation
    */
   //@{
   /**
    *  Which types of radiation to generate
    */
   ShowerInteraction inter_;
   
   /**
    *  Coupling for the generation of hard QCD radiation
    */
   ShowerAlphaPtr alphaS_;
   
   /**
    *  Coupling for the generation of hard QED radiation
    */
   ShowerAlphaPtr alphaEM_;
 
   /**
    *  Minimum \f$p_T\f$
    */
   Energy pTmin_;
   //@}
 
 private:
 
   /**
    *   Mmeber variables for the kinematics of the hard emission
    */
   //@{
   /**
    *  Transverse momentum of the emission
    */
   Energy pT_;
 
   /**
    *  Mass of decaying particle
    */
   Energy mb_;
 
   /**
    *  Reduced mass of emitter child particle
    */
   double e_;
 
   /**
    * Reduced mass of spectator child particle
    */
   double s_;
 
   /**
    *  Reduced mass of emitter child particle squared
    */
   double e2_;
 
   /**
    * Reduced mass of spectator child particle squared
    */
   double s2_;
   //@}
 };
 
 }
 
 #endif /* Herwig_PerturbativeDecayer_H */