diff --git a/Decay/General/FFSDecayer.cc b/Decay/General/FFSDecayer.cc
--- a/Decay/General/FFSDecayer.cc
+++ b/Decay/General/FFSDecayer.cc
@@ -1,463 +1,465 @@
 // -*- C++ -*-
 //
 // FFSDecayer.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 FFSDecayer class.
 //
 
 #include "FFSDecayer.h"
 #include "ThePEG/Utilities/DescribeClass.h"
 #include "ThePEG/Interface/ClassDocumentation.h"
 #include "ThePEG/Persistency/PersistentOStream.h"
 #include "ThePEG/Persistency/PersistentIStream.h"
 #include "ThePEG/PDT/DecayMode.h"
 #include "ThePEG/Helicity/WaveFunction/ScalarWaveFunction.h"
 #include "ThePEG/Helicity/WaveFunction/SpinorWaveFunction.h"
 #include "ThePEG/Helicity/WaveFunction/SpinorBarWaveFunction.h"
 #include "Herwig/Utilities/Kinematics.h"
 #include "Herwig/Decay/GeneralDecayMatrixElement.h"
 
 using namespace Herwig;
 using namespace ThePEG::Helicity;
 
 IBPtr FFSDecayer::clone() const {
   return new_ptr(*this);
 }
 
 IBPtr FFSDecayer::fullclone() const {
   return new_ptr(*this);
 }
 
 void FFSDecayer::setDecayInfo(PDPtr incoming, PDPair outgoing,
 			      vector<VertexBasePtr> vertex,
 			      map<ShowerInteraction,VertexBasePtr> & inV,
 			      const vector<map<ShowerInteraction,VertexBasePtr> > & outV,
 			      map<ShowerInteraction,VertexBasePtr> ) {
   decayInfo(incoming,outgoing);
   for(auto vert : vertex) {
     vertex_             .push_back(dynamic_ptr_cast<AbstractFFSVertexPtr>(vert));
     perturbativeVertex_ .push_back(dynamic_ptr_cast<FFSVertexPtr>        (vert));
   }
   vector<ShowerInteraction> itemp={ShowerInteraction::QCD,ShowerInteraction::QED};
   for(auto & inter : itemp) {
     incomingVertex_[inter] = dynamic_ptr_cast<AbstractFFVVertexPtr>(inV.at(inter));
     outgoingVertexF_[inter] = AbstractFFVVertexPtr();
     outgoingVertexS_[inter] = AbstractVSSVertexPtr();
     if(outV[0].at(inter)) {
       if (outV[0].at(inter)->getName()==VertexType::FFV)
 	outgoingVertexF_[inter] = dynamic_ptr_cast<AbstractFFVVertexPtr>(outV[0].at(inter));
       else
 	outgoingVertexS_[inter] = dynamic_ptr_cast<AbstractVSSVertexPtr>(outV[0].at(inter));
     }
     if(outV[1].at(inter)) {
       if (outV[1].at(inter)->getName()==VertexType::FFV)
 	outgoingVertexF_[inter] = dynamic_ptr_cast<AbstractFFVVertexPtr>(outV[1].at(inter));
       else
 	outgoingVertexS_[inter] = dynamic_ptr_cast<AbstractVSSVertexPtr>(outV[1].at(inter));
     }
   }
 }
 
 void FFSDecayer::persistentOutput(PersistentOStream & os) const {
   os << perturbativeVertex_       << vertex_
      << incomingVertex_   << outgoingVertexF_
      << outgoingVertexS_;
 }
 
 void FFSDecayer::persistentInput(PersistentIStream & is, int) {
   is >> perturbativeVertex_       >> vertex_
      >> incomingVertex_   >> outgoingVertexF_
      >> outgoingVertexS_;
 }
 
 // The following static variable is needed for the type
 // description system in ThePEG.
 DescribeClass<FFSDecayer,GeneralTwoBodyDecayer>
 describeHerwigFFSDecayer("Herwig::FFSDecayer", "Herwig.so");
 
 void FFSDecayer::Init() {
 
   static ClassDocumentation<FFSDecayer> documentation
     ("The FFSDecayer class implements the decay of a fermion to "
      "a fermion and a scalar.");
 
 }
 
 double FFSDecayer::me2(const int , const Particle & inpart,
 		       const ParticleVector & decay,
 		       MEOption meopt) const {
   if(!ME())
     ME(new_ptr(GeneralDecayMatrixElement(PDT::Spin1Half,PDT::Spin1Half,PDT::Spin0)));
   //Need to use different barred or unbarred spinors depending on 
   //whether particle is cc or not.
   int itype[2];
   if(inpart.dataPtr()->CC())        itype[0] = inpart.id()    > 0? 0:1;
   else                              itype[0] = 2;
   if(decay[0]->dataPtr()->CC())     itype[1] = decay[0]->id() > 0? 0:1;
   else                              itype[1] = 2;
   bool ferm(itype[0] == 0 || itype[1] == 0 || (itype[0] == 2 && itype[1] == 2));
 
   if(meopt==Initialize) {
     // spinors and rho
     if(ferm) {
       SpinorWaveFunction   ::calculateWaveFunctions(wave_,rho_,
 						    const_ptr_cast<tPPtr>(&inpart),
 						    incoming);
       if(wave_[0].wave().Type() != SpinorType::u)
 	for(unsigned int ix = 0; ix < 2; ++ix) wave_   [ix].conjugate();
     }
     else {
       SpinorBarWaveFunction::calculateWaveFunctions(wavebar_,rho_,
 						    const_ptr_cast<tPPtr>(&inpart),
 						    incoming);
       if(wavebar_[0].wave().Type() != SpinorType::v)
 	for(unsigned int ix = 0; ix < 2; ++ix) wavebar_[ix].conjugate();
     }
+    // fix rho if no correlations
+    fixRho(rho_);
   }
   // setup spin info when needed
   if(meopt==Terminate) {
     // for the decaying particle
     if(ferm) {
       SpinorWaveFunction::
 	constructSpinInfo(wave_,const_ptr_cast<tPPtr>(&inpart),incoming,true);
       SpinorBarWaveFunction::constructSpinInfo(wavebar_,decay[0],outgoing,true);
     }
     else {
       SpinorBarWaveFunction::
 	constructSpinInfo(wavebar_,const_ptr_cast<tPPtr>(&inpart),incoming,true);
       SpinorWaveFunction::constructSpinInfo(wave_,decay[0],outgoing,true);
     }
     ScalarWaveFunction::constructSpinInfo(decay[1],outgoing,true);
   }
   if(ferm)
     SpinorBarWaveFunction::
       calculateWaveFunctions(wavebar_,decay[0],outgoing);
   else
     SpinorWaveFunction::
       calculateWaveFunctions(wave_   ,decay[0],outgoing);
   ScalarWaveFunction scal(decay[1]->momentum(),decay[1]->dataPtr(),outgoing);
   Energy2 scale(sqr(inpart.mass()));
   for(unsigned int if1 = 0; if1 < 2; ++if1) {
     for(unsigned int if2 = 0; if2 < 2; ++if2) {
       if(ferm) (*ME())(if1, if2, 0) = 0.;
       else     (*ME())(if2, if1, 0) = 0.;
       for(auto vert : vertex_) {
 	if(ferm) (*ME())(if1, if2, 0) += 
 		   vert->evaluate(scale,wave_[if1],wavebar_[if2],scal);
 	else     (*ME())(if2, if1, 0) += 
 		   vert->evaluate(scale,wave_[if1],wavebar_[if2],scal);
       }
     }
   }
   double output = (ME()->contract(rho_)).real()/scale*UnitRemoval::E2;
   // colour and identical particle factors
   output *= colourFactor(inpart.dataPtr(),decay[0]->dataPtr(),
 			 decay[1]->dataPtr());
   // return the answer
   return output;
 }
 
 Energy FFSDecayer::partialWidth(PMPair inpart, PMPair outa,
 				PMPair outb) const {
   if( inpart.second < outa.second + outb.second  ) return ZERO;
   if(perturbativeVertex_.size()==1 &&
      perturbativeVertex_[0]) {
     double mu1(0.),mu2(0.);
     tcPDPtr in = inpart.first->CC() ? tcPDPtr(inpart.first->CC()) : inpart.first;
     if(outa.first->iSpin() == PDT::Spin1Half) {
       mu1 = outa.second/inpart.second;
       mu2 = outb.second/inpart.second;
       perturbativeVertex_[0]->setCoupling(sqr(inpart.second), in, outa.first, outb.first);
     }
     else {
       mu1 = outb.second/inpart.second;
       mu2 = outa.second/inpart.second;
       perturbativeVertex_[0]->setCoupling(sqr(inpart.second), in, outb.first, outa.first);
       
     }
     double c2 = norm(perturbativeVertex_[0]->norm());
     Complex cl = perturbativeVertex_[0]->left();
     Complex cr = perturbativeVertex_[0]->right();
     double me2 = c2*( (norm(cl) + norm(cr))*(1. + sqr(mu1) - sqr(mu2))
 		      + 2.*mu1*(conj(cl)*cr + conj(cr)*cl).real() );
     Energy pcm = Kinematics::pstarTwoBodyDecay(inpart.second, outa.second,
 					outb.second);
     Energy output = me2*pcm/16./Constants::pi;
     // colour factor
     output *= colourFactor(inpart.first,outa.first,outb.first);
     // return the answer
     return output;
   }
   else {
     return GeneralTwoBodyDecayer::partialWidth(inpart,outa,outb);
   }
 }
 
 
 double FFSDecayer::threeBodyME(const int , const Particle & inpart,
 			       const ParticleVector & decay,
 			       ShowerInteraction inter, MEOption meopt) {
   int iscal (0), iferm (1), iglu (2);
   // get location of outgoing fermion/scalar
   if(decay[1]->dataPtr()->iSpin()==PDT::Spin0) swap(iscal,iferm);
   // work out whether inpart is a fermion or antifermion
   int itype[2];
   if(inpart.dataPtr()->CC())        itype[0] = inpart.id() > 0 ? 0 : 1;
   else                              itype[0] = 2;
   if(decay[iferm]->dataPtr()->CC()) itype[1] = decay[iferm]->id() > 0 ? 0 : 1;
   else                              itype[1] = 2;
 
   bool ferm(false);
   if(itype[0] == itype[1] ) {
     ferm = itype[0]==0 || (itype[0]==2 && decay[iscal]->id() < 0);
   }
   else if(itype[0] == 2) {
     ferm = itype[1]==0;
   }
   else if(itype[1] == 2) {
     ferm = itype[0]==0;
   }
   else if((itype[0] == 1 && itype[1] == 0) ||
 	  (itype[0] == 0 && itype[1] == 1)) {
     if(abs(inpart.id())<=16) {
       ferm = itype[0]==0;
     }
     else if(abs(decay[iferm]->id())<=16) {
       ferm = itype[1]==0;
     }
     else {
       ferm = true;
     }
   }
   else
     assert(false);
   if(meopt==Initialize) {
     // create spinor (bar) for decaying particle
     if(ferm) {
       SpinorWaveFunction::calculateWaveFunctions(wave3_, rho3_, const_ptr_cast<tPPtr>(&inpart), 
 						 incoming);
       if(wave3_[0].wave().Type() != SpinorType::u)
    	for(unsigned int ix = 0; ix < 2; ++ix) wave3_[ix].conjugate();
     }
     else {
       SpinorBarWaveFunction::calculateWaveFunctions(wavebar3_,rho3_, const_ptr_cast<tPPtr>(&inpart), 
 						    incoming);
       if(wavebar3_[0].wave().Type() != SpinorType::v)
    	for(unsigned int ix = 0; ix < 2; ++ix) wavebar3_[ix].conjugate();
     }
   }
   // setup spin information when needed 
   if(meopt==Terminate) {
     if(ferm) {
       SpinorWaveFunction::
 	constructSpinInfo(wave3_,const_ptr_cast<tPPtr>(&inpart),incoming,true);
       SpinorBarWaveFunction::constructSpinInfo(wavebar3_,decay[iferm],outgoing,true);
     }
     else {
       SpinorBarWaveFunction::
 	constructSpinInfo(wavebar3_,const_ptr_cast<tPPtr>(&inpart),incoming,true);
       SpinorWaveFunction::constructSpinInfo(wave3_,decay[iferm],outgoing,true);
     }
     ScalarWaveFunction::constructSpinInfo(        decay[iscal],outgoing,true);
     VectorWaveFunction::constructSpinInfo(gluon_, decay[iglu ],outgoing,true,false);
     return 0.;
   }
 
   // calulate colour factors and number of colour flows
   unsigned int nflow;
   vector<DVector> cfactors = getColourFactors(inpart, decay, nflow);
 
   vector<GeneralDecayMEPtr> ME(nflow,new_ptr(GeneralDecayMatrixElement(PDT::Spin1Half, PDT::Spin0,
 								       PDT::Spin1Half, PDT::Spin1)));
   // create wavefunctions
   if (ferm)  SpinorBarWaveFunction::calculateWaveFunctions(wavebar3_, decay[iferm],outgoing);
   else       SpinorWaveFunction::   calculateWaveFunctions(wave3_   , decay[iferm],outgoing);
   
   ScalarWaveFunction swave3_(decay[iscal]->momentum(), decay[iscal]->dataPtr(),outgoing);
   VectorWaveFunction::calculateWaveFunctions(gluon_,   decay[iglu ],outgoing,true);
 
   // gauge invariance test
 #ifdef GAUGE_CHECK
   gluon_.clear();
   for(unsigned int ix=0;ix<3;++ix) {
     if(ix==1) gluon_.push_back(VectorWaveFunction());
     else {
       gluon_.push_back(VectorWaveFunction(decay[iglu ]->momentum(),decay[iglu ]->dataPtr(),10,
 					  outgoing));
     }
   }
 #endif
   
   if (! ((incomingVertex_[inter]  && (outgoingVertexF_[inter] || outgoingVertexS_[inter])) ||
 	 (outgoingVertexF_[inter] &&  outgoingVertexS_[inter])))
     throw Exception()
       << "Invalid vertices for radiation in FFS decay in FFSDecayer::threeBodyME"
       << Exception::runerror;
 
 
   // sort out colour flows
   int F(1), S(2);
   if (decay[iscal]->dataPtr()->iColour()==PDT::Colour3 && 
       decay[iferm]->dataPtr()->iColour()==PDT::Colour8)
     swap(F,S);
   else if (decay[iferm]->dataPtr()->iColour()==PDT::Colour3bar && 
 	   decay[iscal]->dataPtr()->iColour()==PDT::Colour8)
     swap(F,S);
 
 
   Complex diag;
   Energy2 scale(sqr(inpart.mass()));
 
   const GeneralTwoBodyDecayer::CFlow & colourFlow
         = colourFlows(inpart, decay);
   double gs(0.);
   bool couplingSet(false);
 #ifdef GAUGE_CHECK
   double total=0.;
 #endif
   for(unsigned int ifi = 0; ifi < 2; ++ifi) {
     for(unsigned int ifo = 0; ifo < 2; ++ifo) {
       for(unsigned int ig = 0; ig < 2; ++ig) {
    	// radiation from the incoming fermion
    	if((inpart.dataPtr()->coloured() && inter==ShowerInteraction::QCD) ||
 	   (inpart.dataPtr()->charged()  && inter==ShowerInteraction::QED) ) {
    	  assert(incomingVertex_[inter]);
 	  if (ferm) {
 	    SpinorWaveFunction spinorInter =
 	      incomingVertex_[inter]->evaluate(scale,3,inpart.dataPtr(),wave3_[ifi],
 					       gluon_[2*ig],inpart.mass());
 
 	    assert(wave3_[ifi].particle()->id()==spinorInter.particle()->id());
 	    diag = 0.;
 	    for(auto vertex : vertex_)
 	      diag += vertex->evaluate(scale,spinorInter,wavebar3_[ifo],swave3_);
 	  }
 	  else {
 	    SpinorBarWaveFunction spinorBarInter = 
 	      incomingVertex_[inter]->evaluate(scale,3,inpart.dataPtr(),wavebar3_[ifi],
 					       gluon_[2*ig],inpart.mass());
 
 	    assert(wavebar3_[ifi].particle()->id()==spinorBarInter.particle()->id());
 	    diag = 0.;
 	    for(auto vertex :vertex_)
 	      diag+= vertex->evaluate(scale,wave3_[ifo], spinorBarInter,swave3_);
 	  }
 	  if(!couplingSet) {
 	    gs = abs(incomingVertex_[inter]->norm());
 	    couplingSet = true;
 	  }
 	  for(unsigned int ix=0;ix<colourFlow[0].size();++ix) {
 	    (*ME[colourFlow[0][ix].first])(ifi, 0, ifo, ig) += 
 	       colourFlow[0][ix].second*diag;
 	  }
 #ifdef GAUGE_CHECK
 	  total+=norm(diag);
 #endif
 	}
 	  
   	// radiation from outgoing fermion
    	if((decay[iferm]->dataPtr()->coloured() && inter==ShowerInteraction::QCD) ||
 	   (decay[iferm]->dataPtr()->charged()  && inter==ShowerInteraction::QED) ) {
   	  assert(outgoingVertexF_[inter]);
 	  // ensure you get correct outgoing particle from first vertex
 	  tcPDPtr off = decay[iferm]->dataPtr();
 	  if(off->CC()) off = off->CC();  	  
 	  if (ferm) {	    
 	    SpinorBarWaveFunction spinorBarInter = 
 	      outgoingVertexF_[inter]->evaluate(scale,3,off,wavebar3_[ifo],
 						gluon_[2*ig],decay[iferm]->mass());
 	    
 	    assert(wavebar3_[ifo].particle()->id()==spinorBarInter.particle()->id());
 	    diag = 0.;
 	    for(auto vertex :vertex_)
 	      diag+= vertex->evaluate(scale,wave3_[ifi],spinorBarInter,swave3_);
 	  }
 	  else {
 	    SpinorWaveFunction spinorInter = 
 	      outgoingVertexF_[inter]->evaluate(scale,3,off,wave3_[ifo],
 						gluon_[2*ig],decay[iferm]->mass());
 	      
 	    assert(wave3_[ifo].particle()->id()==spinorInter.particle()->id());
 	    diag = 0.;
 	    for(auto vertex :vertex_)
 	      diag+= vertex->evaluate(scale,spinorInter,wavebar3_[ifi],swave3_);
 	  }
 	  if(!couplingSet) {
 	    gs = abs(outgoingVertexF_[inter]->norm());
 	    couplingSet = true;
 	  }
 	  for(unsigned int ix=0;ix<colourFlow[F].size();++ix) {
 	    (*ME[colourFlow[F][ix].first])(ifi, 0, ifo, ig) += 
 	      colourFlow[F][ix].second*diag;
 	  }
 #ifdef GAUGE_CHECK
 	  total+=norm(diag);
 #endif
   	}
 
   	// radiation from outgoing scalar
    	if((decay[iscal]->dataPtr()->coloured() && inter==ShowerInteraction::QCD) ||
 	   (decay[iscal]->dataPtr()->charged()  && inter==ShowerInteraction::QED) ) {
   	  assert(outgoingVertexS_[inter]);
 	  // ensure you get correct ougoing particle from first vertex
 	  tcPDPtr off = decay[iscal]->dataPtr();
 	  if(off->CC()) off = off->CC();
 	  ScalarWaveFunction  scalarInter = 
 	    outgoingVertexS_[inter]->evaluate(scale,3,off,gluon_[2*ig],
 					      swave3_,decay[iscal]->mass());
 	    
 	  assert(swave3_.particle()->id()==scalarInter.particle()->id());
 	  if (ferm){
 	    diag = 0.;
 	    for(auto vertex :vertex_)
 	      diag += vertex->evaluate(scale,wave3_[ifi],wavebar3_[ifo],scalarInter);
 	  }
 	  else {
 	    diag = 0.;
 	    for(auto vertex :vertex_)
 	      diag += vertex->evaluate(scale,wave3_[ifo],wavebar3_[ifi],scalarInter);
 	  }
 	  if(!couplingSet) {
 	    gs = abs(outgoingVertexS_[inter]->norm());
 	    couplingSet = true;
 	  }
 	  for(unsigned int ix=0;ix<colourFlow[S].size();++ix) {
   	    (*ME[colourFlow[S][ix].first])(ifi, 0, ifo, ig) += 
 	      colourFlow[S][ix].second*diag;
 	  }
 #ifdef GAUGE_CHECK
 	  total+=norm(diag);
 #endif
   	}
       }
     }
   }
 
   // contract matrices
   double output=0.;
   for(unsigned int ix=0; ix<nflow; ++ix){
     for(unsigned int iy=0; iy<nflow; ++iy){
       output+=cfactors[ix][iy]*(ME[ix]->contract(*ME[iy],rho3_)).real();
     }
   }
   // divide by alpha(S,EM)
   output*=(4.*Constants::pi)/sqr(gs);
 #ifdef GAUGE_CHECK
   double ratio = output/total;
   if(abs(ratio)>1e-20) {
     generator()->log() << "Test of gauge invariance in decay\n" << inpart << "\n";
     for(unsigned int ix=0;ix<decay.size();++ix)
       generator()->log() << *decay[ix] << "\n";
     generator()->log() << "Test of gauge invariance " << ratio << "\n";
   }
 #endif
 
   // return the answer
   return output;
 }
diff --git a/Decay/General/FFVCurrentDecayer.cc b/Decay/General/FFVCurrentDecayer.cc
--- a/Decay/General/FFVCurrentDecayer.cc
+++ b/Decay/General/FFVCurrentDecayer.cc
@@ -1,200 +1,202 @@
 // -*- C++ -*-
 //
 // FFVCurrentDecayer.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 FFVCurrentDecayer class.
 //
 
 #include "FFVCurrentDecayer.h"
 #include "ThePEG/Utilities/DescribeClass.h"
 #include "ThePEG/Interface/ClassDocumentation.h"
 #include "ThePEG/Persistency/PersistentOStream.h"
 #include "ThePEG/Persistency/PersistentIStream.h"
 #include "ThePEG/Helicity/WaveFunction/VectorWaveFunction.h"
 #include "ThePEG/Helicity/WaveFunction/SpinorWaveFunction.h"
 #include "ThePEG/Helicity/WaveFunction/SpinorBarWaveFunction.h"
 #include "ThePEG/StandardModel/StandardModelBase.h"
 #include "Herwig/Decay/GeneralDecayMatrixElement.h"
 
 using namespace Herwig;
 
 using ThePEG::Helicity::VectorWaveFunction;
 using ThePEG::Helicity::SpinorWaveFunction;
 using ThePEG::Helicity::SpinorBarWaveFunction;
 using ThePEG::Helicity::Direction;
 using ThePEG::Helicity::incoming;
 using ThePEG::Helicity::outgoing;
 
 IBPtr FFVCurrentDecayer::clone() const {
   return new_ptr(*this);
 }
 
 IBPtr FFVCurrentDecayer::fullclone() const {
   return new_ptr(*this);
 }
 
 void FFVCurrentDecayer::doinit() {
   FFVPtr_ = dynamic_ptr_cast<FFVVertexPtr>(vertex());
   GeneralCurrentDecayer::doinit();
 }
 
 
 void FFVCurrentDecayer::rebind(const TranslationMap & trans)
   {
   FFVPtr_ = trans.translate(FFVPtr_);
   GeneralCurrentDecayer::rebind(trans);
 }
 
 IVector FFVCurrentDecayer::getReferences() {
   IVector ret = GeneralCurrentDecayer::getReferences();
   ret.push_back(FFVPtr_);
   return ret;
 }
 
 void FFVCurrentDecayer::persistentOutput(PersistentOStream & os) const {
   os << FFVPtr_;
 }
 
 void FFVCurrentDecayer::persistentInput(PersistentIStream & is, int) {
   is >> FFVPtr_;
 }
 
 // The following static variable is needed for the type
 // description system in ThePEG.
 DescribeClass<FFVCurrentDecayer,GeneralCurrentDecayer>
 describeHerwigFFVCurrentDecayer("Herwig::FFVCurrentDecayer", "Herwig.so");
 
 void FFVCurrentDecayer::Init() {
 
   static ClassDocumentation<FFVCurrentDecayer> documentation
     ("There is no documentation for the FFVCurrentDecayer class");
 
 }
 
 double FFVCurrentDecayer::me2(const int ichan, const Particle & inpart,
 			      const ParticleVector & decay,
 			      MEOption meopt) const {
   // get the particles for the hadronic curret
   Energy q;
   ParticleVector hadpart(decay.begin()+1,decay.end());
   // fermion types
   int itype[2];
   if(inpart.dataPtr()->CC())    itype[0] = inpart.id() > 0 ? 0 : 1;
   else                          itype[0] = 2;
   if(decay[0]->dataPtr()->CC()) itype[1] = decay[0]->id() > 0 ? 0 : 1;
   else                          itype[1] = 2;
   //Need to use different barred or unbarred spinors depending on 
   //whether particle is cc or not.
   bool ferm(itype[0] == 0 || itype[1] == 0 || (itype[0] == 2 && itype[1] == 2));
   if(meopt==Initialize) {
     // spinors and rho
     if(ferm) {
       SpinorWaveFunction   ::calculateWaveFunctions(wave_,rho_,
 						    const_ptr_cast<tPPtr>(&inpart),
 						    incoming);
       if(wave_[0].wave().Type() != SpinorType::u)
 	for(unsigned int ix = 0; ix < 2; ++ix) wave_   [ix].conjugate();
     }
     else {
       SpinorBarWaveFunction::calculateWaveFunctions(wavebar_,rho_,
 						    const_ptr_cast<tPPtr>(&inpart),
 						    incoming);
       if(wavebar_[0].wave().Type() != SpinorType::v)
 	for(unsigned int ix = 0; ix < 2; ++ix) wavebar_[ix].conjugate();
     }
+    // fix rho if no correlations
+    fixRho(rho_);
   }
   // setup spin info when needed
   if(meopt==Terminate) {
     // for the decaying particle
     if(ferm) {
       SpinorWaveFunction::
 	constructSpinInfo(wave_,const_ptr_cast<tPPtr>(&inpart),incoming,true);
       SpinorBarWaveFunction::constructSpinInfo(wavebar_,decay[0],outgoing,true);
     }
     else {
       SpinorBarWaveFunction::
 	constructSpinInfo(wavebar_,const_ptr_cast<tPPtr>(&inpart),incoming,true);
       SpinorWaveFunction::constructSpinInfo(wave_,decay[0],outgoing,true);
     }
     weakCurrent()->current(mode(),ichan,q,hadpart,meopt);
     return 0.;
   }
   Energy2 scale(sqr(inpart.mass()));
   if(ferm)
     SpinorBarWaveFunction::
       calculateWaveFunctions(wavebar_,decay[0],outgoing);
   else
     SpinorWaveFunction::
       calculateWaveFunctions(wave_   ,decay[0],outgoing);
   // calculate the hadron current
   vector<LorentzPolarizationVectorE> 
     hadron(weakCurrent()->current(mode(),ichan,q,hadpart,meopt));
   // prefactor
   double pre = sqr(pow(inpart.mass()/q,int(hadpart.size()-2)));
   // work out the mapping for the hadron vector
   vector<unsigned int> constants(decay.size()+1),ihel(decay.size()+1);
   vector<PDT::Spin> ispin(decay.size());
   int itemp(1);
   unsigned int hhel,ix(decay.size());
   do {
     --ix;
     ispin[ix]=decay[ix]->data().iSpin();
     itemp*=ispin[ix];
     constants[ix]=itemp;
   }
   while(ix>0);
   constants[decay.size()]=1;
   constants[0]=constants[1];
   // compute the matrix element
   GeneralDecayMEPtr newME(new_ptr(GeneralDecayMatrixElement(PDT::Spin1Half,ispin)));
   VectorWaveFunction vWave;
   tcPDPtr vec= inpart.dataPtr()->iCharge()-decay[0]->dataPtr()->iCharge() > 0
     ? getParticleData(ParticleID::Wplus) : getParticleData(ParticleID::Wminus);
   Lorentz5Momentum vmom=inpart.momentum()-decay[0]->momentum();
   vmom.rescaleMass();
   for(hhel=0;hhel<hadron.size();++hhel) {
     // map the index for the hadrons to a helicity state
     for(ix=decay.size();ix>1;--ix) ihel[ix]=(hhel%constants[ix-1])/constants[ix];
     vWave=VectorWaveFunction(vmom,vec,hadron[hhel]*UnitRemoval::InvE,outgoing);
     for(unsigned int if1 = 0; if1 < 2; ++if1) {
       for(unsigned int if2 = 0; if2 < 2; ++if2) {
 	ihel[0]=if1;
 	ihel[1]=if2;
 	if(!ferm) swap(ihel[0],ihel[1]);
 	(*newME)(ihel) = FFVPtr_->evaluate(scale,wave_[if1],wavebar_[if2],vWave);
       }
     }
   }
   // store the matrix element
   ME(newME);
   // multiply by the CKM element
   int iq,ia;
   weakCurrent()->decayModeInfo(mode(),iq,ia);
   double ckm(1.);
   if(iq<=6) {
     if(iq%2==0) ckm = SM().CKM(iq/2-1,(abs(ia)-1)/2);
     else        ckm = SM().CKM(abs(ia)/2-1,(iq-1)/2);
   }
   pre /= 0.125*sqr(FFVPtr_->weakCoupling(scale));
   double output(0.5*pre*ckm*(ME()->contract(rho_)).real()*
 		sqr(SM().fermiConstant()*UnitRemoval::E2));
   return output;
 }
  
 Energy FFVCurrentDecayer::partialWidth(tPDPtr inpart, tPDPtr outa,
 				       vector<tPDPtr> currout) {
   vector<long> id;
   id.push_back(inpart->id());
   id.push_back(outa->id());
   for(unsigned int ix=0;ix<currout.size();++ix) id.push_back(currout[ix]->id());
   bool cc;
   int mode=modeNumber(cc,id);
   imode(mode);
   return initializePhaseSpaceMode(mode,true,true);  
 }
diff --git a/Decay/General/FFVDecayer.cc b/Decay/General/FFVDecayer.cc
--- a/Decay/General/FFVDecayer.cc
+++ b/Decay/General/FFVDecayer.cc
@@ -1,456 +1,458 @@
 // -*- C++ -*-
 //
 // FFVDecayer.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 FFVDecayer class.
 //
 
 #include "FFVDecayer.h"
 #include "ThePEG/Utilities/DescribeClass.h"
 #include "ThePEG/Interface/ClassDocumentation.h"
 #include "ThePEG/Persistency/PersistentOStream.h"
 #include "ThePEG/Persistency/PersistentIStream.h"
 #include "ThePEG/PDT/DecayMode.h"
 #include "ThePEG/Helicity/WaveFunction/VectorWaveFunction.h"
 #include "ThePEG/Helicity/WaveFunction/SpinorWaveFunction.h"
 #include "ThePEG/Helicity/WaveFunction/SpinorBarWaveFunction.h"
 #include "Herwig/Utilities/Kinematics.h"
 #include "Herwig/Decay/GeneralDecayMatrixElement.h"
 using namespace Herwig;
 using namespace ThePEG::Helicity;
 
 IBPtr FFVDecayer::clone() const {
   return new_ptr(*this);
 }
 
 IBPtr FFVDecayer::fullclone() const {
   return new_ptr(*this);
 }
 
 void FFVDecayer::setDecayInfo(PDPtr incoming, PDPair outgoing,
 			      vector<VertexBasePtr> vertex,
 			      map<ShowerInteraction,VertexBasePtr> & inV,
 			      const vector<map<ShowerInteraction,VertexBasePtr> > & outV,
 			      map<ShowerInteraction,VertexBasePtr> ) {
   decayInfo(incoming,outgoing);
   for(auto vert : vertex) {
     vertex_             .push_back(dynamic_ptr_cast<AbstractFFVVertexPtr>(vert));
     perturbativeVertex_ .push_back(dynamic_ptr_cast<FFVVertexPtr>        (vert));
   }
   vector<ShowerInteraction> itemp={ShowerInteraction::QCD,ShowerInteraction::QED};
   for(auto & inter : itemp) {
     incomingVertex_[inter] = dynamic_ptr_cast<AbstractFFVVertexPtr>(inV.at(inter));
     if(outV[0].at(inter)) {
       if (outV[0].at(inter)->getName()==VertexType::FFV)
 	outgoingVertexF_[inter] = dynamic_ptr_cast<AbstractFFVVertexPtr>(outV[0].at(inter));
       else
 	outgoingVertexV_[inter] = dynamic_ptr_cast<AbstractVVVVertexPtr>(outV[0].at(inter));
     }
     if(outV[1].at(inter)) {
       if (outV[1].at(inter)->getName()==VertexType::FFV)
 	outgoingVertexF_[inter] = dynamic_ptr_cast<AbstractFFVVertexPtr>(outV[1].at(inter));
       else
 	outgoingVertexV_[inter] = dynamic_ptr_cast<AbstractVVVVertexPtr>(outV[1].at(inter));
     }
   }
 }
 
 void FFVDecayer::persistentOutput(PersistentOStream & os) const {
   os << vertex_           << perturbativeVertex_
      << incomingVertex_   << outgoingVertexF_
      << outgoingVertexV_;
 }
 
 void FFVDecayer::persistentInput(PersistentIStream & is, int) {
   is >> vertex_           >> perturbativeVertex_
      >> incomingVertex_   >> outgoingVertexF_
      >> outgoingVertexV_;
 }
 
 double FFVDecayer::me2(const int , const Particle & inpart,
 		       const ParticleVector & decay, 
 		       MEOption meopt) const {
   if(!ME())
     ME(new_ptr(GeneralDecayMatrixElement(PDT::Spin1Half,PDT::Spin1Half,PDT::Spin1)));
   // type of process
   int itype[2];
   if(inpart.dataPtr()->CC())    itype[0] = inpart.id() > 0 ? 0 : 1;
   else                          itype[0] = 2;
   if(decay[0]->dataPtr()->CC()) itype[1] = decay[0]->id() > 0 ? 0 : 1;
   else                          itype[1] = 2;  
   //Need to use different barred or unbarred spinors depending on 
   //whether particle is cc or not.
   bool ferm(itype[0] == 0 || itype[1] == 0 || (itype[0] == 2 && itype[1] == 2));
   if(meopt==Initialize) {
     // spinors and rho
     if(ferm) {
       SpinorWaveFunction   ::calculateWaveFunctions(wave_,rho_,
 						    const_ptr_cast<tPPtr>(&inpart),
 						    incoming);
       if(wave_[0].wave().Type() != SpinorType::u)
 	for(unsigned int ix = 0; ix < 2; ++ix) wave_   [ix].conjugate();
     }
     else {
       SpinorBarWaveFunction::calculateWaveFunctions(wavebar_,rho_,
 						    const_ptr_cast<tPPtr>(&inpart),
 						    incoming);
       if(wavebar_[0].wave().Type() != SpinorType::v)
 	for(unsigned int ix = 0; ix < 2; ++ix) wavebar_[ix].conjugate();
     }
+    // fix rho if no correlations
+    fixRho(rho_);
   }
   // setup spin info when needed
   if(meopt==Terminate) {
     // for the decaying particle
     if(ferm) {
       SpinorWaveFunction::
 	constructSpinInfo(wave_,const_ptr_cast<tPPtr>(&inpart),incoming,true);
       SpinorBarWaveFunction::constructSpinInfo(wavebar_,decay[0],outgoing,true);
     }
     else {
       SpinorBarWaveFunction::
 	constructSpinInfo(wavebar_,const_ptr_cast<tPPtr>(&inpart),incoming,true);
       SpinorWaveFunction::constructSpinInfo(wave_,decay[0],outgoing,true);
     }
     VectorWaveFunction::
       constructSpinInfo(vector_,decay[1],outgoing,true,false);
   }
   Energy2 scale(sqr(inpart.mass()));
   if(ferm)
     SpinorBarWaveFunction::
       calculateWaveFunctions(wavebar_,decay[0],outgoing);
   else
     SpinorWaveFunction::
       calculateWaveFunctions(wave_   ,decay[0],outgoing);
   bool massless = decay[1]->dataPtr()->mass()==ZERO;
   VectorWaveFunction::
     calculateWaveFunctions(vector_,decay[1],outgoing,massless);
   for(unsigned int if1 = 0; if1 < 2; ++if1) {
     for(unsigned int if2 = 0; if2 < 2; ++if2) {
       for(unsigned int vhel = 0; vhel < 3; ++vhel) {
 	if(massless && vhel == 1) ++vhel;
 	if(ferm)
 	  (*ME())(if1, if2,vhel) = 0.;
 	else
 	  (*ME())(if2, if1, vhel) = 0.;
 	for(auto vertex : vertex_) {
 	  if(ferm)
 	    (*ME())(if1, if2,vhel) += 
 	      vertex->evaluate(scale,wave_[if1],wavebar_[if2],vector_[vhel]);
 	  else
 	    (*ME())(if2, if1, vhel) += 
 	      vertex->evaluate(scale,wave_[if1],wavebar_[if2],vector_[vhel]);
 	}
       }
     }
   }
   double output=(ME()->contract(rho_)).real()/scale*UnitRemoval::E2;
   // colour and identical particle factors
   output *= colourFactor(inpart.dataPtr(),decay[0]->dataPtr(),decay[1]->dataPtr());
   // return the answer
   return output;
 }
 
 Energy FFVDecayer::partialWidth(PMPair inpart, PMPair outa, 
 				PMPair outb) const {
   if( inpart.second < outa.second + outb.second  ) return ZERO;
   if(perturbativeVertex_.size()==1 &&
      perturbativeVertex_[0]) {
     double mu1(outa.second/inpart.second),mu2(outb.second/inpart.second);
     tcPDPtr in = inpart.first->CC() ? tcPDPtr(inpart.first->CC()) : inpart.first;
     if( outa.first->iSpin() == PDT::Spin1Half)
       perturbativeVertex_[0]->setCoupling(sqr(inpart.second), in,
 				       outa.first, outb.first);
     else {
       swap(mu1,mu2);
       perturbativeVertex_[0]->setCoupling(sqr(inpart.second),in,
 				       outb.first,outa.first);
     }
     Complex cl(perturbativeVertex_[0]->left()),cr(perturbativeVertex_[0]->right());
     double me2(0.);
     if( mu2 > 0. ) {
       me2 = (norm(cl) + norm(cr))*(1. + sqr(mu1*mu2) + sqr(mu2) 
 				   - 2.*sqr(mu1) - 2.*sqr(mu2*mu2) 
 				   +  sqr(mu1*mu1))
 	- 6.*mu1*sqr(mu2)*(conj(cl)*cr + conj(cr)*cl).real();
       me2 /= sqr(mu2);
     }
     else
       me2 = 2.*( (norm(cl) + norm(cr))*(sqr(mu1) + 1.) 
 		 - 4.*mu1*(conj(cl)*cr + conj(cr)*cl).real() );
     Energy pcm = Kinematics::pstarTwoBodyDecay(inpart.second, outa.second,
 					outb.second);
     Energy output = norm(perturbativeVertex_[0]->norm())*me2*pcm/16./Constants::pi; 
     // colour factor
     output *= colourFactor(inpart.first,outa.first,outb.first);
     // return the answer 
     return output;
   }
   else {
     return GeneralTwoBodyDecayer::partialWidth(inpart,outa,outb);
   }
 }
 
 // The following static variable is needed for the type
 // description system in ThePEG.
 DescribeClass<FFVDecayer,GeneralTwoBodyDecayer>
 describeHerwigFFVDecayer("Herwig::FFVDecayer", "Herwig.so");
 
 void FFVDecayer::Init() {
 
   static ClassDocumentation<FFVDecayer> documentation
     ("The FFVDecayer class implements the decay of a fermion to a fermion and a vector boson");
 
 }
 
 double  FFVDecayer::threeBodyME(const int , const Particle & inpart,
 				const ParticleVector & decay,
 				ShowerInteraction inter, MEOption meopt) {
 
   int iferm (0), ivect (1), iglu (2);
   // get location of outgoing lepton/vector
   if(decay[1]->dataPtr()->iSpin()==PDT::Spin1Half) swap(iferm,ivect);
   // work out whether inpart is a fermion or antifermion
   int itype[2];
   if(inpart.dataPtr()->CC())        itype[0] = inpart.id() > 0 ? 0 : 1;
   else                              itype[0] = 2;
   if(decay[iferm]->dataPtr()->CC()) itype[1] = decay[iferm]->id() > 0 ? 0 : 1;
   else                              itype[1] = 2;
 
   bool ferm(itype[0] == 0 || itype[1] == 0 || 
 	   (itype[0] == 2 && itype[1] == 2 && decay[ivect]->id() < 0));  
 
   // no emissions from massive vectors
   bool massless = decay[ivect]->dataPtr()->mass()==ZERO;
 
   if(meopt==Initialize) {
     // create spinor (bar) for decaying particle
     if(ferm) {
       SpinorWaveFunction::calculateWaveFunctions(wave3_, rho3_, const_ptr_cast<tPPtr>(&inpart), 
 						 incoming);
       if(wave3_[0].wave().Type() != SpinorType::u)
    	for(unsigned int ix = 0; ix < 2; ++ix) wave3_[ix].conjugate();
     }
     else {
       SpinorBarWaveFunction::calculateWaveFunctions(wavebar3_,rho3_, const_ptr_cast<tPPtr>(&inpart), 
 						    incoming);
       if(wavebar3_[0].wave().Type() != SpinorType::v)
    	for(unsigned int ix = 0; ix < 2; ++ix) wavebar3_[ix].conjugate();
     }
   }
   // setup spin information when needed 
   if(meopt==Terminate) {
     if(ferm) {
       SpinorWaveFunction::
 	constructSpinInfo(wave3_,const_ptr_cast<tPPtr>(&inpart),incoming,true);
       SpinorBarWaveFunction::constructSpinInfo(wavebar3_,decay[iferm],outgoing,true);
     }
     else {
       SpinorBarWaveFunction::
 	constructSpinInfo(wavebar3_,const_ptr_cast<tPPtr>(&inpart),incoming,true);
       SpinorWaveFunction::constructSpinInfo(wave3_,decay[iferm],outgoing,true);
     }
     VectorWaveFunction::constructSpinInfo(vector3_, decay[ivect],outgoing,true,massless);
     VectorWaveFunction::constructSpinInfo(gluon_,   decay[iglu ],outgoing,true,false);
     return 0.;
   }
 
   // calulate colour factors and number of colour flows
   unsigned int nflow;
   vector<DVector> cfactors = getColourFactors(inpart, decay, nflow);
 
   vector<GeneralDecayMEPtr> ME(nflow,new_ptr(GeneralDecayMatrixElement(PDT::Spin1Half, PDT::Spin1Half,
 								       PDT::Spin1,     PDT::Spin1)));
 
   // create wavefunctions
   if (ferm)  SpinorBarWaveFunction::calculateWaveFunctions(wavebar3_, decay[iferm],outgoing);
   else       SpinorWaveFunction::   calculateWaveFunctions(wave3_   , decay[iferm],outgoing);
   
   VectorWaveFunction::calculateWaveFunctions(vector3_, decay[ivect],outgoing,massless);
   VectorWaveFunction::calculateWaveFunctions(gluon_,   decay[iglu ],outgoing,true );
 
   // gauge invariance test
 #ifdef GAUGE_CHECK
   gluon_.clear();
   for(unsigned int ix=0;ix<3;++ix) {
     if(ix==1) gluon_.push_back(VectorWaveFunction());
     else {
       gluon_.push_back(VectorWaveFunction(decay[iglu ]->momentum(),
   					  decay[iglu ]->dataPtr(),10,
   					  outgoing));
     }
   }
 #endif
 
   if (! ((incomingVertex_[inter]  && (outgoingVertexF_[inter]  || outgoingVertexV_[inter])) ||
 	 (outgoingVertexF_[inter] &&  outgoingVertexV_[inter])))
     throw Exception()
       << "Invalid vertices for QCD radiation in FFV decay in FFVDecayer::threeBodyME"
       << Exception::runerror;
 
 
   // sort out colour flows
   int F(1), V(2);
   if (decay[iferm]->dataPtr()->iColour()==PDT::Colour3bar && 
       decay[ivect]->dataPtr()->iColour()==PDT::Colour8)
     swap(F,V);
   else if (decay[ivect]->dataPtr()->iColour()==PDT::Colour3 && 
 	   decay[iferm]->dataPtr()->iColour()==PDT::Colour8)
     swap(F,V);
 
   Complex diag;
   Energy2 scale(sqr(inpart.mass()));
 
   const GeneralTwoBodyDecayer::CFlow & colourFlow = colourFlows(inpart, decay);
   double gs(0.);
   bool couplingSet(false);
 #ifdef GAUGE_CHECK
   double total=0.;
 #endif
   for(unsigned int ifi = 0; ifi < 2; ++ifi) {
     for(unsigned int ifo = 0; ifo < 2; ++ifo) {
       for(unsigned int iv = 0; iv < 3; ++iv) {
 	for(unsigned int ig = 0; ig < 2; ++ig) {
 	  // radiation from the incoming fermion
 	  if((inpart.dataPtr()->coloured() && inter==ShowerInteraction::QCD) ||
 	     (inpart.dataPtr()->charged()  && inter==ShowerInteraction::QED) ) {
 	    assert(incomingVertex_[inter]);
 	    if (ferm){
 	      SpinorWaveFunction spinorInter =
 		incomingVertex_[inter]->evaluate(scale,3,inpart.dataPtr(),wave3_[ifi],
 						  gluon_[2*ig],inpart.mass());
 	      
 	      assert(wave3_[ifi].particle()->id()==spinorInter.particle()->id());
 	      diag = 0.;
 	      for(auto vertex : vertex_)
 		diag += vertex->evaluate(scale,spinorInter,wavebar3_[ifo],vector3_[iv]);
 	    }
 	    else {
 	      SpinorBarWaveFunction spinorBarInter = 
 		incomingVertex_[inter]->evaluate(scale,3,inpart.dataPtr(),wavebar3_[ifi],
 						  gluon_[2*ig],inpart.mass());
 	      
 	      assert(wavebar3_[ifi].particle()->id()==spinorBarInter.particle()->id());
 	      diag = 0.;
 	      for(auto vertex : vertex_)
 		diag += vertex->evaluate(scale,wave3_[ifo], spinorBarInter,vector3_[iv]);
 	    }
 	    if(!couplingSet) {
 	      gs = abs(incomingVertex_[inter]->norm());
 	      couplingSet = true;
 	    }
 	    for(unsigned int ix=0;ix<colourFlow[0].size();++ix) {
 	      (*ME[colourFlow[0][ix].first])(ifi, ifo, iv, ig) += 
 		colourFlow[0][ix].second*diag;
 	    }
 #ifdef GAUGE_CHECK
 	    total+=norm(diag);
 #endif
 	  }
 	  // radiation from outgoing fermion
 	  if((decay[iferm]->dataPtr()->coloured() && inter==ShowerInteraction::QCD) ||
 	     (decay[iferm]->dataPtr()->charged()  && inter==ShowerInteraction::QED) ) {
 	    assert(outgoingVertexF_[inter]);
 	    // ensure you get correct outgoing particle from first vertex
 	    tcPDPtr off = decay[iferm]->dataPtr();
 	    if(off->CC()) off = off->CC(); 
 	    if (ferm) {	    
 	      SpinorBarWaveFunction spinorBarInter = 
 		outgoingVertexF_[inter]->evaluate(scale,3,off,wavebar3_[ifo],
 						  gluon_[2*ig],decay[iferm]->mass());
 	      
 	      assert(wavebar3_[ifo].particle()->id()==spinorBarInter.particle()->id());
 	      diag = 0.;
 	      for(auto vertex : vertex_)
 		diag += vertex->evaluate(scale,wave3_[ifi],spinorBarInter,vector3_[iv]);
 	    }
 	    else {
 	      SpinorWaveFunction spinorInter = 
 		outgoingVertexF_[inter]->evaluate(scale,3,off,wave3_[ifo],
 						  gluon_[2*ig],decay[iferm]->mass());
 		
 	      assert(wave3_[ifo].particle()->id()==spinorInter.particle()->id());
 	      
 	      diag = 0.;
 	      for(auto vertex : vertex_)
 		diag += vertex->evaluate(scale,spinorInter,wavebar3_[ifi],vector3_[iv]);
 	    }
 	    if(!couplingSet) {
 	      gs = abs(outgoingVertexF_[inter]->norm());
 	      couplingSet = true;
 	    }
 	    for(unsigned int ix=0;ix<colourFlow[F].size();++ix) {
 	      (*ME[colourFlow[F][ix].first])(ifi, ifo, iv, ig) += 
 		 colourFlow[F][ix].second*diag;
 	    }
 #ifdef GAUGE_CHECK
 	    total+=norm(diag);
 #endif
 	  }
 	  
 	  // radiation from outgoing vector
 	  if((decay[ivect]->dataPtr()->coloured() && inter==ShowerInteraction::QCD) ||
 	     (decay[ivect]->dataPtr()->charged()  && inter==ShowerInteraction::QED) ) {
 	    assert(outgoingVertexV_[inter]);
 	    // ensure you get correct ougoing particle from first vertex
 	    tcPDPtr off = decay[ivect]->dataPtr();
 	    if(off->CC()) off = off->CC();
 	    VectorWaveFunction  vectorInter = 
 	      outgoingVertexV_[inter]->evaluate(scale,3,off,gluon_[2*ig],
 						vector3_[iv],decay[ivect]->mass());
 	    
 	    assert(vector3_[iv].particle()->id()==vectorInter.particle()->id());
 	    if (ferm) {
 	      diag = 0.;
 	      for(auto vertex : vertex_)
 		diag += vertex->evaluate(scale,wave3_[ifi],wavebar3_[ifo],vectorInter);
 	    }
 	    else {
 	      diag = 0.;
 	      for(auto vertex : vertex_)
 		diag += vertex->evaluate(scale,wave3_[ifo],wavebar3_[ifi],vectorInter);
 	    }
 	    if(!couplingSet) {
 	      gs = abs(outgoingVertexV_[inter]->norm());
 	      couplingSet = true;
 	    }
 	    for(unsigned int ix=0;ix<colourFlow[V].size();++ix) {
 	      (*ME[colourFlow[V][ix].first])(ifi, ifo, iv, ig) += 
 		colourFlow[V][ix].second*diag;
 	    }
 #ifdef GAUGE_CHECK
 	    total+=norm(diag);
 #endif
 	  }
 	}
 	if(massless) ++iv;
       }
     }
   }
 
   // contract matrices
   double output=0.;
   for(unsigned int ix=0; ix<nflow; ++ix){
     for(unsigned int iy=0; iy<nflow; ++iy){
       output+=cfactors[ix][iy]*(ME[ix]->contract(*ME[iy],rho3_)).real();
     }
   }
   // divide by alpha(S,eM)
   output *= (4.*Constants::pi)/sqr(gs);
 #ifdef GAUGE_CHECK
   double ratio = output/total;
   if(abs(ratio)>1e-20) {
     generator()->log() << "Test of gauge invariance in decay\n" << inpart << "\n";
     for(unsigned int ix=0;ix<decay.size();++ix)
       generator()->log() << *decay[ix] << "\n";
     generator()->log() << "Test of gauge invariance " << ratio << "\n";
   }
 #endif
   // return the answer
   return output;
 }
diff --git a/Decay/General/FRSDecayer.cc b/Decay/General/FRSDecayer.cc
--- a/Decay/General/FRSDecayer.cc
+++ b/Decay/General/FRSDecayer.cc
@@ -1,189 +1,191 @@
 // -*- C++ -*-
 //
 // FRSDecayer.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 FRSDecayer class.
 //
 
 #include "FRSDecayer.h"
 #include "ThePEG/Utilities/DescribeClass.h"
 #include "ThePEG/Interface/ClassDocumentation.h"
 #include "ThePEG/Persistency/PersistentOStream.h"
 #include "ThePEG/Persistency/PersistentIStream.h"
 #include "ThePEG/PDT/DecayMode.h"
 #include "ThePEG/Helicity/WaveFunction/ScalarWaveFunction.h"
 #include "ThePEG/Helicity/WaveFunction/SpinorWaveFunction.h"
 #include "ThePEG/Helicity/WaveFunction/SpinorBarWaveFunction.h"
 #include "Herwig/Utilities/Kinematics.h"
 #include "Herwig/Decay/GeneralDecayMatrixElement.h"
 
 using namespace Herwig;
 using namespace ThePEG::Helicity;
 
 IBPtr FRSDecayer::clone() const {
   return new_ptr(*this);
 }
 
 IBPtr FRSDecayer::fullclone() const {
   return new_ptr(*this);
 }
 
 void FRSDecayer::setDecayInfo(PDPtr incoming, PDPair outgoing,
 			      vector<VertexBasePtr> vertex,
 			      map<ShowerInteraction,VertexBasePtr> &,
 			      const vector<map<ShowerInteraction,VertexBasePtr> > &,
 			      map<ShowerInteraction,VertexBasePtr>) {
   decayInfo(incoming,outgoing);
   for(auto vert : vertex) {
     vertex_            .push_back(dynamic_ptr_cast<AbstractRFSVertexPtr>(vert));
     perturbativeVertex_.push_back(dynamic_ptr_cast<RFSVertexPtr>        (vert));
   }
 }
 
 void FRSDecayer::persistentOutput(PersistentOStream & os) const {
   os << perturbativeVertex_ << vertex_;
 }
 
 void FRSDecayer::persistentInput(PersistentIStream & is, int) {
   is >> perturbativeVertex_ >> vertex_;
 }
 
 // The following static variable is needed for the type
 // description system in ThePEG.
 DescribeClass<FRSDecayer,GeneralTwoBodyDecayer>
 describeHerwigFRSDecayer("Herwig::FRSDecayer", "Herwig.so");
 
 void FRSDecayer::Init() {
 
   static ClassDocumentation<FRSDecayer> documentation
     ("The FRSDecayer class implements the decay of a fermion to "
      "a spin-3/2 fermion and a scalar.");
 
 }
 
 double FRSDecayer::me2(const int , const Particle & inpart,
 		       const ParticleVector & decay,
 		       MEOption meopt) const {
   bool ferm = inpart.id() > 0;
   if(!ME())
     ME(new_ptr(GeneralDecayMatrixElement(PDT::Spin1Half,PDT::Spin3Half,PDT::Spin0)));
   if(meopt==Initialize) {
     // spinors and rho
     if(ferm) {
       SpinorWaveFunction   ::calculateWaveFunctions(wave_,rho_,
 						    const_ptr_cast<tPPtr>(&inpart),
 						    incoming);
       if(wave_[0].wave().Type() != SpinorType::u)
 	for(unsigned int ix = 0; ix < 2; ++ix) wave_   [ix].conjugate();
     }
     else {
       SpinorBarWaveFunction::calculateWaveFunctions(wavebar_,rho_,
 						    const_ptr_cast<tPPtr>(&inpart),
 						    incoming);
       if(wavebar_[0].wave().Type() != SpinorType::v)
 	for(unsigned int ix = 0; ix < 2; ++ix) wavebar_[ix].conjugate();
     }
+    // fix rho if no correlations
+    fixRho(rho_);
   }
   // setup spin info when needed
   if(meopt==Terminate) {
     // for the decaying particle
     if(ferm) {
       SpinorWaveFunction::
 	constructSpinInfo(wave_,const_ptr_cast<tPPtr>(&inpart),incoming,true);
       RSSpinorBarWaveFunction::constructSpinInfo(RSwavebar_,decay[0],outgoing,true);
     }
     else {
       SpinorBarWaveFunction::
 	constructSpinInfo(wavebar_,const_ptr_cast<tPPtr>(&inpart),incoming,true);
       RSSpinorWaveFunction::constructSpinInfo(RSwave_,decay[0],outgoing,true);
     }
     ScalarWaveFunction::constructSpinInfo(decay[1],outgoing,true);
   }
   if(ferm)
     RSSpinorBarWaveFunction::
       calculateWaveFunctions(RSwavebar_,decay[0],outgoing);
   else
     RSSpinorWaveFunction::
       calculateWaveFunctions(RSwave_   ,decay[0],outgoing);
   ScalarWaveFunction scal(decay[1]->momentum(),decay[1]->dataPtr(),outgoing);
   Energy2 scale(sqr(inpart.mass()));
   for(unsigned int if1 = 0; if1 < 2; ++if1) {
     for(unsigned int if2 = 0; if2 < 4; ++if2) {
       (*ME())(if1, if2, 0) = 0.;
       for(auto vert : vertex_) {
 	if(ferm) (*ME())(if1, if2, 0) +=
 		   vert->evaluate(scale,wave_[if1],RSwavebar_[if2],scal);
 	else     (*ME())(if1, if2, 0) += 
 		   vert->evaluate(scale,RSwave_[if2],wavebar_[if1],scal);
       }
     }
   }
   double output = (ME()->contract(rho_)).real()/scale*UnitRemoval::E2;
   // colour and identical particle factors
   output *= colourFactor(inpart.dataPtr(),decay[0]->dataPtr(),
 			 decay[1]->dataPtr());
   // test code
 //   Energy q = inpart.mass();
 //   Energy m1 = decay[0]->mass();
 //   Energy m2 = decay[1]->mass();
 //   Energy2 q2(q*q),m12(m1*m1),m22(m2*m2);
 //   Energy2 pcm2(0.25*(q2*(q2-2.*m12-2.*m22)+(m12-m22)*(m12-m22))/q2);
 //   Energy pcm(sqrt(pcm2));
 //   Energy Qp(sqrt((q+m1)*(q+m1)-m22)),Qm(sqrt((q-m1)*(q-m1)-m22));
 //   double r23(sqrt(2./3.));
 //   // couplings
 //   Complex left  = perturbativeVertex_-> left()*perturbativeVertex_-> norm();
 //   Complex right = perturbativeVertex_->right()*perturbativeVertex_-> norm();
 //   complex<InvEnergy> A1 = 0.5*(left+right)*UnitRemoval::InvE;
 //   complex<InvEnergy> B1 = 0.5*(right-left)*UnitRemoval::InvE;
 //   complex<Energy> h1(-2.*r23*pcm*q/m1*Qm*B1);
 //   complex<Energy> h2( 2.*r23*pcm*q/m1*Qp*A1);
 //   cout << "testing 1/2->3/2 0 "
 //        << output*scale/GeV2 << "   " 
 //        << real(h1*conj(h1)+h2*conj(h2))/4./GeV2     << "   " 
 //        << real(h1*conj(h1)+h2*conj(h2))/4./(output*scale) << endl;
   // return the answer
   return output;
 }
 
 Energy FRSDecayer::partialWidth(PMPair inpart, PMPair outa,
 				PMPair outb) const {
   if( inpart.second < outa.second + outb.second  ) return ZERO;
   if(perturbativeVertex_.size()==1 &&
      perturbativeVertex_[0]) {
     Energy q = inpart.second;
     Energy m1 = outa.second;
     Energy m2 = outb.second;
     Energy2 q2(q*q),m12(m1*m1),m22(m2*m2);
     Energy2 pcm2(0.25*(q2*(q2-2.*m12-2.*m22)+(m12-m22)*(m12-m22))/q2);
     Energy pcm(sqrt(pcm2));
     Energy Qp(sqrt((q+m1)*(q+m1)-m22)),Qm(sqrt((q-m1)*(q-m1)-m22));
     double r23(sqrt(2./3.));
     // couplings
     tcPDPtr in = inpart.first->CC() ? tcPDPtr(inpart.first->CC()) : inpart.first;
     perturbativeVertex_[0]->setCoupling(sqr(inpart.second), outa.first, 
 				     in,  outb.first);
     Complex left  = perturbativeVertex_[0]-> left()*perturbativeVertex_[0]-> norm();
     Complex right = perturbativeVertex_[0]->right()*perturbativeVertex_[0]-> norm();
     complex<InvEnergy> A1 = 0.5*(left+right)*UnitRemoval::InvE;
     complex<InvEnergy> B1 = 0.5*(right-left)*UnitRemoval::InvE;
     complex<Energy> h1(-2.*r23*pcm*q/m1*Qm*B1);
     complex<Energy> h2( 2.*r23*pcm*q/m1*Qp*A1);
     double me2 = real(h1*conj(h1)+h2*conj(h2))/4./sqr(inpart.second);
     Energy output = me2*pcm/8./Constants::pi;
     // colour factor
     output *= colourFactor(inpart.first,outa.first,outb.first);
     // return the answer
     return output;
   }
   else {
     return GeneralTwoBodyDecayer::partialWidth(inpart,outa,outb);
   }
 }
 
diff --git a/Decay/General/FRVDecayer.cc b/Decay/General/FRVDecayer.cc
--- a/Decay/General/FRVDecayer.cc
+++ b/Decay/General/FRVDecayer.cc
@@ -1,219 +1,221 @@
 // -*- C++ -*-
 //
 // FRVDecayer.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 FRVDecayer class.
 //
 
 #include "FRVDecayer.h"
 #include "ThePEG/Utilities/DescribeClass.h"
 #include "ThePEG/Interface/ClassDocumentation.h"
 #include "ThePEG/Persistency/PersistentOStream.h"
 #include "ThePEG/Persistency/PersistentIStream.h"
 #include "ThePEG/PDT/DecayMode.h"
 #include "ThePEG/Helicity/WaveFunction/VectorWaveFunction.h"
 #include "ThePEG/Helicity/WaveFunction/SpinorWaveFunction.h"
 #include "ThePEG/Helicity/WaveFunction/SpinorBarWaveFunction.h"
 #include "Herwig/Utilities/Kinematics.h"
 #include "Herwig/Decay/GeneralDecayMatrixElement.h"
 
 using namespace Herwig;
 using namespace ThePEG::Helicity;
 
 IBPtr FRVDecayer::clone() const {
   return new_ptr(*this);
 }
 
 IBPtr FRVDecayer::fullclone() const {
   return new_ptr(*this);
 }
 
 void FRVDecayer::setDecayInfo(PDPtr incoming, PDPair outgoing,
 			      vector<VertexBasePtr> vertex,
 			      map<ShowerInteraction,VertexBasePtr> &,
 			      const vector<map<ShowerInteraction,VertexBasePtr> > &,
 			      map<ShowerInteraction,VertexBasePtr>) {
   decayInfo(incoming,outgoing);
   for(auto vert : vertex) {
     vertex_            .push_back(dynamic_ptr_cast<AbstractRFVVertexPtr>(vert));
     perturbativeVertex_.push_back(dynamic_ptr_cast<RFVVertexPtr>        (vert));
   }
 }
 
 void FRVDecayer::persistentOutput(PersistentOStream & os) const {
   os << vertex_ << perturbativeVertex_;
 }
 
 void FRVDecayer::persistentInput(PersistentIStream & is, int) {
   is >> vertex_ >> perturbativeVertex_;
 }
 
 double FRVDecayer::me2(const int , const Particle & inpart,
 		       const ParticleVector & decay, 
 		       MEOption meopt) const {
   if(!ME())
     ME(new_ptr(GeneralDecayMatrixElement(PDT::Spin1Half,PDT::Spin3Half,PDT::Spin1)));
   // decaying fermion or antifermion
   bool ferm = inpart.id() > 0;
   // initialize
   if(meopt==Initialize) {
     // spinors and rho
     if(ferm) {
       SpinorWaveFunction   ::calculateWaveFunctions(wave_,rho_,
 						    const_ptr_cast<tPPtr>(&inpart),
 						    incoming);
       if(wave_[0].wave().Type() != SpinorType::u)
 	for(unsigned int ix = 0; ix < 2; ++ix) wave_   [ix].conjugate();
     }
     else {
       SpinorBarWaveFunction::calculateWaveFunctions(wavebar_,rho_,
 						    const_ptr_cast<tPPtr>(&inpart),
 						    incoming);
       if(wavebar_[0].wave().Type() != SpinorType::v)
 	for(unsigned int ix = 0; ix < 2; ++ix) wavebar_[ix].conjugate();
     }
+    // fix rho if no correlations
+    fixRho(rho_);
   }
   // setup spin info when needed
   if(meopt==Terminate) {
     // for the decaying particle
     if(ferm) {
       SpinorWaveFunction::
 	constructSpinInfo(wave_,const_ptr_cast<tPPtr>(&inpart),incoming,true);
       RSSpinorBarWaveFunction::constructSpinInfo(RSwavebar_,decay[0],outgoing,true);
     }
     else {
       SpinorBarWaveFunction::
 	constructSpinInfo(wavebar_,const_ptr_cast<tPPtr>(&inpart),incoming,true);
       RSSpinorWaveFunction::constructSpinInfo(RSwave_,decay[0],outgoing,true);
     }
     VectorWaveFunction::
       constructSpinInfo(vector_,decay[1],outgoing,true,false);
   }
   Energy2 scale(sqr(inpart.mass()));
   if(ferm)
     RSSpinorBarWaveFunction::
       calculateWaveFunctions(RSwavebar_,decay[0],outgoing);
   else
     RSSpinorWaveFunction::
       calculateWaveFunctions(RSwave_   ,decay[0],outgoing);
   bool massless = decay[1]->dataPtr()->mass()==ZERO;
   VectorWaveFunction::
     calculateWaveFunctions(vector_,decay[1],outgoing,massless);
   // loop over helicities
   for(unsigned int if1 = 0; if1 < 2; ++if1) {
     for(unsigned int if2 = 0; if2 < 4; ++if2) {
       for(unsigned int vhel = 0; vhel < 3; ++vhel) {
 	if(massless && vhel == 1) ++vhel;
 	(*ME())(if1, if2,vhel) = 0.;
 	for(auto vert : vertex_) {
 	  if(ferm)
 	    (*ME())(if1, if2,vhel) += 
 	      vert->evaluate(scale,wave_[if1],
 			     RSwavebar_[if2],vector_[vhel]);
 	  else
 	    (*ME())(if1, if2, vhel) += 
 	      vert->evaluate(scale,RSwave_[if2],
 			     wavebar_[if1],vector_[vhel]);
 	}
       }
     }
   }
   double output=(ME()->contract(rho_)).real()/scale*UnitRemoval::E2;
   // test
 //   Energy m1(inpart.mass()),m2(decay[0]->mass()),m3(decay[1]->mass());
 //   Energy2 m12(m1*m1),m22(m2*m2),m32(m3*m3);
 //   Energy Qp(sqrt(sqr(m1+m2)-sqr(m3))),Qm(sqrt(sqr(m1-m2)-sqr(m3)));
 //   double r2(sqrt(2.)),r3(sqrt(3.));
 //   Energy pcm(Kinematics::pstarTwoBodyDecay(m1,m2,m3));
 //   vector<Complex> left  = perturbativeVertex_-> left();
 //   vector<Complex> right = perturbativeVertex_->right();
 //   Complex A1 = 0.5*(left [0]+right[0])*perturbativeVertex_-> norm();
 //   Complex B1 = 0.5*(right[0]- left[0])*perturbativeVertex_-> norm();
 //   complex<InvEnergy> A2 = 0.5*(left [1]+right[1])*perturbativeVertex_-> norm()*UnitRemoval::InvE;
 //   complex<InvEnergy> B2 = 0.5*(right[1]- left[1])*perturbativeVertex_-> norm()*UnitRemoval::InvE;
 //   complex<InvEnergy2> A3 = 0.5*(left [2]+right[2])*perturbativeVertex_-> norm()*UnitRemoval::InvE2;
 //   complex<InvEnergy2> B3 = 0.5*(right[2]- left[2])*perturbativeVertex_-> norm()*UnitRemoval::InvE2;
 //   complex<Energy> h1(-2.*Qp*A1),h2(2.*Qm*B1);
 //   complex<Energy> h3(-2./r3*Qp*(A1-Qm*Qm/m2*A2));
 //   complex<Energy> h4( 2./r3*Qm*(B1-Qp*Qp/m2*B2));
 //   complex<Energy> h5(ZERO),h6(ZERO);
 //   if(decay[1]->mass()>ZERO) {
 //     h5 = -2.*r2/r3/m2/m3*Qp*(0.5*(m12-m22-m32)*A1+0.5*Qm*Qm*(m1+m2)*A2
 //     			   +m12*pcm*pcm*A3);
 //     h6 =  2.*r2/r3/m2/m3*Qm*(0.5*(m12-m22-m32)*B1-0.5*Qp*Qp*(m1-m2)*B2
 // 					   +m12*pcm*pcm*B3);
 //   }
 //   cout << "testing 1/2->3/2 1 " << inpart.id() << " "
 //        << output << "   " 
 //        << 0.25*(h1*conj(h1)+h2*conj(h2)+h3*conj(h3)+
 // 		h4*conj(h4)+h5*conj(h5)+h6*conj(h6))/sqr(inpart.mass()) << "   " 
 //        << 0.25*(h1*conj(h1)+h2*conj(h2)+h3*conj(h3)+
 // 		h4*conj(h4)+h5*conj(h5)+h6*conj(h6))/sqr(inpart.mass())/output << endl;
   // colour and identical particle factors
   output *= colourFactor(inpart.dataPtr(),decay[0]->dataPtr(),decay[1]->dataPtr());
   // return the answer
   return output;
 }
 
 Energy FRVDecayer::partialWidth(PMPair inpart, PMPair outa, 
 				PMPair outb) const {
   if( inpart.second < outa.second + outb.second  ) return ZERO;
   if(perturbativeVertex_.size()==1 &&
      perturbativeVertex_[0]) {
     Energy m1(inpart.second),m2(outa.second),m3(outb.second);
     Energy2 m12(m1*m1),m22(m2*m2),m32(m3*m3);
     Energy Qp(sqrt(sqr(m1+m2)-sqr(m3))),Qm(sqrt(sqr(m1-m2)-sqr(m3)));
     double r2(sqrt(2.)),r3(sqrt(3.));
     Energy pcm(Kinematics::pstarTwoBodyDecay(m1,m2,m3));
     // couplings
     tcPDPtr in = inpart.first->CC() ? tcPDPtr(inpart.first->CC()) : inpart.first;
     perturbativeVertex_[0]->setCoupling(sqr(inpart.second), outa.first, 
 				     in,  outb.first);
     vector<Complex> left  = perturbativeVertex_[0]-> left();
     vector<Complex> right = perturbativeVertex_[0]->right();
     Complex A1 = 0.5*(left [0]+right[0])*perturbativeVertex_[0]-> norm();
     Complex B1 = 0.5*(right[0]- left[0])*perturbativeVertex_[0]-> norm();
     complex<InvEnergy> A2 = 0.5*(left [1]+right[1])*perturbativeVertex_[0]-> norm()*UnitRemoval::InvE;
     complex<InvEnergy> B2 = 0.5*(right[1]- left[1])*perturbativeVertex_[0]-> norm()*UnitRemoval::InvE;
     complex<InvEnergy2> A3 = 0.5*(left [2]+right[2])*perturbativeVertex_[0]-> norm()*UnitRemoval::InvE2;
     complex<InvEnergy2> B3 = 0.5*(right[2]- left[2])*perturbativeVertex_[0]-> norm()*UnitRemoval::InvE2;
     complex<Energy> h1(-2.*Qp*A1),h2(2.*Qm*B1);
     complex<Energy> h3(-2./r3*Qp*(A1-Qm*Qm/m2*A2));
     complex<Energy> h4( 2./r3*Qm*(B1-Qp*Qp/m2*B2));
     complex<Energy> h5(ZERO),h6(ZERO);
     if(outb.second>ZERO) {
       h5 = -2.*r2/r3/m2/m3*Qp*(0.5*(m12-m22-m32)*A1+0.5*Qm*Qm*(m1+m2)*A2
 			       +m12*pcm*pcm*A3);
       h6 =  2.*r2/r3/m2/m3*Qm*(0.5*(m12-m22-m32)*B1-0.5*Qp*Qp*(m1-m2)*B2
 			       +m12*pcm*pcm*B3);
     }
     double me2 = 0.25*real(h1*conj(h1)+h2*conj(h2)+h3*conj(h3)+
 			   h4*conj(h4)+h5*conj(h5)+h6*conj(h6))/sqr(inpart.second);
     Energy output = me2*pcm/8./Constants::pi;
     // colour factor
     output *= colourFactor(inpart.first,outa.first,outb.first);
     return output;
   }
   else {
     return GeneralTwoBodyDecayer::partialWidth(inpart,outa,outb);
   }
 }
 
 // The following static variable is needed for the type
 // description system in ThePEG.
 DescribeClass<FRVDecayer,GeneralTwoBodyDecayer>
 describeHerwigFRVDecayer("Herwig::FRVDecayer", "Herwig.so");
 
 void FRVDecayer::Init() {
 
   static ClassDocumentation<FRVDecayer> documentation
     ("The FRVDecayer class handles the decay of a fermion to "
      "a spin-3/2 particle and a vector boson.");
 
 }
diff --git a/Decay/General/FtoFFFDecayer.cc b/Decay/General/FtoFFFDecayer.cc
--- a/Decay/General/FtoFFFDecayer.cc
+++ b/Decay/General/FtoFFFDecayer.cc
@@ -1,309 +1,311 @@
 // -*- C++ -*-
 //
 // This is the implementation of the non-inlined, non-templated member
 // functions of the FtoFFFDecayer class.
 //
 
 #include "FtoFFFDecayer.h"
 #include "ThePEG/Utilities/DescribeClass.h"
 #include "ThePEG/Interface/ClassDocumentation.h"
 #include "ThePEG/Persistency/PersistentOStream.h"
 #include "ThePEG/Persistency/PersistentIStream.h"
 #include "Herwig/Decay/DecayPhaseSpaceMode.h"
 #include "Herwig/PDT/ThreeBodyAllOnCalculator.h"
 #include "Herwig/Decay/GeneralDecayMatrixElement.h"
 #include <numeric>
 
 using namespace Herwig;
 
 IBPtr FtoFFFDecayer::clone() const {
   return new_ptr(*this);
 }
 
 IBPtr FtoFFFDecayer::fullclone() const {
   return new_ptr(*this);
 }
 
 void FtoFFFDecayer::persistentOutput(PersistentOStream & os) const {
   os << sca_ << vec_ << ten_;
 }
 
 void FtoFFFDecayer::persistentInput(PersistentIStream & is, int) {
   is >> sca_ >> vec_ >> ten_;
 }
 
 // The following static variable is needed for the type
 // description system in ThePEG.
 DescribeClass<FtoFFFDecayer,GeneralThreeBodyDecayer>
 describeHerwigFtoFFFDecayer("Herwig::FtoFFFDecayer", "Herwig.so");
 
 void FtoFFFDecayer::Init() {
 
   static ClassDocumentation<FtoFFFDecayer> documentation
     ("The FtoFFFDecayer class implements the general decay of a fermion to "
      "three fermions.");
 
 }
 
 void FtoFFFDecayer::doinit() {
   GeneralThreeBodyDecayer::doinit();
   if(outgoing().empty()) return;
   unsigned int ndiags = getProcessInfo().size();
   sca_.resize(ndiags);
   vec_.resize(ndiags);
   ten_.resize(ndiags);
   for(unsigned int ix = 0;ix < ndiags; ++ix) {
     TBDiagram current = getProcessInfo()[ix];
     tcPDPtr offshell = current.intermediate;
     if( offshell->CC() ) offshell = offshell->CC();
     if(offshell->iSpin() == PDT::Spin0) {
       AbstractFFSVertexPtr vert1 = dynamic_ptr_cast<AbstractFFSVertexPtr>
 	(current.vertices.first);
       AbstractFFSVertexPtr vert2 = dynamic_ptr_cast<AbstractFFSVertexPtr>
 	(current.vertices.second);
       if(!vert1||!vert2) throw Exception() 
 	<< "Invalid vertices for a scalar diagram in FtoFFFDecayer::doinit()"
 	<< Exception::runerror;
       sca_[ix] = make_pair(vert1, vert2);
     }
     else if(offshell->iSpin() == PDT::Spin1) {
       AbstractFFVVertexPtr vert1 = dynamic_ptr_cast<AbstractFFVVertexPtr>
 	(current.vertices.first);
       AbstractFFVVertexPtr vert2 = dynamic_ptr_cast<AbstractFFVVertexPtr>
 	(current.vertices.second);
       if(!vert1||!vert2) throw Exception() 
 	<< "Invalid vertices for a vector diagram in FtoFFFDecayer::doinit()"
 	<< Exception::runerror;
       vec_[ix] = make_pair(vert1, vert2);
     }
     else if(offshell->iSpin() == PDT::Spin2) {
       AbstractFFTVertexPtr vert1 = dynamic_ptr_cast<AbstractFFTVertexPtr>
 	(current.vertices.first);
       AbstractFFTVertexPtr vert2 = dynamic_ptr_cast<AbstractFFTVertexPtr>
 	(current.vertices.second);
       if(!vert1||!vert2) throw Exception() 
 	<< "Invalid vertices for a tensor diagram in FtoFFFDecayer::doinit()"
 	<< Exception::runerror;
       ten_[ix] = make_pair(vert1, vert2);
     }
   }
 }
 
 double  FtoFFFDecayer::me2(const int ichan, const Particle & inpart,
 			   const ParticleVector & decay,
 			   MEOption meopt) const {
   // particle or CC of particle
   bool cc = (*getProcessInfo().begin()).incoming != inpart.id();
   // special handling or first/last call
   const vector<vector<double> > cfactors(getColourFactors());
   const vector<vector<double> > nfactors(getLargeNcColourFactors());
   const size_t ncf(numberOfFlows());
   Energy2 scale(sqr(inpart.mass()));
   if(meopt==Initialize) {
     SpinorWaveFunction::
       calculateWaveFunctions(inwave_.first,rho_,const_ptr_cast<tPPtr>(&inpart),
 			    Helicity::incoming);
     inwave_.second.resize(2);
     if(inwave_.first[0].wave().Type() == SpinorType::u) {
       for(unsigned int ix = 0; ix < 2; ++ix) {
 	inwave_.second[ix] = inwave_.first[ix].bar();
 	inwave_.second[ix].conjugate();
       }
     }
     else {
       for(unsigned int ix = 0; ix < 2; ++ix) {
 	inwave_.second[ix] = inwave_.first[ix].bar();
 	inwave_.first[ix].conjugate();
       }
     }
+    // fix rho if no correlations
+    fixRho(rho_);
   }
   // setup spin info when needed
   if(meopt==Terminate) {
     // for the decaying particle
     if(inpart.id()<0) 
       SpinorWaveFunction::constructSpinInfo(inwave_.first,
 					    const_ptr_cast<tPPtr>(&inpart),
 					    Helicity::incoming,true);
     else
       SpinorBarWaveFunction::constructSpinInfo(inwave_.second,
 					       const_ptr_cast<tPPtr>(&inpart),
 					       Helicity::incoming,true);
     // outgoing particles
     for(unsigned int ix = 0; ix < 3; ++ix) {
       SpinorWaveFunction::
       constructSpinInfo(outwave_[ix].first,decay[ix],Helicity::outgoing,true);
     }
   }
   // outgoing particles
   for(unsigned int ix = 0; ix < 3; ++ix) {
     SpinorWaveFunction::
       calculateWaveFunctions(outwave_[ix].first,decay[ix],Helicity::outgoing);
     outwave_[ix].second.resize(2);
     if(outwave_[ix].first[0].wave().Type() == SpinorType::u) {
       for(unsigned int iy = 0; iy < 2; ++iy) {
 	outwave_[ix].second[iy] = outwave_[ix].first[iy].bar();
 	outwave_[ix].first[iy].conjugate();
       }
     }
     else {
       for(unsigned int iy = 0; iy < 2; ++iy) {
 	outwave_[ix].second[iy] = outwave_[ix].first[iy].bar();
 	outwave_[ix].second[iy].conjugate();
       }
     }
   }
   bool ferm = inpart.id()>0; 
   vector<Complex> flows(ncf, Complex(0.)),largeflows(ncf, Complex(0.)); 
   static const unsigned int out2[3]={1,0,0},out3[3]={2,2,1};
   vector<GeneralDecayMEPtr> mes(ncf,new_ptr(GeneralDecayMatrixElement(PDT::Spin1Half,PDT::Spin1Half,
 								      PDT::Spin1Half,PDT::Spin1Half)));
   vector<GeneralDecayMEPtr> mel(ncf,new_ptr(GeneralDecayMatrixElement(PDT::Spin1Half,PDT::Spin1Half,
 								      PDT::Spin1Half,PDT::Spin1Half)));
   unsigned int ihel[4];
   for(ihel[0] = 0; ihel[0] < 2; ++ihel[0]) {
     for(ihel[1] = 0; ihel[1] < 2; ++ihel[1]) {
       for(ihel[2] = 0; ihel[2] < 2; ++ihel[2]) {
 	for(ihel[3] = 0; ihel[3] < 2; ++ihel[3]) {
 	  flows = vector<Complex>(ncf, Complex(0.));
 	  largeflows = vector<Complex>(ncf, Complex(0.));
 	  unsigned int idiag=0;
 	  for(vector<TBDiagram>::const_iterator dit=getProcessInfo().begin();
 	      dit!=getProcessInfo().end();++dit) {
 	    if(ichan>=0&&diagramMap()[ichan]!=idiag) {
 	      ++idiag;
 	      continue;
 	    }
 	    // the sign from normal ordering
 	    double sign = ferm ? 1. : -1;
 	    // outgoing wavefunction and NO sign
 	    if     (dit->channelType==TBDiagram::channel23) sign *= -1.;
 	    else if(dit->channelType==TBDiagram::channel13) sign *=  1.;
 	    else if(dit->channelType==TBDiagram::channel12) sign *= -1.;
 	    else throw Exception()
 	      << "Unknown diagram type in FtoFFFDecayer::me2()" << Exception::runerror;
 	    // wavefunctions
 	    SpinorWaveFunction    w0,w3;
 	    SpinorBarWaveFunction w1,w2;
 	    // incoming wavefunction
 	    if(ferm) {
 	      w0 = inwave_.first [ihel[0]];
 	      w1 = outwave_[dit->channelType].second[ihel[dit->channelType+1]];
 	    }
 	    else {
 	      w0 = outwave_[dit->channelType].first [ihel[dit->channelType+1]];
 	      w1 = inwave_.second[ihel[0]];
 	    }
 	    if(decay[out2[dit->channelType]]->id()<0&&
 	       decay[out3[dit->channelType]]->id()>0) {
 	      w2 = outwave_[out3[dit->channelType]].second[ihel[out3[dit->channelType]+1]];
 	      w3 = outwave_[out2[dit->channelType]].first [ihel[out2[dit->channelType]+1]];
 	      sign *= -1.;
 	    }
 	    else {
 	      w2 = outwave_[out2[dit->channelType]].second[ihel[out2[dit->channelType]+1]];
 	      w3 = outwave_[out3[dit->channelType]].first [ihel[out3[dit->channelType]+1]];
 	    }
 	    tcPDPtr offshell = dit->intermediate;
 	    if(cc&&offshell->CC()) offshell=offshell->CC();
 	    Complex diag(0.);
 	    // intermediate scalar
 	    if     (offshell->iSpin() == PDT::Spin0) { 
 	      ScalarWaveFunction inters = sca_[idiag].first->
 		evaluate(scale, widthOption(), offshell, w0, w1);
 	      diag = sca_[idiag].second->evaluate(scale,w3,w2,inters);
 	    }
 	    // intermediate vector
 	    else if(offshell->iSpin() == PDT::Spin1) {
 	      VectorWaveFunction interv = vec_[idiag].first->
 		evaluate(scale, widthOption(), offshell, w0, w1);
 	      diag = vec_[idiag].second->evaluate(scale,w3,w2,interv);
 	    }
 	    // intermediate tensor
 	    else if(offshell->iSpin() == PDT::Spin2) {
 	      TensorWaveFunction intert = ten_[idiag].first->
 		evaluate(scale, widthOption(), offshell, w0, w1);
 	      diag = ten_[idiag].second->evaluate(scale,w3,w2,intert);
 	    }
 	    // unknown
 	    else throw Exception()
 	      << "Unknown intermediate in FtoFFFDecayer::me2()" 
 	      << Exception::runerror;
 	    // apply NO sign
 	    diag *= sign;
 	    // matrix element for the different colour flows
 	    if(ichan<0) {
 	      for(unsigned iy = 0; iy < dit->colourFlow.size(); ++iy) {
 		flows[dit->colourFlow[iy].first - 1] += 
 		  dit->colourFlow[iy].second * diag;
 	      }
 	      for(unsigned iy = 0; iy < dit->largeNcColourFlow.size(); ++iy) {
 		largeflows[dit->largeNcColourFlow[iy].first - 1] += 
 		  dit->largeNcColourFlow[iy].second * diag;
 	      }
 	    }
 	    else {
 	      for(unsigned iy = 0; iy < dit->colourFlow.size(); ++iy) {
 		if(dit->colourFlow[iy].first - 1!=colourFlow()) continue;
 		flows[dit->colourFlow[iy].first - 1] += 
 		  dit->colourFlow[iy].second * diag;
 	      }
 	      for(unsigned iy = 0; iy < dit->largeNcColourFlow.size(); ++iy) {
 		if(dit->colourFlow[iy].first - 1!=colourFlow()) continue;
 		largeflows[dit->largeNcColourFlow[iy].first - 1] += 
 		  dit->largeNcColourFlow[iy].second * diag;
 	      }
 	    }
 	    ++idiag;
 	  }
 	  // now add the flows to the me2 with appropriate colour factors
 	  for(unsigned int ix = 0; ix < ncf; ++ix) {
 	    (*mes[ix])(ihel[0],ihel[1],ihel[2],ihel[3]) =      flows[ix];
 	    (*mel[ix])(ihel[0],ihel[1],ihel[2],ihel[3]) = largeflows[ix];
 	  }
 	}
       }
     }
   }
   double me2(0.);
   if(ichan<0) {
     vector<double> pflows(ncf,0.);
     for(unsigned int ix = 0; ix < ncf; ++ix) {
       for(unsigned int iy = 0; iy < ncf; ++ iy) {
 	double con = cfactors[ix][iy]*(mes[ix]->contract(*mes[iy],rho_)).real();
 	me2 += con;
 	if(ix==iy) {
 	  con = nfactors[ix][iy]*(mel[ix]->contract(*mel[iy],rho_)).real();
 	  pflows[ix] += con;
 	}
       }
     }
     double ptotal(std::accumulate(pflows.begin(),pflows.end(),0.));
     ptotal *=UseRandom::rnd();
     for(unsigned int ix=0;ix<pflows.size();++ix) {
       if(ptotal<=pflows[ix]) {
 	colourFlow(ix);
 	ME(mes[ix]);
 	break;
       }
       ptotal-=pflows[ix];
     }
   }
   else {
     unsigned int iflow = colourFlow();
     me2 = nfactors[iflow][iflow]*(mel[iflow]->contract(*mel[iflow],rho_)).real();
   }
   // return the matrix element squared
   return me2;
 }
 
 WidthCalculatorBasePtr FtoFFFDecayer::
 threeBodyMEIntegrator(const DecayMode & ) const {
   vector<int> intype;
   vector<Energy> inmass,inwidth;
   vector<double> inpow,inweights;
   constructIntegratorChannels(intype,inmass,inwidth,inpow,inweights);
   return new_ptr(ThreeBodyAllOnCalculator<FtoFFFDecayer>
 		 (inweights,intype,inmass,inwidth,inpow,*this,0,
 		  outgoing()[0]->mass(),outgoing()[1]->mass(),outgoing()[2]->mass(),
 		 relativeError()));
 }
diff --git a/Decay/General/FtoFVVDecayer.cc b/Decay/General/FtoFVVDecayer.cc
--- a/Decay/General/FtoFVVDecayer.cc
+++ b/Decay/General/FtoFVVDecayer.cc
@@ -1,401 +1,403 @@
 // -*- C++ -*-
 //
 // This is the implementation of the non-inlined, non-templated member
 // functions of the FtoFVVDecayer class.
 //
 
 #include "FtoFVVDecayer.h"
 #include "ThePEG/Utilities/DescribeClass.h"
 #include "ThePEG/Interface/ClassDocumentation.h"
 #include "ThePEG/Persistency/PersistentOStream.h"
 #include "ThePEG/Persistency/PersistentIStream.h"
 #include "Herwig/Decay/DecayPhaseSpaceMode.h"
 #include "Herwig/PDT/ThreeBodyAllOnCalculator.h"
 #include "Herwig/Decay/GeneralDecayMatrixElement.h"
 #include <numeric>
 
 using namespace Herwig;
 
 IBPtr FtoFVVDecayer::clone() const {
   return new_ptr(*this);
 }
 
 IBPtr FtoFVVDecayer::fullclone() const {
   return new_ptr(*this);
 }
 
 void FtoFVVDecayer::persistentOutput(PersistentOStream & os) const {
   os << sca_ << fer_ << vec_ << ten_;
 }
 
 void FtoFVVDecayer::persistentInput(PersistentIStream & is, int) {
   is >> sca_ >> fer_ >> vec_ >> ten_;
 }
 
 // The following static variable is needed for the type
 // description system in ThePEG.
 DescribeClass<FtoFVVDecayer,GeneralThreeBodyDecayer>
 describeHerwigFtoFVVDecayer("Herwig::FtoFVVDecayer", "Herwig.so");
 
 void FtoFVVDecayer::Init() {
 
   static ClassDocumentation<FtoFVVDecayer> documentation
     ("The FtoFVVDecayer class implements the general decay of a fermion to "
      "a fermion and a pair of vectors.");
 
 }
 
 void FtoFVVDecayer::doinit() {
   GeneralThreeBodyDecayer::doinit();
   if(outgoing().empty()) return;
   unsigned int ndiags = getProcessInfo().size();
   sca_.resize(ndiags);
   fer_.resize(ndiags);
   vec_.resize(ndiags);
   ten_.resize(ndiags);
   for(unsigned int ix = 0;ix < ndiags; ++ix) {
     TBDiagram current = getProcessInfo()[ix];
     tcPDPtr offshell = current.intermediate;
     if(offshell->iSpin() == PDT::Spin0) {
       AbstractFFSVertexPtr vert1 = dynamic_ptr_cast<AbstractFFSVertexPtr>
 	(current.vertices.first);
       AbstractVVSVertexPtr vert2 = dynamic_ptr_cast<AbstractVVSVertexPtr>
 	(current.vertices.second);
       if(!vert1||!vert2) throw Exception() 
 	<< "Invalid vertices for a scalar diagram in FtoFVVDecayer::doinit()"
 	<< Exception::runerror;
       sca_[ix] = make_pair(vert1, vert2);
     }
     else if(offshell->iSpin() == PDT::Spin1Half) {
       AbstractFFVVertexPtr vert1 = dynamic_ptr_cast<AbstractFFVVertexPtr>
 	(current.vertices.first);
       AbstractFFVVertexPtr vert2 = dynamic_ptr_cast<AbstractFFVVertexPtr>
 	(current.vertices.second);
       if(!vert1||!vert2) throw Exception() 
 	<< "Invalid vertices for a scalar diagram in FtoFVVDecayer::doinit()"
 	<< Exception::runerror;
       fer_[ix] = make_pair(vert1, vert2);
     }
     else if(offshell->iSpin() == PDT::Spin1) {
       AbstractFFVVertexPtr vert1 = dynamic_ptr_cast<AbstractFFVVertexPtr>
 	(current.vertices.first);
       AbstractVVVVertexPtr vert2 = dynamic_ptr_cast<AbstractVVVVertexPtr>
 	(current.vertices.second);
       if(!vert1||!vert2) throw Exception() 
 	<< "Invalid vertices for a vector diagram in FtoFVVDecayer::doinit()"
 	<< Exception::runerror;
       vec_[ix] = make_pair(vert1, vert2);
     }
     else if(offshell->iSpin() == PDT::Spin2) {
       AbstractFFTVertexPtr vert1 = dynamic_ptr_cast<AbstractFFTVertexPtr>
 	(current.vertices.first);
       AbstractVVTVertexPtr vert2 = dynamic_ptr_cast<AbstractVVTVertexPtr>
 	(current.vertices.second);
       if(!vert1||!vert2) throw Exception() 
 	<< "Invalid vertices for a tensor diagram in FtoFVVDecayer::doinit()"
 	<< Exception::runerror;
       ten_[ix] = make_pair(vert1, vert2);
     }
   }
 }
 
 double  FtoFVVDecayer::me2(const int ichan, const Particle & inpart,
 			   const ParticleVector & decay,
 			   MEOption meopt) const {
   // particle or CC of particle
   bool cc = (*getProcessInfo().begin()).incoming != inpart.id();
   // special handling or first/last call
   //Set up wave-functions
   bool ferm( inpart.id() > 0 );
   if(meopt==Initialize) {
     if( ferm ) {
       SpinorWaveFunction::
 	calculateWaveFunctions(fwave_,rho_,const_ptr_cast<tPPtr>(&inpart),
 			       Helicity::incoming);
       if( fwave_[0].wave().Type() != SpinorType::u )
 	fwave_[0].conjugate();
       if( fwave_[1].wave().Type() != SpinorType::u )
 	fwave_[1].conjugate();
     }
     else {
       SpinorBarWaveFunction::
 	calculateWaveFunctions(fbwave_, rho_, const_ptr_cast<tPPtr>(&inpart),
 			       Helicity::incoming);
       if( fbwave_[0].wave().Type() != SpinorType::v )
 	fbwave_[0].conjugate();
       if( fbwave_[1].wave().Type() != SpinorType::v )
 	fbwave_[1].conjugate();
     }
+    // fix rho if no correlations
+    fixRho(rho_);
   }
   // setup spin info when needed
   if(meopt==Terminate) {
     // for the decaying particle
     if(ferm)
       SpinorWaveFunction::constructSpinInfo(fwave_,
 					    const_ptr_cast<tPPtr>(&inpart),
 					    Helicity::incoming,true);
     else
       SpinorBarWaveFunction::constructSpinInfo(fbwave_,
 					       const_ptr_cast<tPPtr>(&inpart),
 					       Helicity::incoming,true);
     int ivec(-1);
     // outgoing particles
     for(int ix = 0; ix < 3; ++ix) {
       tPPtr p = decay[ix];
       if( p->dataPtr()->iSpin() == PDT::Spin1Half ) {
 	if( ferm ) {
 	  SpinorBarWaveFunction::
 	    constructSpinInfo(fbwave_, p, Helicity::outgoing,true);
 	}
 	else {
 	  SpinorWaveFunction::
 	    constructSpinInfo(fwave_ , p, Helicity::outgoing,true);
 	}
       }
       else if( p->dataPtr()->iSpin() == PDT::Spin1 ) {
 	if( ivec < 0 ) {
 	  ivec = ix;
 	  VectorWaveFunction::
 	    constructSpinInfo(vwave_.first , p, Helicity::outgoing, true, false);
 	}
 	else {
 	  VectorWaveFunction::
 	    constructSpinInfo(vwave_.second, p, Helicity::outgoing, true, false);
 	}
       }
     }
     return 0.;
   }
   // outgoing, keep track of fermion and first occurrence of vector positions
   int isp(-1), ivec(-1);
   // outgoing particles
   pair<bool,bool> mass = make_pair(false,false);
   for(int ix = 0; ix < 3; ++ix) {
     tPPtr p = decay[ix];
     if( p->dataPtr()->iSpin() == PDT::Spin1Half ) {
       isp = ix;
       if( ferm ) {
 	SpinorBarWaveFunction::
 	  calculateWaveFunctions(fbwave_, p, Helicity::outgoing);
 	if( fbwave_[0].wave().Type() != SpinorType::u )
 	  fbwave_[0].conjugate();
 	if( fbwave_[1].wave().Type() != SpinorType::u )
 	  fbwave_[1].conjugate();
       }
       else {
 	SpinorWaveFunction::
 	  calculateWaveFunctions(fwave_, p, Helicity::outgoing);
 	if( fwave_[0].wave().Type() != SpinorType::v )
 	  fwave_[0].conjugate();
 	if( fwave_[1].wave().Type() != SpinorType::v )
 	  fwave_[1].conjugate();
       }
     }
     else if( p->dataPtr()->iSpin() == PDT::Spin1 ) {
       bool massless = p->id() == ParticleID::gamma || p->id() == ParticleID::g;
       if( ivec < 0 ) {
 	ivec = ix;
 	VectorWaveFunction::
 	  calculateWaveFunctions(vwave_.first , p, Helicity::outgoing, massless);
 	mass.first = massless;
       }
       else {
 	VectorWaveFunction::
 	  calculateWaveFunctions(vwave_.second, p, Helicity::outgoing, massless);
 	mass.second = massless;
       }
     }
   }
   assert(isp >= 0 && ivec >= 0);
   Energy2 scale(sqr(inpart.mass()));
   const vector<vector<double> > cfactors(getColourFactors());
   const vector<vector<double> > nfactors(getLargeNcColourFactors());
   const size_t ncf(numberOfFlows());
   vector<Complex> flows(ncf, Complex(0.)), largeflows(ncf, Complex(0.)); 
   vector<GeneralDecayMEPtr> 
     mes(ncf,new_ptr(GeneralDecayMatrixElement(PDT::Spin1Half, 
 					      (isp == 0) ? PDT::Spin1Half : PDT::Spin1,
 					      (isp == 1) ? PDT::Spin1Half : PDT::Spin1,
 					      (isp == 2) ? PDT::Spin1Half : PDT::Spin1)));
   vector<GeneralDecayMEPtr> 
     mel(ncf,new_ptr(GeneralDecayMatrixElement(PDT::Spin1Half, 
 					      (isp == 0) ? PDT::Spin1Half : PDT::Spin1,
 					      (isp == 1) ? PDT::Spin1Half : PDT::Spin1,
 					      (isp == 2) ? PDT::Spin1Half : PDT::Spin1)));
   //Helicity calculation
   for( unsigned int if1 = 0; if1 < 2; ++if1 ) {
     for( unsigned int if2 = 0; if2 < 2; ++if2 ) {
       for( unsigned int iv1 = 0; iv1 < 3; ++iv1 ) {
 	if ( mass.first && iv1 == 1 ) continue;
 	for( unsigned int iv2 = 0; iv2 < 3; ++iv2 ) {
 	  if ( mass.second && iv2 == 1 ) continue;
 	  flows = vector<Complex>(ncf, Complex(0.));
 	largeflows = vector<Complex>(ncf, Complex(0.));
 	unsigned int idiag(0);
 	for(vector<TBDiagram>::const_iterator dit = getProcessInfo().begin();
 	    dit != getProcessInfo().end(); ++dit) {
 	  // If we are selecting a particular channel
 	  if( ichan >= 0 && diagramMap()[ichan] != idiag ) {
 	    ++idiag;
 	    continue;
 	  }
 	  tcPDPtr offshell = (*dit).intermediate;
 	  if(cc&&offshell->CC()) offshell=offshell->CC();
 	  Complex diag;
 	  if( offshell->iSpin() == PDT::Spin1Half ) {
 	    // Make sure we connect the correct particles 
 	    VectorWaveFunction vw1, vw2;
 	    if( (*dit).channelType == TBDiagram::channel23 ) {
 	      vw1 = vwave_.first[iv1];
 	      vw2 = vwave_.second[iv2];
 	    }
 	    else if( (*dit).channelType == TBDiagram::channel12 ) {
 	      vw1 = vwave_.second[iv2];
 	      vw2 = vwave_.first[iv1];
 	    }
 	    else {
 	      if( ivec < isp ) {
 		vw1 = vwave_.second[iv2];
 		vw2 = vwave_.first[iv1];
 	      }
 	      else {
 		vw1 = vwave_.first[iv1];
 		vw2 = vwave_.second[iv2];
 	      }
 	    }
 	    if( ferm ) {
 	      SpinorWaveFunction inters = 
 		fer_[idiag].first->evaluate(scale, widthOption(), offshell,
 					    fwave_[if1], vw1);
 	      diag = fer_[idiag].second->evaluate(scale, inters, fbwave_[if2],
 						  vw2);
 	    }
 	    else {
 	      SpinorBarWaveFunction inters = 
 		fer_[idiag].first->evaluate(scale, widthOption(), offshell,
 					    fbwave_[if2], vw1);
 	      diag = fer_[idiag].second->evaluate(scale, fwave_[if1], inters, 
 						  vw2);
 	    }
 	  }
 	  else if( offshell->iSpin() == PDT::Spin0 ) {
 	    ScalarWaveFunction inters = 
 	      sca_[idiag].first->evaluate(scale, widthOption(), offshell, 
 					  fwave_[if1], fbwave_[if2]);
 	    diag = sca_[idiag].second->evaluate(scale, vwave_.first[iv1],
 						vwave_.second[iv2], inters);
 	  }
 	  else if( offshell->iSpin() == PDT::Spin1 ) {
 	    VectorWaveFunction interv = 
 	      vec_[idiag].first->evaluate(scale, widthOption(), offshell, 
 					  fwave_[if1], fbwave_[if2]);
 	    diag = vec_[idiag].second->evaluate(scale, vwave_.first[iv1],
 						vwave_.second[iv2], interv);
 	  } 
 	  else if( offshell->iSpin() == PDT::Spin2 ) {
 	    TensorWaveFunction intert = 
 	      ten_[idiag].first->evaluate(scale, widthOption(), offshell, 
 					  fwave_[if1], fbwave_[if2]);
 	    diag = ten_[idiag].second->evaluate(scale, vwave_.first[iv1],
 						vwave_.second[iv2], intert);
 	  }
 	  else 
 	    throw Exception()
 	      << "Unknown intermediate in FtoFVVDecayer::me2()" 
 	      << Exception::runerror;
 	  //NO sign
 	  if( !ferm ) diag *= -1;
 
 	  if(ichan<0) {
 	    for(unsigned iy = 0; iy < dit->colourFlow.size(); ++iy) {
 	      flows[dit->colourFlow[iy].first - 1] += 
 		dit->colourFlow[iy].second * diag;
 	    }
 	    for(unsigned iy = 0; iy < dit->largeNcColourFlow.size(); ++iy) {
 	      largeflows[dit->largeNcColourFlow[iy].first - 1] += 
 		dit->largeNcColourFlow[iy].second * diag;
 	    }
 	  }
 	  else {
 	    for(unsigned iy = 0; iy < dit->colourFlow.size(); ++iy) {
 	      if(dit->colourFlow[iy].first - 1!=colourFlow()) continue;
 	      flows[dit->colourFlow[iy].first - 1] += 
 		dit->colourFlow[iy].second * diag;
 	    }
 	    for(unsigned iy = 0; iy < dit->largeNcColourFlow.size(); ++iy) {
 	      if(dit->colourFlow[iy].first - 1!=colourFlow()) continue;
 	      largeflows[dit->largeNcColourFlow[iy].first - 1] += 
 		dit->largeNcColourFlow[iy].second * diag;
 	    }
 	  }
 	  ++idiag;
 	}// end diagram loop
 
 	// now add the flows to the me2 
 	unsigned int h1(if1), h2(if2);
 	if( !ferm ) swap(h1,h2);
 	  for(unsigned int ix = 0; ix < ncf; ++ix) {
 	    if(isp == 0) {
 	      (*mes[ix])(h1, h2, iv1, iv2) = flows[ix];
 	      (*mel[ix])(h1, h2, iv1, iv2) = largeflows[ix];
 	    }
 	    else if(isp == 1) { 
 	      (*mes[ix])(h1, iv1, h2, iv2) = flows[ix];
 	      (*mel[ix])(h1, iv1, h2, iv2) = largeflows[ix];
 	    }
 	    else if(isp == 2) { 
 	      (*mes[ix])(h1, iv1, iv2, h2) = flows[ix];
 	      (*mel[ix])(h1, iv1, h2, iv2) = largeflows[ix];
 	    }
 	  }
 
 	}//v2
       }//v1
     }//f2
   }//f1
   
   //Finally, work out me2. This depends on whether we are selecting channels
   //or not
   double me2(0.);
   if(ichan<0) {
     vector<double> pflows(ncf,0.);
     for(unsigned int ix = 0; ix < ncf; ++ix) {
       for(unsigned int iy = 0; iy < ncf; ++ iy) {
 	double con = cfactors[ix][iy]*(mes[ix]->contract(*mes[iy],rho_)).real();
 	me2 += con;
 	if(ix==iy) {
 	  con = nfactors[ix][iy]*(mel[ix]->contract(*mel[iy],rho_)).real();
 	  pflows[ix] += con;
 	}
       }
     }
     double ptotal(std::accumulate(pflows.begin(),pflows.end(),0.));
     ptotal *= UseRandom::rnd();
     for(unsigned int ix=0;ix<pflows.size();++ix) {
       if(ptotal<=pflows[ix]) {
         colourFlow(ix);
         ME(mes[ix]);
         break;
       }
       ptotal-=pflows[ix];
     }
   }
   else {
     unsigned int iflow = colourFlow();
     me2 = nfactors[iflow][iflow]*(mel[iflow]->contract(*mel[iflow],rho_)).real();
   }
   // return the matrix element squared
   return me2;
 }
 
 WidthCalculatorBasePtr FtoFVVDecayer::
 threeBodyMEIntegrator(const DecayMode & ) const {
   vector<int> intype;
   vector<Energy> inmass,inwidth;
   vector<double> inpow,inweights;
   constructIntegratorChannels(intype,inmass,inwidth,inpow,inweights);
   return new_ptr(ThreeBodyAllOnCalculator<FtoFVVDecayer>
 		 (inweights,intype,inmass,inwidth,inpow,*this,0,
 		  outgoing()[0]->mass(),outgoing()[1]->mass(),
 		  outgoing()[2]->mass(),relativeError()));
 }
diff --git a/Decay/General/SFFDecayer.cc b/Decay/General/SFFDecayer.cc
--- a/Decay/General/SFFDecayer.cc
+++ b/Decay/General/SFFDecayer.cc
@@ -1,491 +1,493 @@
 // -*- C++ -*-
 //
 // SFFDecayer.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 SFFDecayer class.
 //
 
 #include "SFFDecayer.h"
 #include "ThePEG/Utilities/DescribeClass.h"
 #include "ThePEG/Interface/ClassDocumentation.h"
 #include "ThePEG/Persistency/PersistentOStream.h"
 #include "ThePEG/Persistency/PersistentIStream.h"
 #include "ThePEG/PDT/DecayMode.h"
 #include "ThePEG/Helicity/WaveFunction/ScalarWaveFunction.h"
 #include "ThePEG/Helicity/WaveFunction/SpinorWaveFunction.h"
 #include "ThePEG/Helicity/WaveFunction/SpinorBarWaveFunction.h"
 #include "Herwig/Utilities/Kinematics.h"
 #include "Herwig/Decay/GeneralDecayMatrixElement.h"
 
 using namespace Herwig;
 using namespace ThePEG::Helicity;
 
 IBPtr SFFDecayer::clone() const {
   return new_ptr(*this);
 }
 
 IBPtr SFFDecayer::fullclone() const {
   return new_ptr(*this);
 }
 
 void SFFDecayer::setDecayInfo(PDPtr incoming, PDPair outgoing,
 			      vector<VertexBasePtr> vertex,
 			      map<ShowerInteraction,VertexBasePtr> & inV,
 			      const vector<map<ShowerInteraction,VertexBasePtr> > & outV,
 			      map<ShowerInteraction,VertexBasePtr> ) {
   decayInfo(incoming,outgoing);
   for(auto vert : vertex) {
     vertex_             .push_back(dynamic_ptr_cast<AbstractFFSVertexPtr>(vert));
     perturbativeVertex_ .push_back(dynamic_ptr_cast<FFSVertexPtr>        (vert));
   }
   vector<ShowerInteraction> itemp={ShowerInteraction::QCD,ShowerInteraction::QED};
   for(auto & inter : itemp) {
     incomingVertex_[inter] = dynamic_ptr_cast<AbstractVSSVertexPtr>(inV.at(inter));
     outgoingVertex1_[inter] = dynamic_ptr_cast<AbstractFFVVertexPtr>(outV[0].at(inter));
     outgoingVertex2_[inter] = dynamic_ptr_cast<AbstractFFVVertexPtr>(outV[1].at(inter));
   }
 }
 
 void SFFDecayer::persistentOutput(PersistentOStream & os) const {
   os << vertex_           << perturbativeVertex_ 
      << incomingVertex_   << outgoingVertex1_
      << outgoingVertex2_;
 }
 
 void SFFDecayer::persistentInput(PersistentIStream & is, int) {
   is >> vertex_           >> perturbativeVertex_ 
      >> incomingVertex_   >> outgoingVertex1_
      >> outgoingVertex2_;
 }
 
 // The following static variable is needed for the type
 // description system in ThePEG.
 DescribeClass<SFFDecayer,GeneralTwoBodyDecayer>
 describeHerwigSFFDecayer("Herwig::SFFDecayer", "Herwig.so");
 
 void SFFDecayer::Init() {
 
   static ClassDocumentation<SFFDecayer> documentation
     ("This class implements to decay of a scalar to 2 fermions");
 
 }
 
 double SFFDecayer::me2(const int , const Particle & inpart,
 		       const ParticleVector & decay,MEOption meopt) const {
   if(!ME())
     ME(new_ptr(GeneralDecayMatrixElement(PDT::Spin0,PDT::Spin1Half,PDT::Spin1Half)));
   // work out which is the fermion and antifermion
   int iferm(1),ianti(0);
   int itype[2];
   for(unsigned int ix=0;ix<2;++ix) {
     if(decay[ix]->dataPtr()->CC()) itype[ix] = decay[ix]->id()>0 ? 0:1;
     else                           itype[ix] = 2;
   }
   if(itype[0]==0||itype[1]==1||(itype[0]==2&&itype[1]==2)) swap(iferm,ianti);
 
   if(meopt==Initialize) {
     ScalarWaveFunction::
       calculateWaveFunctions(rho_,const_ptr_cast<tPPtr>(&inpart),incoming);
     swave_ = ScalarWaveFunction(inpart.momentum(),inpart.dataPtr(),incoming);
+    // fix rho if no correlations
+    fixRho(rho_);
   }
   if(meopt==Terminate) {
     ScalarWaveFunction::
       constructSpinInfo(const_ptr_cast<tPPtr>(&inpart),incoming,true);
     SpinorBarWaveFunction::
       constructSpinInfo(wavebar_,decay[iferm],outgoing,true);
     SpinorWaveFunction::
       constructSpinInfo(wave_   ,decay[ianti],outgoing,true);
     return 0.;
   }
   SpinorBarWaveFunction::
     calculateWaveFunctions(wavebar_,decay[iferm],outgoing);
   SpinorWaveFunction::
     calculateWaveFunctions(wave_   ,decay[ianti],outgoing);
   Energy2 scale(sqr(inpart.mass()));
   for(unsigned int ifm = 0; ifm < 2; ++ifm){
     for(unsigned int ia = 0; ia < 2; ++ia) {
       if(iferm > ianti) (*ME())(0, ia, ifm) = 0.;
       else              (*ME())(0, ifm, ia) = 0.;
       for(auto vert : vertex_) {
 	if(iferm > ianti){
 	  (*ME())(0, ia, ifm) += vert->evaluate(scale,wave_[ia],
 						wavebar_[ifm],swave_);
 	}
 	else {
 	  (*ME())(0, ifm, ia) += vert->evaluate(scale,wave_[ia],
 						wavebar_[ifm],swave_);
 	}
       }
     }
   }
 
   double output = (ME()->contract(rho_)).real()/scale*UnitRemoval::E2;
   // colour and identical particle factors
   output *= colourFactor(inpart.dataPtr(),decay[0]->dataPtr(),
 			 decay[1]->dataPtr());
   // return the answer
   return output;
 }
 
 Energy SFFDecayer::partialWidth(PMPair inpart, PMPair outa, 
 				PMPair outb) const {
   if( inpart.second < outa.second + outb.second  ) return ZERO;
   if(perturbativeVertex_.size()==1 &&
      perturbativeVertex_[0]) {
     tcPDPtr in = inpart.first->CC() ? tcPDPtr(inpart.first->CC()) : inpart.first;
     perturbativeVertex_[0]->setCoupling(sqr(inpart.second), outb.first, outa.first,
 				     in);
     double mu1(outa.second/inpart.second),mu2(outb.second/inpart.second);
     double c2 = norm(perturbativeVertex_[0]->norm());
     Complex al(perturbativeVertex_[0]->left()), ar(perturbativeVertex_[0]->right());
     double me2 = -c2*( (norm(al) + norm(ar))*( sqr(mu1) + sqr(mu2) - 1.)
 		       + 2.*(ar*conj(al) + al*conj(ar)).real()*mu1*mu2 );
     Energy pcm = Kinematics::pstarTwoBodyDecay(inpart.second, outa.second,
 					outb.second);
     Energy output = me2*pcm/(8*Constants::pi);
     // colour factor
     output *= colourFactor(inpart.first,outa.first,outb.first);
     return output;
   }
   else {
     return GeneralTwoBodyDecayer::partialWidth(inpart,outa,outb);
   }
 }
 
 double SFFDecayer::threeBodyME(const int , const Particle & inpart,
 			       const ParticleVector & decay,
 			       ShowerInteraction inter, MEOption meopt) {
   // work out which is the fermion and antifermion
   int ianti(0), iferm(1), iglu(2);
   int itype[2];
   for(unsigned int ix=0;ix<2;++ix) {
     if(decay[ix]->dataPtr()->CC()) itype[ix] = decay[ix]->id()>0 ? 0:1;
     else                           itype[ix] = 2;
   }
   if(itype[0]==0 && itype[1]!=0) swap(iferm, ianti);
   if(itype[0]==2 && itype[1]==1) swap(iferm, ianti);
   if(itype[0]==0 && itype[1]==0 && decay[0]->dataPtr()->id()<decay[1]->dataPtr()->id()) 
     swap(iferm, ianti);
   if(itype[0]==1 && itype[1]==1 && decay[0]->dataPtr()->id()<decay[1]->dataPtr()->id()) 
     swap(iferm, ianti);
   
   if(meopt==Initialize) {
     // create scalar wavefunction for decaying particle
     ScalarWaveFunction::
       calculateWaveFunctions(rho3_,const_ptr_cast<tPPtr>(&inpart),incoming);
     swave3_ = ScalarWaveFunction(inpart.momentum(),inpart.dataPtr(),incoming);
   }
   // setup spin information when needed
   if(meopt==Terminate) {
     ScalarWaveFunction::
       constructSpinInfo(const_ptr_cast<tPPtr>(&inpart),incoming,true);
     SpinorBarWaveFunction::
       constructSpinInfo(wavebar3_ ,decay[iferm],outgoing,true);
     SpinorWaveFunction::
       constructSpinInfo(wave3_    ,decay[ianti],outgoing,true);
     VectorWaveFunction::
       constructSpinInfo(gluon_    ,decay[iglu ],outgoing,true,false);
     return 0.;
   }
 
   // calculate colour factors and number of colour flows
   unsigned int nflow;
   vector<DVector> cfactors = getColourFactors(inpart, decay, nflow);
 
   vector<GeneralDecayMEPtr> ME(nflow,new_ptr(GeneralDecayMatrixElement(PDT::Spin0,     PDT::Spin1Half,
 								       PDT::Spin1Half, PDT::Spin1)));
   // create wavefunctions
   SpinorBarWaveFunction::
     calculateWaveFunctions(wavebar3_, decay[iferm],outgoing);
   SpinorWaveFunction::
     calculateWaveFunctions(wave3_   , decay[ianti],outgoing);
   VectorWaveFunction::
     calculateWaveFunctions(gluon_   , decay[iglu ],outgoing,true);
 
   // gauge invariance test
 #ifdef GAUGE_CHECK
   gluon_.clear();
   for(unsigned int ix=0;ix<3;++ix) {
     if(ix==1) gluon_.push_back(VectorWaveFunction());
     else {
       gluon_.push_back(VectorWaveFunction(decay[iglu ]->momentum(),
   				          decay[iglu ]->dataPtr(),10,
   					  outgoing));
     }
   }
 #endif
 
   // identify fermion and/or anti-fermion vertex
   AbstractFFVVertexPtr outgoingVertexF;
   AbstractFFVVertexPtr outgoingVertexA;
   identifyVertices(iferm, ianti, inpart, decay, outgoingVertexF, outgoingVertexA,
 		   inter);
 
   const GeneralTwoBodyDecayer::CFlow & colourFlow
         = colourFlows(inpart, decay);
 
   Energy2 scale(sqr(inpart.mass()));
   double gs(0.);
   bool couplingSet(false);
 #ifdef GAUGE_CHECK
   double total=0.;
 #endif
   for(unsigned int ifm = 0; ifm < 2; ++ifm) {
     for(unsigned int ia = 0; ia < 2; ++ia) {
       for(unsigned int ig = 0; ig < 2; ++ig) {
 	// radiation from the incoming scalar
 	if((inpart.dataPtr()->coloured() && inter==ShowerInteraction::QCD) ||
 	   (inpart.dataPtr()->charged()  && inter==ShowerInteraction::QED) ) {
 	  assert(incomingVertex_[inter]);
 
 	  ScalarWaveFunction scalarInter = 
 	    incomingVertex_[inter]->evaluate(scale,3,inpart.dataPtr(),
 					      gluon_[2*ig],swave3_,inpart.mass());
 
 	  assert(swave3_.particle()->id()==scalarInter.particle()->id());
 
 	  if(!couplingSet) {
 	    gs = abs(incomingVertex_[inter]->norm());
 	    couplingSet = true;
 	  }
 	  Complex diag = 0.;
 	  for(auto vertex : vertex_)
 	    diag += vertex->evaluate(scale,wave3_[ia],
 				     wavebar3_[ifm],scalarInter);
 	  for(unsigned int ix=0;ix<colourFlow[0].size();++ix) {
 	    (*ME[colourFlow[0][ix].first])(0, ia, ifm, ig) += 
 	      colourFlow[0][ix].second*diag;
 	  }
 #ifdef GAUGE_CHECK
 	  total+=norm(diag);
 #endif
 	}
 	// radiation from outgoing fermion
 	if((decay[iferm]->dataPtr()->coloured() && inter==ShowerInteraction::QCD) ||
 	   (decay[iferm]->dataPtr()->charged()  && inter==ShowerInteraction::QED)) {
 	  assert(outgoingVertexF);
 	  // ensure you get correct outgoing particle from first vertex
 	  tcPDPtr off = decay[iferm]->dataPtr();
 	  if(off->CC()) off = off->CC();
 	  SpinorBarWaveFunction interS = 
 	    outgoingVertexF->evaluate(scale,3,off,wavebar3_[ifm],
 				      gluon_[2*ig],decay[iferm]->mass());
 	  
 	  assert(wavebar3_[ifm].particle()->id()==interS.particle()->id());
 	  
 	  if(!couplingSet) {
 	    gs = abs(outgoingVertexF->norm());
 	    couplingSet = true;
 	  }
 	  Complex diag = 0.;
 	  for(auto vertex : vertex_)
 	    diag += vertex->evaluate(scale,wave3_[ia], interS,swave3_);
 	  for(unsigned int ix=0;ix<colourFlow[1].size();++ix) {
 	    (*ME[colourFlow[1][ix].first])(0, ia, ifm, ig) += 
 	      colourFlow[1][ix].second*diag;
 	  }
 #ifdef GAUGE_CHECK
 	  total+=norm(diag);
 #endif
 	}
 	
 	// radiation from outgoing antifermion
 	if((decay[ianti]->dataPtr()->coloured() && inter==ShowerInteraction::QCD) ||
 	   (decay[ianti]->dataPtr()->charged()  && inter==ShowerInteraction::QED)) {
 	  assert(outgoingVertexA);
 	  // ensure you get correct outgoing particle from first vertex
 	  tcPDPtr off = decay[ianti]->dataPtr();
 	  if(off->CC()) off = off->CC();
 	  SpinorWaveFunction  interS = 
 	    outgoingVertexA->evaluate(scale,3,off,wave3_[ia],
 				      gluon_[2*ig],decay[ianti]->mass());
 	  
 	  assert(wave3_[ia].particle()->id()==interS.particle()->id());
 
 	  if(!couplingSet) {
 	    gs = abs(outgoingVertexA->norm());
 	    couplingSet = true;
 	  }
 	  Complex diag = 0.;
 	  for(auto vertex : vertex_)
 	    diag += vertex->evaluate(scale,interS,wavebar3_[ifm],swave3_);
 	  for(unsigned int ix=0;ix<colourFlow[2].size();++ix) {
 	    (*ME[colourFlow[2][ix].first])(0, ia, ifm, ig) += 
 	      colourFlow[2][ix].second*diag;
 	  }
 #ifdef GAUGE_CHECK
 	  total+=norm(diag);
 #endif
 	}
       }
     }
   }
   
   // contract matrices 
   double output=0.;
   for(unsigned int ix=0; ix<nflow; ++ix){
     for(unsigned int iy=0; iy<nflow; ++iy){
       output+=cfactors[ix][iy]*(ME[ix]->contract(*ME[iy],rho3_)).real();
     }
   }
   // divide by alpha(S,EM)
   output *= (4.*Constants::pi)/sqr(gs);
 #ifdef GAUGE_CHECK
   double ratio = output/total;
   if(abs(ratio)>1e-20) {
     generator()->log() << "Test of gauge invariance in decay\n" << inpart << "\n";
     for(unsigned int ix=0;ix<decay.size();++ix)
       generator()->log() << *decay[ix] << "\n";
     generator()->log() << "Test of gauge invariance " << ratio << "\n";
   }
 #endif
     // return the answer
   return output;
 }
 
 void SFFDecayer::identifyVertices(const int iferm, const int ianti,
 				  const Particle & inpart, const ParticleVector & decay, 
 				  AbstractFFVVertexPtr & outgoingVertexF, 
 				  AbstractFFVVertexPtr & outgoingVertexA,
 				  ShowerInteraction inter) {
   // QCD
   if(inter==ShowerInteraction::QCD) {
     // work out which fermion each outgoing vertex corresponds to 
     // two outgoing vertices
     if( inpart.dataPtr()       ->iColour()==PDT::Colour0     &&
 	((decay[iferm]->dataPtr()->iColour()==PDT::Colour3     &&
 	  decay[ianti]->dataPtr()->iColour()==PDT::Colour3bar) ||
 	 (decay[iferm]->dataPtr()->iColour()==PDT::Colour8     &&
 	  decay[ianti]->dataPtr()->iColour()==PDT::Colour8))) {
       if(outgoingVertex1_[inter]==outgoingVertex2_[inter]) {
 	outgoingVertexF = outgoingVertex1_[inter];
 	outgoingVertexA = outgoingVertex2_[inter];
       }
       else if (outgoingVertex1_[inter]->isIncoming(const_ptr_cast<tPDPtr>(decay[iferm]->dataPtr()))) {
 	outgoingVertexF = outgoingVertex1_[inter];
 	outgoingVertexA = outgoingVertex2_[inter];
       }
       else if (outgoingVertex2_[inter]->isIncoming(const_ptr_cast<tPDPtr>(decay[iferm]->dataPtr()))) {
 	outgoingVertexF = outgoingVertex2_[inter];
 	outgoingVertexA = outgoingVertex1_[inter];
       }
     }
     else if(inpart.dataPtr()       ->iColour()==PDT::Colour8 &&
 	    decay[iferm]->dataPtr()->iColour()==PDT::Colour3 &&
 	    decay[ianti]->dataPtr()->iColour()==PDT::Colour3bar) {
       if(outgoingVertex1_[inter]==outgoingVertex2_[inter]) {
 	outgoingVertexF = outgoingVertex1_[inter];
 	outgoingVertexA = outgoingVertex2_[inter];
       }
       else if (outgoingVertex1_[inter]->isIncoming(const_ptr_cast<tPDPtr>(decay[iferm]->dataPtr()))) {
 	outgoingVertexF = outgoingVertex1_[inter];
 	outgoingVertexA = outgoingVertex2_[inter];
       }
       else if (outgoingVertex2_[inter]->isIncoming(const_ptr_cast<tPDPtr>(decay[iferm]->dataPtr()))) {
 	outgoingVertexF = outgoingVertex2_[inter];
 	outgoingVertexA = outgoingVertex1_[inter];
       }
     }
     
     // one outgoing vertex
     else if(inpart.dataPtr()->iColour()==PDT::Colour3){
       if(decay[iferm]->dataPtr()->iColour()==PDT::Colour3 &&  
 	 decay[ianti]->dataPtr()->iColour()==PDT::Colour0){
       if     (outgoingVertex1_[inter]) outgoingVertexF = outgoingVertex1_[inter];
       else if(outgoingVertex2_[inter]) outgoingVertexF = outgoingVertex2_[inter];
       }
       else if (decay[iferm]->dataPtr()->iColour()==PDT::Colour3 &&
 	       decay[ianti]->dataPtr()->iColour()==PDT::Colour8) {
 	if (outgoingVertex1_[inter]->isIncoming(const_ptr_cast<tPDPtr>(decay[ianti]->dataPtr()))) {
 	  outgoingVertexF = outgoingVertex2_[inter];
 	  outgoingVertexA = outgoingVertex1_[inter];
 	}
 	else {
 	  outgoingVertexF = outgoingVertex1_[inter];
 	  outgoingVertexA = outgoingVertex2_[inter];
 	}
       }
       else if(decay[iferm]->dataPtr()->iColour()==PDT::Colour3bar &&
 	      decay[ianti]->dataPtr()->iColour()==PDT::Colour3bar) {
 	if (outgoingVertex1_[inter]->isIncoming(const_ptr_cast<tPDPtr>(decay[iferm]->dataPtr()))) {
 	  outgoingVertexF = outgoingVertex1_[inter];
 	  outgoingVertexA = outgoingVertex2_[inter];
 	}
 	else {
 	  outgoingVertexF = outgoingVertex2_[inter];
 	  outgoingVertexA = outgoingVertex1_[inter];
 	}
       }
     }
     else if(inpart.dataPtr()->iColour()==PDT::Colour3bar){
       if(decay[ianti]->dataPtr()->iColour()==PDT::Colour3bar &&  
 	 decay[iferm]->dataPtr()->iColour()==PDT::Colour0){
 	if     (outgoingVertex1_[inter]) outgoingVertexA = outgoingVertex1_[inter];
 	else if(outgoingVertex2_[inter]) outgoingVertexA = outgoingVertex2_[inter];
       }
       else if (decay[iferm]->dataPtr()->iColour()==PDT::Colour8 &&
 	       decay[ianti]->dataPtr()->iColour()==PDT::Colour3bar){
 	if (outgoingVertex1_[inter]->isIncoming(const_ptr_cast<tPDPtr>(decay[iferm]->dataPtr()))) {
 	  outgoingVertexF = outgoingVertex1_[inter];
 	  outgoingVertexA = outgoingVertex2_[inter];
 	}
 	else {
 	  outgoingVertexF = outgoingVertex2_[inter];
 	  outgoingVertexA = outgoingVertex1_[inter];
 	}
       }
       else if(decay[iferm]->dataPtr()->iColour()==PDT::Colour3 &&
 	      decay[ianti]->dataPtr()->iColour()==PDT::Colour3) {
 	if (outgoingVertex1_[inter]->isIncoming(const_ptr_cast<tPDPtr>(decay[iferm]->dataPtr()))) {
 	  outgoingVertexF = outgoingVertex1_[inter];
 	  outgoingVertexA = outgoingVertex2_[inter];
 	}
 	else {
 	  outgoingVertexF = outgoingVertex2_[inter];
 	  outgoingVertexA = outgoingVertex1_[inter];
 	}
       }
     }
     else if(inpart.dataPtr()->iColour()==PDT::Colour6 ||
 	    inpart.dataPtr()->iColour()==PDT::Colour6bar) {
       if (outgoingVertex1_[inter]->isIncoming(const_ptr_cast<tPDPtr>(decay[iferm]->dataPtr()))) {
 	outgoingVertexF = outgoingVertex1_[inter];
 	outgoingVertexA = outgoingVertex2_[inter];
       }
       else {
 	outgoingVertexF = outgoingVertex2_[inter];
 	outgoingVertexA = outgoingVertex1_[inter];
       }
     }
   
     if (! ((incomingVertex_[inter]  && (outgoingVertexF  || outgoingVertexA)) ||
 	   ( outgoingVertexF &&  outgoingVertexA))) {
       throw Exception()
 	<< "Invalid vertices for QCD radiation in SFF decay in SFFDecayer::identifyVertices"
 	<< Exception::runerror;
     }
   }
   // QED
   else {
     if(decay[iferm]->dataPtr()->charged()) {
       if (outgoingVertex1_[inter] &&
 	  outgoingVertex1_[inter]->isIncoming(const_ptr_cast<tPDPtr>(decay[iferm]->dataPtr())))
 	outgoingVertexF = outgoingVertex1_[inter];
       else
 	outgoingVertexF = outgoingVertex2_[inter];
     }
     if(decay[ianti]->dataPtr()->charged()) {
       if (outgoingVertex1_[inter] &&
 	  outgoingVertex1_[inter]->isIncoming(const_ptr_cast<tPDPtr>(decay[ianti]->dataPtr())))
 	outgoingVertexA = outgoingVertex1_[inter];
       else
 	outgoingVertexA = outgoingVertex2_[inter];
     }
   }
 }
diff --git a/Decay/General/SRFDecayer.cc b/Decay/General/SRFDecayer.cc
--- a/Decay/General/SRFDecayer.cc
+++ b/Decay/General/SRFDecayer.cc
@@ -1,196 +1,198 @@
 // -*- C++ -*-
 //
 // SRFDecayer.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 SRFDecayer class.
 //
 
 #include "SRFDecayer.h"
 #include "ThePEG/Utilities/DescribeClass.h"
 #include "ThePEG/Interface/ClassDocumentation.h"
 #include "ThePEG/Persistency/PersistentOStream.h"
 #include "ThePEG/Persistency/PersistentIStream.h"
 #include "ThePEG/PDT/DecayMode.h"
 #include "ThePEG/Helicity/WaveFunction/ScalarWaveFunction.h"
 #include "ThePEG/Helicity/WaveFunction/SpinorWaveFunction.h"
 #include "ThePEG/Helicity/WaveFunction/SpinorBarWaveFunction.h"
 #include "Herwig/Utilities/Kinematics.h"
 #include "Herwig/Decay/GeneralDecayMatrixElement.h"
 
 using namespace Herwig;
 using namespace ThePEG::Helicity;
 
 IBPtr SRFDecayer::clone() const {
   return new_ptr(*this);
 }
 
 IBPtr SRFDecayer::fullclone() const {
   return new_ptr(*this);
 }
 
 void SRFDecayer::setDecayInfo(PDPtr incoming, PDPair outgoing,
 			      vector<VertexBasePtr> vertex,
 			      map<ShowerInteraction,VertexBasePtr> &,
 			      const vector<map<ShowerInteraction,VertexBasePtr> > &,
 			      map<ShowerInteraction,VertexBasePtr>) {
   decayInfo(incoming,outgoing);
   for(auto vert : vertex) {
     vertex_             .push_back(dynamic_ptr_cast<AbstractRFSVertexPtr>(vert));
     perturbativeVertex_ .push_back(dynamic_ptr_cast<RFSVertexPtr>        (vert));
   }
 }
 
 void SRFDecayer::persistentOutput(PersistentOStream & os) const {
   os << vertex_ << perturbativeVertex_;
 }
 
 void SRFDecayer::persistentInput(PersistentIStream & is, int) {
   is >> vertex_ >> perturbativeVertex_;
 }
 
 // The following static variable is needed for the type
 // description system in ThePEG.
 DescribeClass<SRFDecayer,GeneralTwoBodyDecayer>
 describeHerwigSRFDecayer("Herwig::SRFDecayer", "Herwig.so");
 
 void SRFDecayer::Init() {
 
   static ClassDocumentation<SRFDecayer> documentation
     ("This class implements to decay of a scalar to a spin-3/2 and"
      " spin-1/2 fermion");
 
 }
 
 double SRFDecayer::me2(const int , const Particle & inpart,
 		       const ParticleVector & decay,MEOption meopt) const {
   unsigned int irs=0,ifm=1;
   if(decay[0]->dataPtr()->iSpin()==PDT::Spin1Half) swap(irs,ifm);
   if(!ME()) {
     if(irs==0)
       ME(new_ptr(GeneralDecayMatrixElement(PDT::Spin0,PDT::Spin3Half,PDT::Spin1Half)));
     else
       ME(new_ptr(GeneralDecayMatrixElement(PDT::Spin0,PDT::Spin1Half,PDT::Spin3Half)));
   }
   bool ferm = decay[ifm]->id()<0;
   if(meopt==Initialize) {
     ScalarWaveFunction::
       calculateWaveFunctions(rho_,const_ptr_cast<tPPtr>(&inpart),incoming);
     swave_ = ScalarWaveFunction(inpart.momentum(),inpart.dataPtr(),incoming);
+    // fix rho if no correlations
+    fixRho(rho_);
   }
   if(meopt==Terminate) {
     ScalarWaveFunction::
       constructSpinInfo(const_ptr_cast<tPPtr>(&inpart),incoming,true);
     if(ferm) {
       RSSpinorBarWaveFunction::
 	constructSpinInfo(RSwavebar_,decay[irs],outgoing,true);
       SpinorWaveFunction::
 	constructSpinInfo(wave_     ,decay[ifm],outgoing,true);
     }
     else {
       RSSpinorWaveFunction::
 	constructSpinInfo(RSwave_ ,decay[irs],outgoing,true);
       SpinorBarWaveFunction::
 	constructSpinInfo(wavebar_,decay[ifm],outgoing,true);
     }
     return 0.;
   }
   if(ferm) {
     RSSpinorBarWaveFunction::
       calculateWaveFunctions(RSwavebar_,decay[irs],outgoing);
     SpinorWaveFunction::
       calculateWaveFunctions(wave_     ,decay[ifm],outgoing);
   }
   else {
     RSSpinorWaveFunction::
       calculateWaveFunctions(RSwave_ ,decay[irs],outgoing);
     SpinorBarWaveFunction::
       calculateWaveFunctions(wavebar_,decay[ifm],outgoing);
   }
   Energy2 scale(sqr(inpart.mass()));
   for(unsigned int ifm = 0; ifm < 4; ++ifm){
     for(unsigned int ia = 0; ia < 2; ++ia) {
       if(irs==0) {
 	if(ferm) {
 	  (*ME())(0, ifm, ia) = 0.;
 	  for(auto vert : vertex_)
 	    (*ME())(0, ifm, ia) += vert->evaluate(scale,wave_[ia],
 						  RSwavebar_[ifm],swave_);
 	}
 	else {
 	  (*ME())(0, ifm, ia) = 0.;
 	  for(auto vert : vertex_)
 	    (*ME())(0, ifm, ia) += vert->evaluate(scale,RSwave_[ifm],
 						  wavebar_[ia],swave_);
 	}
       }
       else {
 	if(ferm) {
 	  (*ME())(0, ia, ifm) = 0.;
 	  for(auto vert : vertex_)
 	    (*ME())(0, ia, ifm) += vert->evaluate(scale,wave_[ia],
 						  RSwavebar_[ifm],swave_);
 	}
 	else {
 	  (*ME())(0, ia, ifm) = 0.;
 	  for(auto vert : vertex_)
 	    (*ME())(0, ia, ifm) += vert->evaluate(scale,RSwave_[ifm],
 						  wavebar_[ia],swave_);
 	}
       }
     }
   }
   double output = (ME()->contract(rho_)).real()/scale*UnitRemoval::E2;
   // colour and identical particle factors
   output *= colourFactor(inpart.dataPtr(),decay[irs]->dataPtr(),
 			 decay[ifm]->dataPtr());
   // return the answer
   return output;
 }
 
 Energy SRFDecayer::partialWidth(PMPair inpart, PMPair outa, 
 				PMPair outb) const {
   if( inpart.second < outa.second + outb.second  ) return ZERO;
   if(perturbativeVertex_.size()==1 &&
      perturbativeVertex_[0]) {
     Energy q = inpart.second;
     Energy m1 = outa.second, m2 = outb.second;
     // couplings
     tcPDPtr in = inpart.first->CC() ? tcPDPtr(inpart.first->CC()) : inpart.first;
     if(outa.first->iSpin()==PDT::Spin1Half) {
       swap(m1,m2);
       perturbativeVertex_[0]->setCoupling(sqr(inpart.second),outb.first,
 				       outa.first, in);
     }
     else {
       perturbativeVertex_[0]->setCoupling(sqr(inpart.second),outa.first,
 				       outb.first, in);
     }
     Complex left  = perturbativeVertex_[0]-> left()*perturbativeVertex_[0]-> norm();
     Complex right = perturbativeVertex_[0]->right()*perturbativeVertex_[0]-> norm();
     complex<InvEnergy> A1 = 0.5*(left+right)*UnitRemoval::InvE;
     complex<InvEnergy> B1 = 0.5*(right-left)*UnitRemoval::InvE;
     Energy2 q2(q*q),m12(m1*m1),m22(m2*m2);
     Energy2 pcm2(0.25*(q2*(q2-2.*m12-2.*m22)+(m12-m22)*(m12-m22))/q2);
     Energy pcm(sqrt(pcm2));
     Energy Qp(sqrt(-sqr(m2+m1)+q2)),Qm(sqrt(-sqr(m2-m1)+q2));
     double r23(sqrt(2./3.));
     complex<Energy> h1(-2.*r23*pcm*q/m1*Qm*B1);
     complex<Energy> h2( 2.*r23*pcm*q/m1*Qp*A1);
     double me2 = real(h1*conj(h1)+h2*conj(h2))/2./sqr(inpart.second);
     Energy output = me2*pcm/8./Constants::pi;
     // colour factor
     output *= colourFactor(inpart.first,outa.first,outb.first);
     // return the answer
     return output;
   }
   else {
     return GeneralTwoBodyDecayer::partialWidth(inpart,outa,outb);
   }
 }
 
diff --git a/Decay/General/SSSDecayer.cc b/Decay/General/SSSDecayer.cc
--- a/Decay/General/SSSDecayer.cc
+++ b/Decay/General/SSSDecayer.cc
@@ -1,410 +1,412 @@
 // -*- C++ -*-
 //
 // SSSDecayer.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 SSSDecayer class.
 //
 
 #include "SSSDecayer.h"
 #include "ThePEG/Utilities/DescribeClass.h"
 #include "ThePEG/Interface/ClassDocumentation.h"
 #include "ThePEG/Persistency/PersistentOStream.h"
 #include "ThePEG/Persistency/PersistentIStream.h"
 #include "ThePEG/Helicity/WaveFunction/ScalarWaveFunction.h"
 #include "Herwig/Utilities/Kinematics.h"
 #include "Herwig/Decay/GeneralDecayMatrixElement.h"
 
 using namespace Herwig;
 using namespace ThePEG::Helicity;
 
 IBPtr SSSDecayer::clone() const {
   return new_ptr(*this);
 }
 
 IBPtr SSSDecayer::fullclone() const {
   return new_ptr(*this);
 }
 
 void SSSDecayer::setDecayInfo(PDPtr incoming, PDPair outgoing,
 			      vector<VertexBasePtr> vertex,
 			      map<ShowerInteraction,VertexBasePtr> & inV,
 			      const vector<map<ShowerInteraction,VertexBasePtr> > & outV,
 			      map<ShowerInteraction,VertexBasePtr> ) {
   decayInfo(incoming,outgoing);
   for(auto vert : vertex) {
     vertex_            .push_back(dynamic_ptr_cast<AbstractSSSVertexPtr>(vert));
     perturbativeVertex_.push_back(dynamic_ptr_cast<SSSVertexPtr>        (vert));
   }
   vector<ShowerInteraction> itemp={ShowerInteraction::QCD,ShowerInteraction::QED};
   for(auto & inter : itemp) {
     incomingVertex_[inter] = dynamic_ptr_cast<AbstractVSSVertexPtr>(inV.at(inter));
     outgoingVertex1_[inter] = dynamic_ptr_cast<AbstractVSSVertexPtr>(outV[0].at(inter));
     outgoingVertex2_[inter] = dynamic_ptr_cast<AbstractVSSVertexPtr>(outV[1].at(inter));
   }
 }
 
 void SSSDecayer::persistentOutput(PersistentOStream & os) const {
   os << vertex_           << perturbativeVertex_
      << incomingVertex_   << outgoingVertex1_
      << outgoingVertex2_;
 }
 
 void SSSDecayer::persistentInput(PersistentIStream & is, int) {
   is >> vertex_           >> perturbativeVertex_
      >> incomingVertex_   >> outgoingVertex1_
      >> outgoingVertex2_;
 }
 
 // The following static variable is needed for the type
 // description system in ThePEG.
 DescribeClass<SSSDecayer,GeneralTwoBodyDecayer>
 describeHerwigSSSDecayer("Herwig::SSSDecayer", "Herwig.so");
 
 void SSSDecayer::Init() {
 
   static ClassDocumentation<SSSDecayer> documentation
     ("This class implements the decay of a scalar to 2 scalars.");
 
 }
 
 double SSSDecayer::me2(const int , const Particle & inpart,
 		       const ParticleVector & decay,
 		       MEOption meopt) const {
   if(!ME())
     ME(new_ptr(GeneralDecayMatrixElement(PDT::Spin0,PDT::Spin0,PDT::Spin0)));
   if(meopt==Initialize) {
     ScalarWaveFunction::
       calculateWaveFunctions(rho_,const_ptr_cast<tPPtr>(&inpart),incoming);
     swave_ = ScalarWaveFunction(inpart.momentum(),inpart.dataPtr(),incoming);
+    // fix rho if no correlations
+    fixRho(rho_);
   }
   if(meopt==Terminate) {
     ScalarWaveFunction::
       constructSpinInfo(const_ptr_cast<tPPtr>(&inpart),incoming,true);
     for(unsigned int ix=0;ix<2;++ix)
       ScalarWaveFunction::
 	constructSpinInfo(decay[ix],outgoing,true);
   }
   ScalarWaveFunction s1(decay[0]->momentum(),decay[0]->dataPtr(),outgoing);
   ScalarWaveFunction s2(decay[1]->momentum(),decay[1]->dataPtr(),outgoing);
   Energy2 scale(sqr(inpart.mass()));
   (*ME())(0,0,0) = 0.;
   for(auto vert : vertex_) {
     (*ME())(0,0,0) += vert->evaluate(scale,s1,s2,swave_);
   }
   double output = (ME()->contract(rho_)).real()/scale*UnitRemoval::E2;
   // colour and identical particle factors
   output *= colourFactor(inpart.dataPtr(),decay[0]->dataPtr(),
 			 decay[1]->dataPtr());
   // return the answer
   return output;
 }
 
 Energy SSSDecayer::partialWidth(PMPair inpart, PMPair outa, 
 				PMPair outb) const {
   if( inpart.second < outa.second + outb.second  ) return ZERO;
   if(perturbativeVertex_.size()==1 &&
      perturbativeVertex_[0] && !perturbativeVertex_[0]->kinematics()) {
     Energy2 scale(sqr(inpart.second));
     tcPDPtr in = inpart.first->CC() ? tcPDPtr(inpart.first->CC()) : inpart.first;
     perturbativeVertex_[0]->setCoupling(scale, in, outa.first, outb.first);
     Energy pcm = Kinematics::pstarTwoBodyDecay(inpart.second, outa.second,
 					       outb.second);
     double c2 = norm(perturbativeVertex_[0]->norm());
     Energy pWidth = c2*pcm/8./Constants::pi/scale*UnitRemoval::E2;
     // colour factor
     pWidth *= colourFactor(inpart.first,outa.first,outb.first);
     return pWidth;
   }
   else {
     return GeneralTwoBodyDecayer::partialWidth(inpart,outa,outb);
   }
 }
 
 double SSSDecayer::threeBodyME(const int , const Particle & inpart,
 			       const ParticleVector & decay,
 			       ShowerInteraction inter, MEOption meopt) {
   // work out which is the scalar and anti scalar
   int ianti(0), iscal(1), iglu(2);
   int itype[2];
   for(unsigned int ix=0;ix<2;++ix) {
     if(decay[ix]->dataPtr()->CC()) itype[ix] = decay[ix]->id()>0 ? 0:1;
     else                           itype[ix] = 2;
   }
   if(itype[0]==0 && itype[1]!=0) swap(ianti, iscal);
   if(itype[0]==2 && itype[1]==1) swap(ianti, iscal);
   if(itype[0]==0 && itype[1]==0 && abs(decay[0]->dataPtr()->id())>abs(decay[1]->dataPtr()->id())) 
     swap(iscal, ianti);
   if(itype[0]==1 && itype[1]==1 && abs(decay[0]->dataPtr()->id())<abs(decay[1]->dataPtr()->id())) 
     swap(iscal, ianti);
 
   if(meopt==Initialize) {
     // create scalar wavefunction for decaying particle
     ScalarWaveFunction::calculateWaveFunctions(rho3_,const_ptr_cast<tPPtr>(&inpart),incoming);
     swave3_ = ScalarWaveFunction(inpart.momentum(),inpart.dataPtr(),incoming);
   }
   // setup spin information when needed
   if(meopt==Terminate) {
     ScalarWaveFunction::
       constructSpinInfo(const_ptr_cast<tPPtr>(&inpart),incoming,true);
     ScalarWaveFunction::
       constructSpinInfo(decay[iscal],outgoing,true);
     ScalarWaveFunction::
       constructSpinInfo(decay[ianti],outgoing,true);
     VectorWaveFunction::
       constructSpinInfo(gluon_,decay[iglu ],outgoing,true,false);
     return 0.;
   }
   // calculate colour factors and number of colour flows
   unsigned int nflow;
   vector<DVector> cfactors = getColourFactors(inpart, decay, nflow);
 
   vector<GeneralDecayMEPtr> ME(nflow,new_ptr(GeneralDecayMatrixElement(PDT::Spin0, PDT::Spin0,
 								       PDT::Spin0, PDT::Spin1)));
 
   // create wavefunctions
   ScalarWaveFunction scal(decay[iscal]->momentum(), decay[iscal]->dataPtr(),outgoing);
   ScalarWaveFunction anti(decay[ianti]->momentum(), decay[ianti]->dataPtr(),outgoing);
   VectorWaveFunction::calculateWaveFunctions(gluon_,decay[iglu ],outgoing,true);
 
   // gauge invariance test
 #ifdef GAUGE_CHECK
   gluon_.clear();
   for(unsigned int ix=0;ix<3;++ix) {
     if(ix==1) gluon_.push_back(VectorWaveFunction());
     else {
       gluon_.push_back(VectorWaveFunction(decay[iglu ]->momentum(),
 					  decay[iglu ]->dataPtr(),10,
 					  outgoing));
     }
   }
 #endif
 
   AbstractVSSVertexPtr outgoingVertexS;
   AbstractVSSVertexPtr outgoingVertexA;
   identifyVertices(iscal, ianti, inpart, decay, outgoingVertexS, outgoingVertexA,inter);
 
   Energy2 scale(sqr(inpart.mass()));
 
   const GeneralTwoBodyDecayer::CFlow & colourFlow
         = colourFlows(inpart, decay);
   double gs(0.);
   bool couplingSet(false);
 #ifdef GAUGE_CHECK
   double total=0.;
 #endif
   for(unsigned int ig = 0; ig < 2; ++ig) {
     // radiation from the incoming scalar
     if((inpart.dataPtr()->coloured() && inter==ShowerInteraction::QCD) ||
        (inpart.dataPtr()->charged()  && inter==ShowerInteraction::QED) ) {
       assert(incomingVertex_[inter]);
       ScalarWaveFunction scalarInter = 
 	incomingVertex_[inter]->evaluate(scale,3,inpart.dataPtr(),
 					  gluon_[2*ig],swave3_,inpart.mass());
 
       assert(swave3_.particle()->id()==scalarInter.particle()->id());
 
       Complex diag = 0.;
       for(auto vertex : vertex_)
 	diag += vertex->evaluate(scale,scal,anti,scalarInter);
       if(!couplingSet) {
 	gs = abs(incomingVertex_[inter]->norm());
 	couplingSet = true;
       }
       for(unsigned int ix=0;ix<colourFlow[0].size();++ix) {
 	(*ME[colourFlow[0][ix].first])(0, 0, 0, ig) += 
 	   colourFlow[0][ix].second*diag; 
       }
 #ifdef GAUGE_CHECK
       total+=norm(diag);
 #endif
     }
     // radiation from the outgoing scalar
     if((decay[iscal]->dataPtr()->coloured() && inter==ShowerInteraction::QCD) ||
        (decay[iscal]->dataPtr()->charged()  && inter==ShowerInteraction::QED) ) {
       assert(outgoingVertexS);
       // ensure you get correct outgoing particle from first vertex
       tcPDPtr off = decay[iscal]->dataPtr();
       if(off->CC()) off = off->CC();
       ScalarWaveFunction scalarInter = 
 	outgoingVertexS->evaluate(scale,3,off,gluon_[2*ig],scal,decay[iscal]->mass());
 
       assert(scal.particle()->id()==scalarInter.particle()->id());
 
       Complex diag = 0.;
       for(auto vertex : vertex_)
 	diag += vertex->evaluate(scale,swave3_,anti,scalarInter);
       if(!couplingSet) {
 	gs = abs(outgoingVertexS->norm());
 	couplingSet = true;
       }
       for(unsigned int ix=0;ix<colourFlow[1].size();++ix) {
 	(*ME[colourFlow[1][ix].first])(0, 0, 0, ig) += 
 	   colourFlow[1][ix].second*diag;
       }
 #ifdef GAUGE_CHECK
       total+=norm(diag);
 #endif
     }
     // radiation from the outgoing anti scalar
     if((decay[ianti]->dataPtr()->coloured() && inter==ShowerInteraction::QCD) ||
        (decay[ianti]->dataPtr()->charged()  && inter==ShowerInteraction::QED) ) {
       assert(outgoingVertexA);
       // ensure you get correct outgoing particle from first vertex
       tcPDPtr off = decay[ianti]->dataPtr();
       if(off->CC()) off = off->CC();
       ScalarWaveFunction scalarInter = 
 	outgoingVertexA->evaluate(scale,3,off, gluon_[2*ig],anti,decay[ianti]->mass());
 
       assert(anti.particle()->id()==scalarInter.particle()->id());
 
       Complex diag = 0.;
       for(auto vertex : vertex_)
 	diag += vertex->evaluate(scale,swave3_,scal,scalarInter);
       if(!couplingSet) {
 	gs = abs(outgoingVertexA->norm());
 	couplingSet = true;
       }
       for(unsigned int ix=0;ix<colourFlow[2].size();++ix) {
 	(*ME[colourFlow[2][ix].first])(0, 0, 0, ig) += 
 	  colourFlow[2][ix].second*diag;
       }
 #ifdef GAUGE_CHECK
       total+=norm(diag);
 #endif
     }
   }
 
   // contract matrices 
   double output=0.;
   for(unsigned int ix=0; ix<nflow; ++ix){
     for(unsigned int iy=0; iy<nflow; ++iy){
       output+=cfactors[ix][iy]*(ME[ix]->contract(*ME[iy],rho3_)).real();
     }
   }
   // divide by alpha_(S,EM)
   output*=(4.*Constants::pi)/sqr(gs);
 #ifdef GAUGE_CHECK
   double ratio = output/total;
   if(abs(ratio)>1e-20) {
     generator()->log() << "Test of gauge invariance in decay\n" << inpart << "\n";
     for(unsigned int ix=0;ix<decay.size();++ix)
       generator()->log() << *decay[ix] << "\n";
     generator()->log() << "Test of gauge invariance " << ratio << "\n";
   }
 #endif
   // return the answer
   return output;
 }
 
 
 void SSSDecayer::identifyVertices(const int iscal, const int ianti,
 				  const Particle & inpart, const ParticleVector & decay, 
 				  AbstractVSSVertexPtr & outgoingVertexS, 
 				  AbstractVSSVertexPtr & outgoingVertexA,
 				  ShowerInteraction inter){
   // QCD
   if(inter==ShowerInteraction::QCD) {
     // work out which scalar each outgoing vertex corresponds to 
     // two outgoing vertices
     if( inpart.dataPtr()       ->iColour()==PDT::Colour0     &&
 	((decay[iscal]->dataPtr()->iColour()==PDT::Colour3     &&
 	  decay[ianti]->dataPtr()->iColour()==PDT::Colour3bar) ||
 	 (decay[iscal]->dataPtr()->iColour()==PDT::Colour8     &&
 	  decay[ianti]->dataPtr()->iColour()==PDT::Colour8))){
       if(outgoingVertex1_[inter]==outgoingVertex2_[inter]){
 	outgoingVertexS = outgoingVertex1_[inter];
 	outgoingVertexA = outgoingVertex2_[inter];
       }
       else if (outgoingVertex1_[inter]->isIncoming(getParticleData(decay[iscal]->id()))){
 	outgoingVertexS = outgoingVertex1_[inter];
 	outgoingVertexA = outgoingVertex2_[inter];
       }
       else if (outgoingVertex2_[inter]->isIncoming(getParticleData(decay[iscal]->id()))){
 	outgoingVertexS = outgoingVertex2_[inter];
 	outgoingVertexA = outgoingVertex1_[inter];
       }
     }
     else if(inpart.dataPtr()       ->iColour()==PDT::Colour8 &&
 	    decay[iscal]->dataPtr()->iColour()==PDT::Colour3 &&
 	    decay[ianti]->dataPtr()->iColour()==PDT::Colour3bar){
       if(outgoingVertex1_[inter]==outgoingVertex2_[inter]){
 	outgoingVertexS = outgoingVertex1_[inter];
 	outgoingVertexA = outgoingVertex2_[inter];
       }
       else if (outgoingVertex1_[inter]->isIncoming(getParticleData(decay[iscal]->id()))){
 	outgoingVertexS = outgoingVertex1_[inter];
 	outgoingVertexA = outgoingVertex2_[inter];
       }
       else if (outgoingVertex2_[inter]->isIncoming(getParticleData(decay[iscal]->id()))){
 	outgoingVertexS = outgoingVertex2_[inter];
 	outgoingVertexA = outgoingVertex1_[inter];
       }
     }
     // one outgoing vertex
     else if(inpart.dataPtr()    ->iColour()==PDT::Colour3){ 
       if(decay[iscal]->dataPtr()->iColour()==PDT::Colour3 &&  
 	 decay[ianti]->dataPtr()->iColour()==PDT::Colour0){
 	if     (outgoingVertex1_[inter]) outgoingVertexS = outgoingVertex1_[inter];
 	else if(outgoingVertex2_[inter]) outgoingVertexS = outgoingVertex2_[inter]; 
       }
       else if (decay[iscal]->dataPtr()->iColour()==PDT::Colour3 &&  
 	       decay[ianti]->dataPtr()->iColour()==PDT::Colour8){
 	if (outgoingVertex1_[inter]->isIncoming(getParticleData(decay[ianti]->dataPtr()->id()))){
 	  outgoingVertexS = outgoingVertex2_[inter];
 	  outgoingVertexA = outgoingVertex1_[inter];
 	}
 	else {
 	  outgoingVertexS = outgoingVertex1_[inter];
 	  outgoingVertexA = outgoingVertex2_[inter];
 	}
       }
     }
     else if(inpart.dataPtr()    ->iColour()==PDT::Colour3bar){
       if(decay[ianti]->dataPtr()->iColour()==PDT::Colour3bar &&  
 	 decay[iscal]->dataPtr()->iColour()==PDT::Colour0){
 	if     (outgoingVertex1_[inter]) outgoingVertexA = outgoingVertex1_[inter];
 	else if(outgoingVertex2_[inter]) outgoingVertexA = outgoingVertex2_[inter];
       }
       else if (decay[ianti]->dataPtr()->iColour()==PDT::Colour3bar &&  
 	       decay[iscal]->dataPtr()->iColour()==PDT::Colour8){
 	if (outgoingVertex1_[inter]->isIncoming(getParticleData(decay[iscal]->dataPtr()->id()))){
 	  outgoingVertexS = outgoingVertex1_[inter];
 	  outgoingVertexA = outgoingVertex2_[inter];
 	}
 	else {
 	  outgoingVertexS = outgoingVertex2_[inter];
 	  outgoingVertexA = outgoingVertex1_[inter];
 	}
       }
     }
     
     if (! ((incomingVertex_[inter]  && (outgoingVertexS || outgoingVertexA)) ||
 	   ( outgoingVertexS &&  outgoingVertexA)))
       throw Exception()
 	<< "Invalid vertices for QCD radiation in SSS decay in SSSDecayer::identifyVertices"
 	<< Exception::runerror;
   }
   // QED
   else {
     if(decay[iscal]->dataPtr()->charged()) {
       if (outgoingVertex1_[inter] &&
 	  outgoingVertex1_[inter]->isIncoming(const_ptr_cast<tPDPtr>(decay[iscal]->dataPtr())))
 	outgoingVertexS = outgoingVertex1_[inter];
       else
 	outgoingVertexS = outgoingVertex2_[inter];
     }
     if(decay[ianti]->dataPtr()->charged()) {
       if (outgoingVertex1_[inter] &&
 	  outgoingVertex1_[inter]->isIncoming(const_ptr_cast<tPDPtr>(decay[ianti]->dataPtr())))
 	outgoingVertexA = outgoingVertex1_[inter];
       else
 	outgoingVertexA = outgoingVertex2_[inter];
     }
   }
 }
diff --git a/Decay/General/SSVDecayer.cc b/Decay/General/SSVDecayer.cc
--- a/Decay/General/SSVDecayer.cc
+++ b/Decay/General/SSVDecayer.cc
@@ -1,366 +1,368 @@
 // -*- C++ -*-
 //
 // SSVDecayer.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 SSVDecayer class.
 //
 
 #include "SSVDecayer.h"
 #include "ThePEG/Utilities/DescribeClass.h"
 #include "ThePEG/Interface/ClassDocumentation.h"
 #include "ThePEG/Persistency/PersistentOStream.h"
 #include "ThePEG/Persistency/PersistentIStream.h"
 #include "ThePEG/PDT/DecayMode.h"
 #include "Herwig/Utilities/Kinematics.h"
 #include "ThePEG/Helicity/WaveFunction/ScalarWaveFunction.h"
 #include "ThePEG/Helicity/WaveFunction/VectorWaveFunction.h"
 #include "Herwig/Decay/GeneralDecayMatrixElement.h"
 using namespace Herwig;
 using namespace ThePEG::Helicity;
 
 IBPtr SSVDecayer::clone() const {
   return new_ptr(*this);
 }
 
 IBPtr SSVDecayer::fullclone() const {
   return new_ptr(*this);
 }
 
 void SSVDecayer::setDecayInfo(PDPtr incoming, PDPair outgoing,
 			      vector<VertexBasePtr> vertex,
 			      map<ShowerInteraction,VertexBasePtr> & inV,
 			      const vector<map<ShowerInteraction,VertexBasePtr> > & outV,
 			      map<ShowerInteraction,VertexBasePtr> fourV) {
   decayInfo(incoming,outgoing);
   for(auto vert : vertex) {
     vertex_            .push_back(dynamic_ptr_cast<AbstractVSSVertexPtr>(vert));
     perturbativeVertex_.push_back(dynamic_ptr_cast<VSSVertexPtr>        (vert));
   }
   vector<ShowerInteraction> itemp={ShowerInteraction::QCD,ShowerInteraction::QED};
   for(auto & inter : itemp) {
     incomingVertex_[inter]  = dynamic_ptr_cast<AbstractVSSVertexPtr>(inV.at(inter));
     fourPointVertex_[inter] = dynamic_ptr_cast<AbstractVVSSVertexPtr>(fourV.at(inter));
     outgoingVertexS_[inter] = AbstractVSSVertexPtr();
     outgoingVertexV_[inter] = AbstractVVVVertexPtr();  
     if(outV[0].at(inter)) {
       if (outV[0].at(inter)->getName()==VertexType::VSS)
 	outgoingVertexS_[inter]   = dynamic_ptr_cast<AbstractVSSVertexPtr>(outV[0].at(inter));
       else
 	outgoingVertexV_[inter]   = dynamic_ptr_cast<AbstractVVVVertexPtr>(outV[0].at(inter));
     }
     if(outV[1].at(inter)) {
       if (outV[1].at(inter)->getName()==VertexType::VSS)
 	outgoingVertexS_[inter]   = dynamic_ptr_cast<AbstractVSSVertexPtr>(outV[1].at(inter));
       else 
 	outgoingVertexV_[inter]   = dynamic_ptr_cast<AbstractVVVVertexPtr>(outV[1].at(inter));
     }
   }
 }
 
 void SSVDecayer::persistentOutput(PersistentOStream & os) const {
   os << vertex_           << perturbativeVertex_
      << incomingVertex_   << outgoingVertexS_
      << outgoingVertexV_  << fourPointVertex_;
 }
 
 void SSVDecayer::persistentInput(PersistentIStream & is, int) {
   is >> vertex_           >> perturbativeVertex_
      >> incomingVertex_   >> outgoingVertexS_
      >> outgoingVertexV_  >> fourPointVertex_;
 }
 
 // The following static variable is needed for the type
 // description system in ThePEG.
 DescribeClass<SSVDecayer,GeneralTwoBodyDecayer>
 describeHerwigSSVDecayer("Herwig::SSVDecayer", "Herwig.so");
 
 void SSVDecayer::Init() {
 
   static ClassDocumentation<SSVDecayer> documentation
     ("This implements the decay of a scalar to a vector and a scalar");
 
 }
 
 double SSVDecayer::me2(const int , const Particle & inpart,
 		       const ParticleVector & decay,
 		       MEOption meopt) const {
   unsigned int isc(0),ivec(1);
   if(decay[0]->dataPtr()->iSpin() != PDT::Spin0) swap(isc,ivec);
   if(!ME()) {
     if(ivec==1)
       ME(new_ptr(GeneralDecayMatrixElement(PDT::Spin0,PDT::Spin0,PDT::Spin1)));
     else
       ME(new_ptr(GeneralDecayMatrixElement(PDT::Spin0,PDT::Spin1,PDT::Spin0)));
   }
   if(meopt==Initialize) {
     ScalarWaveFunction::
       calculateWaveFunctions(rho_,const_ptr_cast<tPPtr>(&inpart),incoming);
     swave_ = ScalarWaveFunction(inpart.momentum(),inpart.dataPtr(),incoming);
+    // fix rho if no correlations
+    fixRho(rho_);
   }
   if(meopt==Terminate) {
     ScalarWaveFunction::
       constructSpinInfo(const_ptr_cast<tPPtr>(&inpart),incoming,true);
     ScalarWaveFunction::
       constructSpinInfo(decay[isc],outgoing,true);
     VectorWaveFunction::
       constructSpinInfo(vector_,decay[ivec],outgoing,true,false);
   }
   VectorWaveFunction::
     calculateWaveFunctions(vector_,decay[ivec],outgoing,false);
   ScalarWaveFunction sca(decay[isc]->momentum(),decay[isc]->dataPtr(),outgoing);
   Energy2 scale(sqr(inpart.mass()));
   //make sure decay matrix element is in the correct order
   double output(0.);
   if(ivec == 0) {
     for(unsigned int ix = 0; ix < 3; ++ix) {
       (*ME())(0, ix, 0) = 0.;
       for(auto vert : vertex_)
 	(*ME())(0, ix, 0) += vert->evaluate(scale,vector_[ix],sca, swave_);
     }
   }
   else {
     for(unsigned int ix = 0; ix < 3; ++ix) {
       (*ME())(0, 0, ix) = 0.;
       for(auto vert : vertex_)
 	(*ME())(0, 0, ix) += vert->evaluate(scale,vector_[ix],sca,swave_);
     }
   }
   output = (ME()->contract(rho_)).real()/scale*UnitRemoval::E2;
   // colour and identical particle factors
   output *= colourFactor(inpart.dataPtr(),decay[0]->dataPtr(),
 			 decay[1]->dataPtr());
   // return the answer
   return output;
 }
 
 Energy SSVDecayer:: partialWidth(PMPair inpart, PMPair outa, 
 				 PMPair outb) const {
   if( inpart.second < outa.second + outb.second  ) return ZERO;
   if(perturbativeVertex_.size()==1 &&
      perturbativeVertex_[0]) {
     double mu1sq(sqr(outa.second/inpart.second)),
       mu2sq(sqr(outb.second/inpart.second));
     tcPDPtr in = inpart.first->CC() ? tcPDPtr(inpart.first->CC()) : inpart.first;
     if(outa.first->iSpin() == PDT::Spin0) {
       perturbativeVertex_[0]->setCoupling(sqr(inpart.second), outb.first, outa.first,in);
     }
     else {
       swap(mu1sq,mu2sq);
       perturbativeVertex_[0]->setCoupling(sqr(inpart.second), outa.first, outb.first,in);
     }
     double me2(0.);
     if(mu2sq == 0.) 
       me2 = -2.*mu1sq - 2.;
     else
       me2 = ( sqr(mu2sq - mu1sq) - 2.*(mu2sq + mu1sq) + 1. )/mu2sq;
     Energy pcm = Kinematics::pstarTwoBodyDecay(inpart.second, outa.second,
 					       outb.second);
     Energy output = pcm*me2*norm(perturbativeVertex_[0]->norm())/8./Constants::pi;
     // colour factor
     output *= colourFactor(inpart.first,outa.first,outb.first);
     // return the answer
     return output;
   }
   else {
     return GeneralTwoBodyDecayer::partialWidth(inpart,outa,outb);
   }
 }
 
 
 double  SSVDecayer::threeBodyME(const int , const Particle & inpart,
 				const ParticleVector & decay,
 				ShowerInteraction inter, MEOption meopt) {
   int iscal (0), ivect (1), iglu (2);
   // get location of outgoing scalar/vector
   if(decay[1]->dataPtr()->iSpin()==PDT::Spin0) swap(iscal,ivect);
 
   if(meopt==Initialize) {
     // create scalar wavefunction for decaying particle
     ScalarWaveFunction::calculateWaveFunctions(rho3_,const_ptr_cast<tPPtr>(&inpart),incoming);
     swave3_ = ScalarWaveFunction(inpart.momentum(),inpart.dataPtr(),incoming);
   }
   // setup spin information when needed
   if(meopt==Terminate) {
     ScalarWaveFunction::
       constructSpinInfo(const_ptr_cast<tPPtr>(&inpart),incoming,true);
     ScalarWaveFunction::
       constructSpinInfo(decay[iscal],outgoing,true);
      VectorWaveFunction::
       constructSpinInfo(vector3_,decay[ivect],outgoing,true,false);
     VectorWaveFunction::
       constructSpinInfo(gluon_,  decay[iglu ],outgoing,true,false);
     return 0.;
   }
   // calculate colour factors and number of colour flows
   unsigned int nflow;
   vector<DVector> cfactors = getColourFactors(inpart, decay, nflow);
   vector<GeneralDecayMEPtr> ME(nflow,new_ptr(GeneralDecayMatrixElement(PDT::Spin0, PDT::Spin0,
 								       PDT::Spin1, PDT::Spin1)));
 
   // create wavefunctions
   ScalarWaveFunction scal(decay[iscal]->momentum(),  decay[iscal]->dataPtr(),outgoing);
   VectorWaveFunction::calculateWaveFunctions(vector3_,decay[ivect],outgoing,false);
   VectorWaveFunction::calculateWaveFunctions(gluon_,  decay[iglu ],outgoing,true );
 
   // gauge invariance test
 #ifdef GAUGE_CHECK
   gluon_.clear();
   for(unsigned int ix=0;ix<3;++ix) {
     if(ix==1) gluon_.push_back(VectorWaveFunction());
     else {
       gluon_.push_back(VectorWaveFunction(decay[iglu ]->momentum(),
   					  decay[iglu ]->dataPtr(),10,
   					  outgoing));
     }
   }
 #endif
 
   if (! ((incomingVertex_[inter]  && (outgoingVertexS_[inter] || outgoingVertexV_[inter])) ||
 	 (outgoingVertexS_[inter] &&  outgoingVertexV_[inter])))
     throw Exception()
       << "Invalid vertices for radiation in SSV decay in SSVDecayer::threeBodyME"
       << Exception::runerror;
 
 
   // sort out colour flows
   int S(1), V(2);
   if (decay[iscal]->dataPtr()->iColour()==PDT::Colour3bar && 
       decay[ivect]->dataPtr()->iColour()==PDT::Colour8)
     swap(S,V);
   else if (decay[ivect]->dataPtr()->iColour()==PDT::Colour3 && 
 	   decay[iscal]->dataPtr()->iColour()==PDT::Colour8)
     swap(S,V);
 
   Energy2 scale(sqr(inpart.mass()));
 
   const GeneralTwoBodyDecayer::CFlow & colourFlow
         = colourFlows(inpart, decay);
   double gs(0.);
   bool couplingSet(false);
 #ifdef GAUGE_CHECK
   double total=0.;
 #endif
   for(unsigned int iv = 0; iv < 3; ++iv) {
     for(unsigned int ig = 0; ig < 2; ++ig) {
       // radiation from the incoming scalar
       if((inpart.dataPtr()->coloured() && inter==ShowerInteraction::QCD) ||
 	 (inpart.dataPtr()->charged()  && inter==ShowerInteraction::QED) ) {
 	assert(incomingVertex_[inter]);
 	ScalarWaveFunction scalarInter = 
 	  incomingVertex_[inter]->evaluate(scale,3,inpart.dataPtr(),
 					   gluon_[2*ig],swave3_,inpart.mass());
 	
 	assert(swave3_.particle()->id()==scalarInter.particle()->id());
 	Complex diag = 0.;
 	for(auto vertex : vertex_)
 	  diag += vertex->evaluate(scale,vector3_[iv],scal,scalarInter);
 	if(!couplingSet) {
 	  gs = abs(incomingVertex_[inter]->norm());
 	  couplingSet = true;
 	}
 	for(unsigned int ix=0;ix<colourFlow[0].size();++ix) {
 	  (*ME[colourFlow[0][ix].first])(0, 0, iv, ig) += 
 	    colourFlow[0][ix].second*diag; 
 	}
 #ifdef GAUGE_CHECK
 	total+=norm(diag);
 #endif
       }
       // radiation from the outgoing scalar
       if((decay[iscal]->dataPtr()->coloured() && inter==ShowerInteraction::QCD) ||
 	 (decay[iscal]->dataPtr()->charged()  && inter==ShowerInteraction::QED) ) {
 	assert(outgoingVertexS_[inter]);
 	// ensure you get correct outgoing particle from first vertex
 	tcPDPtr off = decay[iscal]->dataPtr();
 	if(off->CC()) off = off->CC();
 	ScalarWaveFunction scalarInter = 
 	  outgoingVertexS_[inter]->evaluate(scale,3,off,gluon_[2*ig],scal,decay[iscal]->mass());
 	
 	assert(scal.particle()->id()==scalarInter.particle()->id());
 
 	if(!couplingSet) {
 	  gs = abs(outgoingVertexS_[inter]->norm());
 	  couplingSet = true;
 	}
 	Complex diag = 0.;
 	for(auto vertex : vertex_)
 	  diag += vertex->evaluate(scale,vector3_[iv],scalarInter,swave3_);
 	for(unsigned int ix=0;ix<colourFlow[S].size();++ix) {
 	  (*ME[colourFlow[S][ix].first])(0, 0, iv, ig) += 
 	    colourFlow[S][ix].second*diag;
 	}
 #ifdef GAUGE_CHECK
 	total+=norm(diag);
 #endif
       }
 
       // radiation from outgoing vector
       if((decay[ivect]->dataPtr()->coloured() && inter==ShowerInteraction::QCD) ||
 	 (decay[ivect]->dataPtr()->charged()  && inter==ShowerInteraction::QED) ) {
 	assert(outgoingVertexV_[inter]);
 	// ensure you get correct outgoing particle from first vertex
 	tcPDPtr off = decay[ivect]->dataPtr();
 	if(off->CC()) off = off->CC();
 	VectorWaveFunction  vectorInter = 
 	  outgoingVertexV_[inter]->evaluate(scale,3,off,gluon_[2*ig],
 					    vector3_[iv],decay[ivect]->mass());
 	
 	assert(vector3_[iv].particle()->id()==vectorInter.particle()->id());
 	
 	if(!couplingSet) {
 	  gs = abs(outgoingVertexV_[inter]->norm());
 	  couplingSet = true;
 	}	
 	Complex diag = 0.;
 	for(auto vertex : vertex_)
 	  diag += vertex->evaluate(scale,vectorInter,scal,swave3_);
 	for(unsigned int ix=0;ix<colourFlow[V].size();++ix) {
 	  (*ME[colourFlow[V][ix].first])(0, 0, iv, ig) += 
 	    colourFlow[V][ix].second*diag;
 	}
 #ifdef GAUGE_CHECK
 	total+=norm(diag);
 #endif
       }
       // radiation from 4 point vertex
       if (fourPointVertex_[inter]) {
 	Complex diag =  fourPointVertex_[inter]->evaluate(scale, gluon_[2*ig], vector3_[iv],
 							  scal, swave3_);
 	for(unsigned int ix=0;ix<colourFlow[3].size();++ix) {
 	  (*ME[colourFlow[3][ix].first])(0, 0, iv, ig) += 
 	     colourFlow[3][ix].second*diag;
 	}
 #ifdef GAUGE_CHECK
 	total+=norm(diag);
 #endif
       }
     }
   }
   
   // contract matrices
   double output=0.;
   for(unsigned int ix=0; ix<nflow; ++ix){
     for(unsigned int iy=0; iy<nflow; ++iy){
       output+=cfactors[ix][iy]*(ME[ix]->contract(*ME[iy],rho3_)).real();
     }
   }
   // divide by alpha_(S,EM)
   output*=(4.*Constants::pi)/sqr(gs);
 #ifdef GAUGE_CHECK
   double ratio = output/total;
   if(abs(ratio)>1e-20) {
     generator()->log() << "Test of gauge invariance in decay\n" << inpart << "\n";
     for(unsigned int ix=0;ix<decay.size();++ix)
       generator()->log() << *decay[ix] << "\n";
     generator()->log() << "Test of gauge invariance " << ratio << "\n";
   }
 #endif
   // return the answer
   return output;
 }
diff --git a/Decay/General/SVVDecayer.cc b/Decay/General/SVVDecayer.cc
--- a/Decay/General/SVVDecayer.cc
+++ b/Decay/General/SVVDecayer.cc
@@ -1,432 +1,434 @@
 // -*- C++ -*-
 //
 // SVVDecayer.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 SVVDecayer class.
 //
 
 #include "SVVDecayer.h"
 #include "ThePEG/Utilities/DescribeClass.h"
 #include "ThePEG/Interface/ClassDocumentation.h"
 #include "ThePEG/Persistency/PersistentOStream.h"
 #include "ThePEG/Persistency/PersistentIStream.h"
 #include "ThePEG/PDT/DecayMode.h"
 #include "ThePEG/Helicity/Vertex/Scalar/VVSVertex.h"
 #include "ThePEG/Helicity/WaveFunction/ScalarWaveFunction.h"
 #include "ThePEG/Helicity/WaveFunction/VectorWaveFunction.h"
 #include "Herwig/Utilities/Kinematics.h"
 #include "Herwig/Decay/GeneralDecayMatrixElement.h"
 
 using namespace Herwig;
 using namespace ThePEG::Helicity;
 
 IBPtr SVVDecayer::clone() const {
   return new_ptr(*this);
 }
 
 IBPtr SVVDecayer::fullclone() const {
   return new_ptr(*this);
 }
 
 void SVVDecayer::setDecayInfo(PDPtr incoming, PDPair outgoing,
 			      vector<VertexBasePtr> vertex,
 			      map<ShowerInteraction,VertexBasePtr> & inV,
 			      const vector<map<ShowerInteraction,VertexBasePtr> > & outV,
 			      map<ShowerInteraction,VertexBasePtr> ) {
   decayInfo(incoming,outgoing);
   for(auto vert : vertex) {
     vertex_            .push_back(dynamic_ptr_cast<AbstractVVSVertexPtr>(vert));
     perturbativeVertex_.push_back(dynamic_ptr_cast<VVSVertexPtr>        (vert));
   }
   vector<ShowerInteraction> itemp={ShowerInteraction::QCD,ShowerInteraction::QED};
   for(auto & inter : itemp) {
     incomingVertex_[inter] = dynamic_ptr_cast<AbstractVSSVertexPtr>(inV.at(inter));
     outgoingVertex1_[inter] = dynamic_ptr_cast<AbstractVVVVertexPtr>(outV[0].at(inter));
     outgoingVertex2_[inter] = dynamic_ptr_cast<AbstractVVVVertexPtr>(outV[1].at(inter));
   }
 }
 
 void SVVDecayer::persistentOutput(PersistentOStream & os) const {
   os << vertex_ << perturbativeVertex_
      << incomingVertex_   << outgoingVertex1_
      << outgoingVertex2_;
 }
 
 void SVVDecayer::persistentInput(PersistentIStream & is, int) {
   is >> vertex_ >> perturbativeVertex_
      >> incomingVertex_   >> outgoingVertex1_
      >> outgoingVertex2_;
 }
 
 // The following static variable is needed for the type
 // description system in ThePEG.
 DescribeClass<SVVDecayer,GeneralTwoBodyDecayer>
 describeHerwigSVVDecayer("Herwig::SVVDecayer", "Herwig.so");
 
 void SVVDecayer::Init() {
 
   static ClassDocumentation<SVVDecayer> documentation
     ("This implements the decay of a scalar to 2 vector bosons.");
 
 }
 
 double SVVDecayer::me2(const int , const Particle & inpart,
 		       const ParticleVector& decay, 
 		       MEOption meopt) const {
   if(!ME())
     ME(new_ptr(GeneralDecayMatrixElement(PDT::Spin0,PDT::Spin1,PDT::Spin1)));
   bool photon[2];
   for(unsigned int ix=0;ix<2;++ix)
     photon[ix] = decay[ix]->mass()==ZERO;
   if(meopt==Initialize) {
     ScalarWaveFunction::
       calculateWaveFunctions(rho_,const_ptr_cast<tPPtr>(&inpart),incoming);
     swave_ = ScalarWaveFunction(inpart.momentum(),inpart.dataPtr(),incoming);
+    // fix rho if no correlations
+    fixRho(rho_);
   }
   if(meopt==Terminate) {
     ScalarWaveFunction::
       constructSpinInfo(const_ptr_cast<tPPtr>(&inpart),incoming,true);
     for(unsigned int ix=0;ix<2;++ix)
       VectorWaveFunction::
 	constructSpinInfo(vectors_[ix],decay[ix],outgoing,true,photon[ix]);
   }
   for(unsigned int ix=0;ix<2;++ix)
     VectorWaveFunction::
       calculateWaveFunctions(vectors_[ix],decay[ix],outgoing,photon[ix]);
   
   
   Energy2 scale(sqr(inpart.mass()));
   unsigned int iv1,iv2;
   for(iv2 = 0; iv2 < 3; ++iv2) {
     if( photon[1] && iv2 == 1 ) ++iv2;
     for(iv1=0;iv1<3;++iv1) {
       if( photon[0] && iv1 == 1) ++iv1;
       (*ME())(0, iv1, iv2) = 0.;
       for(auto vert : vertex_)
 	(*ME())(0, iv1, iv2) += vert->evaluate(scale,vectors_[0][iv1],
 					       vectors_[1][iv2],swave_);
     }
   }
   double output = ME()->contract(rho_).real()/scale*UnitRemoval::E2;
   // colour and identical particle factors
   output *= colourFactor(inpart.dataPtr(),decay[0]->dataPtr(),
 			 decay[1]->dataPtr());
   // return the answer
   return output;
 }
 
 Energy SVVDecayer::partialWidth(PMPair inpart, PMPair outa, 
 				PMPair outb) const {
   if( inpart.second < outa.second + outb.second  ) return ZERO;
   if(perturbativeVertex_.size()==1 &&
      perturbativeVertex_[0]) {
     Energy2 scale(sqr(inpart.second));
     tcPDPtr in = inpart.first->CC() ? tcPDPtr(inpart.first->CC()) : inpart.first;
     perturbativeVertex_[0]->setCoupling(scale, outa.first , 
 				    outb.first, in);
     double mu1sq = sqr(outa.second/inpart.second);
     double mu2sq = sqr(outb.second/inpart.second);
     double m1pm2 = mu1sq + mu2sq;
     double me2(0.); 
     if( mu1sq > 0. && mu2sq > 0.)
       me2 = ( m1pm2*(m1pm2 - 2.) + 8.*mu1sq*mu2sq + 1.)/4./mu1sq/mu2sq;
     else if( mu1sq == 0. || mu2sq == 0. )
       me2 = 3.;
     else 
       me2 = 4.;
     
     Energy pcm = Kinematics::pstarTwoBodyDecay(inpart.second,outa.second,
 					outb.second);
     Energy output = norm(perturbativeVertex_[0]->norm())*
       me2*pcm/(8*Constants::pi)/scale*UnitRemoval::E2;
     // colour factor
     output *= colourFactor(inpart.first,outa.first,outb.first);
     // return the answer
     return output;
   }
   else {
     return GeneralTwoBodyDecayer::partialWidth(inpart,outa,outb);
   }
 }
 
 double SVVDecayer::threeBodyME(const int , const Particle & inpart,
 			       const ParticleVector & decay,
 			       ShowerInteraction inter, MEOption meopt) {
   if(meopt==Initialize) {
     // create scalar wavefunction for decaying particle
     ScalarWaveFunction::
       calculateWaveFunctions(rho3_,const_ptr_cast<tPPtr>(&inpart),incoming);
     swave3_ = ScalarWaveFunction(inpart.momentum(),inpart.dataPtr(),incoming);
   }
   if(meopt==Terminate) {
     ScalarWaveFunction::
       constructSpinInfo(const_ptr_cast<tPPtr>(&inpart),incoming,true);
     VectorWaveFunction::
       constructSpinInfo(vectors3_[0],decay[0],outgoing,true,false);
     VectorWaveFunction::
       constructSpinInfo(vectors3_[1],decay[1],outgoing,true,false);
     VectorWaveFunction::
       constructSpinInfo(gluon_      ,decay[2],outgoing,true,false);
     return 0.;
   }
   // calculate colour factors and number of colour flows
   unsigned int nflow;
   vector<DVector> cfactors = getColourFactors(inpart, decay, nflow);
   vector<GeneralDecayMEPtr> ME(nflow,new_ptr(GeneralDecayMatrixElement(PDT::Spin0, PDT::Spin1,
 								       PDT::Spin1, PDT::Spin1)));
   bool massless[2];
   for(unsigned int ix=0;ix<2;++ix)
     massless[ix] = decay[ix]->mass()!=ZERO;
   // create wavefunctions
   VectorWaveFunction::calculateWaveFunctions(vectors3_[0],decay[0],outgoing,massless[0]);
   VectorWaveFunction::calculateWaveFunctions(vectors3_[1],decay[1],outgoing,massless[1]);
   VectorWaveFunction::calculateWaveFunctions(gluon_      ,decay[2],outgoing,true);
 
   // gauge test
 #ifdef GAUGE_CHECK
   gluon_.clear();
   for(unsigned int ix=0;ix<3;++ix) {
     if(ix==1) gluon_.push_back(VectorWaveFunction());
     else {
       gluon_.push_back(VectorWaveFunction(decay[2]->momentum(),
   					  decay[2]->dataPtr(),10,
   					  outgoing));
     }
   }
 #endif
 
   // get the outgoing vertices
   AbstractVVVVertexPtr outgoingVertex1;
   AbstractVVVVertexPtr outgoingVertex2;
   identifyVertices(inpart,decay, outgoingVertex1, outgoingVertex2,inter);
 
   Energy2 scale(sqr(inpart.mass()));
 
   const GeneralTwoBodyDecayer::CFlow & colourFlow
         = colourFlows(inpart, decay);
   double gs(0.);
   bool couplingSet(false);
 #ifdef GAUGE_CHECK
   double total=0.;
 #endif
 
    for(unsigned int iv1 = 0; iv1 < 3; ++iv1) {
      if(massless[0] && iv1==1) continue;
      for(unsigned int iv2 = 0; iv2 < 3; ++iv2) {
        if(massless[1] && iv2==1) continue;
        for(unsigned int ig = 0; ig < 2; ++ig) {
 	 // radiation from the incoming vector
 	 if((inpart.dataPtr()->coloured() && inter==ShowerInteraction::QCD) ||
 	    (inpart.dataPtr()->charged()  && inter==ShowerInteraction::QED) ) {
 	   assert(incomingVertex_[inter]);	
 	   ScalarWaveFunction scalarInter = 
 	     incomingVertex_[inter]->evaluate(scale,3,inpart.dataPtr(),gluon_[2*ig],
 					      swave3_,inpart.mass());
 	
 	   assert(swave3_.particle()->id()==scalarInter.particle()->id());
 	
 	   Complex diag = 0.;
 	   for(auto vertex : vertex_)
 	     diag += vertex->evaluate(scale,vectors3_[0][iv1],
 				      vectors3_[1][iv2],scalarInter);
 	   if(!couplingSet) {
 	     gs = abs(incomingVertex_[inter]->norm());
 	     couplingSet = true;
 	   }
 	   for(unsigned int ix=0;ix<colourFlow[0].size();++ix) {
 	     (*ME[colourFlow[0][ix].first])(0, iv1, iv2, ig) += 
 	       colourFlow[0][ix].second*diag;
 	   }
 #ifdef GAUGE_CHECK
 	   total+=norm(diag);
 #endif
 	 }
 	 // radiation from the 1st outgoing vector
 	 if((decay[0]->dataPtr()->coloured() && inter==ShowerInteraction::QCD) ||
 	    (decay[0]->dataPtr()->charged()  && inter==ShowerInteraction::QED) ) {
 	   assert(outgoingVertex1);
 	// ensure you get correct outgoing particle from first vertex
 	   tcPDPtr off = decay[0]->dataPtr();
 	   if(off->CC()) off = off->CC();
 	   VectorWaveFunction vectorInter = 
 	     outgoingVertex1->evaluate(scale,3,off,gluon_[2*ig],vectors3_[0][iv1],decay[0]->mass());
 	   
 	   assert(vectors3_[0][iv1].particle()->id()==vectorInter.particle()->id());
 	 
 	   Complex diag =0.;
 	   for(auto vertex : vertex_)
 	     diag += vertex->evaluate(scale,vectorInter,vectors3_[1][iv2],swave3_);
 	   if(!couplingSet) {
 	     gs = abs(outgoingVertex1->norm());
 	     couplingSet = true;
 	   }
 	   for(unsigned int ix=0;ix<colourFlow[1].size();++ix) {
 	     (*ME[colourFlow[1][ix].first])(0, iv1, iv2, ig) += 
 	       colourFlow[1][ix].second*diag;
 	   }
 #ifdef GAUGE_CHECK
 	   total+=norm(diag);
 #endif
 	 }
 	 
 	 if((decay[1]->dataPtr()->coloured() && inter==ShowerInteraction::QCD) ||
 	    (decay[1]->dataPtr()->charged()  && inter==ShowerInteraction::QED) ) {
 	   assert(outgoingVertex2);
 	   // ensure you get correct outgoing particle from first vertex
 	   tcPDPtr off = decay[1]->dataPtr();
 	   if(off->CC()) off = off->CC();
 	   VectorWaveFunction vectorInter = 
 	     outgoingVertex2->evaluate(scale,3,off, gluon_[2*ig],vectors3_[1][iv2],decay[1]->mass());
 	
 	   assert(vectors3_[1][iv2].particle()->id()==vectorInter.particle()->id());
 	
 	   Complex diag = 0.;
 	   for(auto vertex : vertex_)
 	     diag += vertex->evaluate(scale,vectors3_[0][iv1],vectorInter,swave3_);
 	   if(!couplingSet) {
 	     gs = abs(outgoingVertex2->norm());
 	     couplingSet = true;
 	   }
 	   for(unsigned int ix=0;ix<colourFlow[2].size();++ix) {
 	     (*ME[colourFlow[2][ix].first])(0, iv1, iv2, ig) += 
 	       colourFlow[2][ix].second*diag;
 	   }
 #ifdef GAUGE_CHECK
 	   total+=norm(diag);
 #endif
 	 }
        }
      }
    }
 
   // contract matrices 
   double output=0.;
   for(unsigned int ix=0; ix<nflow; ++ix){
     for(unsigned int iy=0; iy<nflow; ++iy){
       output+=cfactors[ix][iy]*(ME[ix]->contract(*ME[iy],rho3_)).real();
     }
   }
   // divide by alpha_(S,EM)
   output*=(4.*Constants::pi)/sqr(gs);
 #ifdef GAUGE_CHECK
   double ratio = output/total;
   if(abs(ratio)>1e-20) {
     generator()->log() << "Test of gauge invariance in decay\n" << inpart << "\n";
     for(unsigned int ix=0;ix<decay.size();++ix)
       generator()->log() << *decay[ix] << "\n";
     generator()->log() << "Test of gauge invariance " << ratio << "\n";
   }
 #endif
   // return the answer
   return output;
 }
 
 void SVVDecayer::identifyVertices(const Particle & inpart, const ParticleVector & decay, 
 				  AbstractVVVVertexPtr & outgoingVertex1, 
 				  AbstractVVVVertexPtr & outgoingVertex2,
 				  ShowerInteraction inter) {
   if(inter==ShowerInteraction::QCD) {
     // work out which scalar each outgoing vertex corresponds to 
     // two outgoing vertices
     if( inpart.dataPtr()       ->iColour()==PDT::Colour0     &&
 	((decay[0]->dataPtr()->iColour()==PDT::Colour3     &&
 	  decay[1]->dataPtr()->iColour()==PDT::Colour3bar) ||
 	 (decay[0]->dataPtr()->iColour()==PDT::Colour8     &&
 	  decay[1]->dataPtr()->iColour()==PDT::Colour8))){
       if(outgoingVertex1_[inter]==outgoingVertex2_[inter]){
 	outgoingVertex1 = outgoingVertex1_[inter];
 	outgoingVertex2 = outgoingVertex2_[inter];
       }
       else if (outgoingVertex1_[inter]->isIncoming(getParticleData(decay[0]->id()))){
 	outgoingVertex1 = outgoingVertex1_[inter];
 	outgoingVertex2 = outgoingVertex2_[inter];
       }
       else if (outgoingVertex2_[inter]->isIncoming(getParticleData(decay[0]->id()))){
 	outgoingVertex1 = outgoingVertex2_[inter];
 	outgoingVertex2 = outgoingVertex1_[inter];
       }
     }
     else if(inpart.dataPtr()       ->iColour()==PDT::Colour8 &&
 	    decay[0]->dataPtr()->iColour()==PDT::Colour3 &&
 	    decay[1]->dataPtr()->iColour()==PDT::Colour3bar){
       if(outgoingVertex1_[inter]==outgoingVertex2_[inter]){
 	outgoingVertex1 = outgoingVertex1_[inter];
 	outgoingVertex2 = outgoingVertex2_[inter];
       }
       else if (outgoingVertex1_[inter]->isIncoming(getParticleData(decay[0]->id()))){
 	outgoingVertex1 = outgoingVertex1_[inter];
 	outgoingVertex2 = outgoingVertex2_[inter];
       }
       else if (outgoingVertex2_[inter]->isIncoming(getParticleData(decay[0]->id()))){
 	outgoingVertex1 = outgoingVertex2_[inter];
 	outgoingVertex2 = outgoingVertex1_[inter];
       }
     }
     
     // one outgoing vertex
     else if(inpart.dataPtr()->iColour()==PDT::Colour3){
       if(decay[0]->dataPtr()->iColour()==PDT::Colour3 &&  
 	 decay[1]->dataPtr()->iColour()==PDT::Colour0){
 	if     (outgoingVertex1_[inter]) outgoingVertex1 = outgoingVertex1_[inter];
 	else if(outgoingVertex2_[inter]) outgoingVertex1 = outgoingVertex2_[inter];
       }
       else if (decay[0]->dataPtr()->iColour()==PDT::Colour3 &&
 	       decay[1]->dataPtr()->iColour()==PDT::Colour8){
 	if (outgoingVertex1_[inter]->isIncoming(getParticleData(decay[1]->dataPtr()->id()))){
 	  outgoingVertex1 = outgoingVertex2_[inter];
 	  outgoingVertex2 = outgoingVertex1_[inter];
 	}
 	else {
 	  outgoingVertex1 = outgoingVertex1_[inter];
 	  outgoingVertex2 = outgoingVertex2_[inter];
 	}
       }
     }
     else if(inpart.dataPtr()->iColour()==PDT::Colour3bar){
       if(decay[1]->dataPtr()->iColour()==PDT::Colour3bar &&  
 	 decay[0]->dataPtr()->iColour()==PDT::Colour0){
 	if     (outgoingVertex1_[inter]) outgoingVertex2 = outgoingVertex1_[inter];
 	else if(outgoingVertex2_[inter]) outgoingVertex2 = outgoingVertex2_[inter];
       }
       else if (decay[0]->dataPtr()->iColour()==PDT::Colour8 &&
 	       decay[1]->dataPtr()->iColour()==PDT::Colour3bar){
 	if (outgoingVertex1_[inter]->isIncoming(getParticleData(decay[0]->dataPtr()->id()))){
 	  outgoingVertex1 = outgoingVertex1_[inter];
 	  outgoingVertex2 = outgoingVertex2_[inter];
 	}
 	else {
 	  outgoingVertex1 = outgoingVertex2_[inter];
 	  outgoingVertex2 = outgoingVertex1_[inter];
 	}
       }
     }
     
     if (! ((incomingVertex_[inter]  && (outgoingVertex1  || outgoingVertex2)) ||
 	   ( outgoingVertex1 &&  outgoingVertex2)))
       throw Exception()
 	<< "Invalid vertices for QCD radiation in SVV decay in SVVDecayer::identifyVertices"
 	<< Exception::runerror;
   }
   else {
     if(decay[0]->dataPtr()->charged()) {
       if (outgoingVertex1_[inter] &&
 	  outgoingVertex1_[inter]->isIncoming(const_ptr_cast<tPDPtr>(decay[0]->dataPtr())))
 	outgoingVertex1 = outgoingVertex1_[inter];
       else
 	outgoingVertex1 = outgoingVertex2_[inter];
     }
     if(decay[1]->dataPtr()->charged()) {
       if (outgoingVertex1_[inter] &&
 	  outgoingVertex1_[inter]->isIncoming(const_ptr_cast<tPDPtr>(decay[1]->dataPtr())))
 	outgoingVertex2 = outgoingVertex1_[inter];
       else
 	outgoingVertex2 = outgoingVertex2_[inter];
     }
   }
 }
diff --git a/Decay/General/StoFFFFDecayer.cc b/Decay/General/StoFFFFDecayer.cc
--- a/Decay/General/StoFFFFDecayer.cc
+++ b/Decay/General/StoFFFFDecayer.cc
@@ -1,1306 +1,1308 @@
 // -*- C++ -*-
 //
 // This is the implementation of the non-inlined, non-templated member
 // functions of the StoFFFFDecayer class.
 //
 
 #include "StoFFFFDecayer.h"
 #include "ThePEG/PDT/DecayMode.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 "Herwig/Decay/DecayPhaseSpaceMode.h"
 #include "ThePEG/Helicity/Vertex/Vector/FFVVertex.h"
 #include "ThePEG/Helicity/Vertex/Scalar/FFSVertex.h"
 #include "Herwig/Models/StandardModel/StandardModel.h"
 #include "Herwig/Decay/GeneralDecayMatrixElement.h"
 #include <numeric>
 
 using namespace Herwig;
 using namespace ThePEG::Helicity;
 
 
 namespace {
 
   inline bool isParticle(tPPtr part) {
     return part->id()>0 && part->dataPtr()->CC();
   }
   inline bool isAntiParticle(tPPtr part) {
     return part->id()<0 && part->dataPtr()->CC();
   }
   inline bool isMajorana(tPPtr part) {
     return !part->dataPtr()->CC();
   }
 
 }
 
 IBPtr StoFFFFDecayer::clone() const {
   return new_ptr(*this);
 }
 
 IBPtr StoFFFFDecayer::fullclone() const {
   return new_ptr(*this);
 }
 
 void StoFFFFDecayer::persistentOutput(PersistentOStream & os) const {
   os << firstVVS_ << firstVSS_ << firstSSS_ << firstFFS_
      << secondFFV_ << secondFFS_
      << thirdFFV_ << thirdFFS_ << sign_;
 }
 
 void StoFFFFDecayer::persistentInput(PersistentIStream & is, int) {
   is >> firstVVS_ >> firstVSS_ >> firstSSS_ >> firstFFS_
      >> secondFFV_ >> secondFFS_
      >> thirdFFV_ >> thirdFFS_ >> sign_;
 }
 
 DescribeClass<StoFFFFDecayer,GeneralFourBodyDecayer>
 describeStoFFFFDecayer("Herwig::StoFFFFDecayer", "Herwig.so");
 
 void StoFFFFDecayer::Init() {
 
   static ClassDocumentation<StoFFFFDecayer> documentation
     ("The StoFFFFDecayer class performs the 4-fermion "
      "decays of scalar particles in BSM models");
 
 }
 
 void StoFFFFDecayer::doinit() {
   GeneralFourBodyDecayer::doinit(); 
   unsigned int ndiags = getProcessInfo().size();
   firstVVS_ .resize(ndiags);
   firstVSS_ .resize(ndiags);
   firstSSS_ .resize(ndiags);
   firstFFS_ .resize(ndiags);
   secondFFV_.resize(ndiags);
   secondFFS_.resize(ndiags);  
   thirdFFV_ .resize(ndiags);
   thirdFFS_ .resize(ndiags);
   for(unsigned int ix = 0;ix < ndiags; ++ix) {
     const NBDiagram & current = getProcessInfo()[ix];
     // first vertex
     firstVVS_[ix] = dynamic_ptr_cast<AbstractVVSVertexPtr>(current.vertex);
     firstVSS_[ix] = dynamic_ptr_cast<AbstractVSSVertexPtr>(current.vertex);
     firstSSS_[ix] = dynamic_ptr_cast<AbstractSSSVertexPtr>(current.vertex);
     firstFFS_[ix] = dynamic_ptr_cast<AbstractFFSVertexPtr>(current.vertex);
     // get the other vertices
     const NBVertex & second = current.vertices.begin()->second.incoming ?
       current.vertices.begin()->second : (++current.vertices.begin())->second;
     // get the other vertices
     const NBVertex & third = current.vertices.begin()->second.incoming ?
       (++current.vertices.begin())->second : (++second.vertices.begin())->second;
     // second vertex
     secondFFV_[ix] = dynamic_ptr_cast<AbstractFFVVertexPtr>(second.vertex);
     secondFFS_[ix] = dynamic_ptr_cast<AbstractFFSVertexPtr>(second.vertex);  
     // third vertex
     thirdFFV_ [ix] = dynamic_ptr_cast<AbstractFFVVertexPtr>(third .vertex);
     thirdFFS_ [ix] = dynamic_ptr_cast<AbstractFFSVertexPtr>(third .vertex); 
     assert( ( firstVVS_[ix] ||  firstVSS_[ix] || 
 	      firstSSS_[ix] ||  firstFFS_[ix] ) && 
 	    (secondFFV_[ix] || secondFFS_[ix] ) &&
 	    ( thirdFFV_[ix] ||  thirdFFS_[ix] ));
     // NO sign
     int order = 
       current.channelType[0]*1000+current.channelType[1]*100+
       current.channelType[2]*10  +current.channelType[3];
     switch(order) {
     case 1234: case 1342: case 1423: 
     case 2143: case 2314: case 2431:
     case 3124: case 3241: case 3412:
     case 4132: case 4213: case 4321:
       sign_.push_back( 1.);
       break;
     case 1243: case 1324: case 1432:
     case 2134: case 2341: case 2413:
     case 3142: case 3214: case 3421:
     case 4123: case 4231: case 4312:
       sign_.push_back(-1.);
       break;
     default:
       assert(false);
     }
   }
 }
 
 double StoFFFFDecayer::me2(const int ichan, const Particle & inpart,
 			   const ParticleVector & decay, MEOption meopt) const {
   // particle or CC of particle
   bool cc = (*getProcessInfo().begin()).incoming->id() != inpart.id();
   // special handling or first/last call
   const vector<vector<double> > & cfactors(getColourFactors());
   const vector<vector<double> > & nfactors(getLargeNcColourFactors());
   const size_t ncf(numberOfFlows());
   Energy2 scale(sqr(inpart.mass()));
   if(meopt==Initialize) {
     ScalarWaveFunction::
       calculateWaveFunctions(rho_,const_ptr_cast<tPPtr>(&inpart),
 			     Helicity::incoming);
     swave_ = ScalarWaveFunction(inpart.momentum(),inpart.dataPtr(),
 				Helicity::incoming);
+    // fix rho if no correlations
+    fixRho(rho_);
   }
   // setup spin info when needed
   if(meopt==Terminate) {
     ScalarWaveFunction::
       constructSpinInfo(const_ptr_cast<tPPtr>(&inpart),
 			Helicity::incoming,true);
     // outgoing particles
     for(unsigned int ix = 0; ix < 4; ++ix) {
       SpinorWaveFunction::
       constructSpinInfo(outwave_[ix].first,decay[ix],Helicity::outgoing,true);
     }
   }
   // outgoing particles
   for(unsigned int ix = 0; ix < 4; ++ix) {
     SpinorWaveFunction::
       calculateWaveFunctions(outwave_[ix].first,decay[ix],Helicity::outgoing);
     outwave_[ix].second.resize(2);
     if(outwave_[ix].first[0].wave().Type() == SpinorType::u) {
       for(unsigned int iy = 0; iy < 2; ++iy) {
 	outwave_[ix].second[iy] = outwave_[ix].first[iy].bar();
 	outwave_[ix].first[iy].conjugate();
       }
     }
     else {
       for(unsigned int iy = 0; iy < 2; ++iy) {
 	outwave_[ix].second[iy] = outwave_[ix].first[iy].bar();
 	outwave_[ix].second[iy].conjugate();
       }
     }
   }
   // matrix element for the colour flows
   vector<Complex> flows(ncf, Complex(0.)),largeflows(ncf, Complex(0.));
   vector<GeneralDecayMEPtr> mes(ncf,new_ptr(GeneralDecayMatrixElement(PDT::Spin0,
 								      PDT::Spin1Half,PDT::Spin1Half,
 								      PDT::Spin1Half,PDT::Spin1Half)));
   vector<GeneralDecayMEPtr> mel(ncf,new_ptr(GeneralDecayMatrixElement(PDT::Spin0,
 								      PDT::Spin1Half,PDT::Spin1Half,
 								      PDT::Spin1Half,PDT::Spin1Half)));
   // calculate the matrix element
   unsigned int ihel[4];
   for(ihel[0] = 0; ihel[0] < 2; ++ihel[0]) {
     for(ihel[1] = 0; ihel[1] < 2; ++ihel[1]) {
       for(ihel[2] = 0; ihel[2] < 2; ++ihel[2]) {
 	for(ihel[3] = 0; ihel[3] < 2; ++ihel[3]) {
 	  flows = vector<Complex>(ncf, Complex(0.));
 	  largeflows = vector<Complex>(ncf, Complex(0.));
 	  unsigned int idiag=0;
 	  for(vector<NBDiagram>::const_iterator dit=getProcessInfo().begin();
 	      dit!=getProcessInfo().end();++dit) {
 	    if(ichan>=0&&diagramMap()[ichan]!=idiag) {
 	      ++idiag;
 	      continue;
 	    }
 	    // location of the particles
 	    int iloc[4];
 	    for(unsigned int ix=0;ix<4;++ix) iloc[ix] = dit->channelType[ix]-1;
 	    // NO sign
 	    double sign = sign_[idiag];
 	    // work out the type of topology
 	    bool topo = dit->vertices.begin()->second.incoming;
 	    const NBVertex & second = topo ? 
    	          dit->vertices.begin()  ->second :
 	      (++(dit->vertices.begin()))->second;
 	    const NBVertex & third = topo ?
 	      (++(dit->  vertices.begin()))->second :
 	      (++(second.vertices.begin()))->second;
 	    // extract the intermediates
 	    tPDPair inter = make_pair(second.incoming,
 				      third .incoming);
 	    if(    inter.second->CC()) inter.second = inter.second->CC();
 	    if(cc&&inter.first ->CC()) inter.first  = inter.first ->CC();
 	    if(cc&&inter.second->CC()) inter.second = inter.second->CC();
 	    // value for the diagram
 	    Complex diag(0.);
 	    // first compute the last part of the diagram
 	    VectorWaveFunction offVector2;
 	    ScalarWaveFunction offScalar2;
 	    // intermediate scalar
 	    if(inter.second->iSpin()==PDT::Spin0) {
 	      if( (isAntiParticle(decay[iloc[2]]) || isMajorana(decay[iloc[2]])) &&
 		   (isParticle   (decay[iloc[3]]) || isMajorana(decay[iloc[3]])) ) {
 		sign *= -1.;
 		offScalar2 = thirdFFS_[idiag]->
 		  evaluate(scale, widthOption(),inter.second,
 			   outwave_[iloc[2]].first [ihel[iloc[2]]],
 			   outwave_[iloc[3]].second[ihel[iloc[3]]]);
 	      }
 	      else {
 		offScalar2 = thirdFFS_[idiag]->
 		  evaluate(scale, widthOption(),inter.second,
 			   outwave_[iloc[3]].first [ihel[iloc[3]]],
 			   outwave_[iloc[2]].second[ihel[iloc[2]]]);
 	      }
 	    }
 	    // intermediate vector
 	    else if(inter.second->iSpin()==PDT::Spin1) {
 	      if( (isAntiParticle(decay[iloc[2]]) || isMajorana(decay[iloc[2]])) &&
 		   (isParticle(decay[iloc[3]])||isMajorana(decay[iloc[3]]))) {
 		sign *= -1.;
 		offVector2 = thirdFFV_[idiag]->
 		  evaluate(scale, widthOption(),inter.second,
 			   outwave_[iloc[2]].first [ihel[iloc[2]]],
 			   outwave_[iloc[3]].second[ihel[iloc[3]]]);
 	      }
 	      else {
 		offVector2 = thirdFFV_[idiag]->
 		  evaluate(scale, widthOption(),inter.second,
 			   outwave_[iloc[3]].first [ihel[iloc[3]]],
 			   outwave_[iloc[2]].second[ihel[iloc[2]]]);
 	      }
 	    }
 	    // unknown
 	    else
 	      assert(false);
 	    // first topology
 	    if(topo) {
 	      // first intermediate
 	      if(inter.first->CC()) inter.first = inter.first->CC();
 	      VectorWaveFunction offVector1;
 	      ScalarWaveFunction offScalar1;
 	      // intermeidate scalar
 	      if(inter.first->iSpin()==PDT::Spin0) {
 		if(decay[iloc[0]]->id()<0&&
 		   decay[iloc[1]]->id()>0) {
 		  sign *= -1.;
 		  offScalar1 = secondFFS_[idiag]->
 		    evaluate(scale, widthOption(),inter.first,
 			     outwave_[iloc[0]].first [ihel[iloc[0]]],
 			     outwave_[iloc[1]].second[ihel[iloc[1]]]);
 		}
 		else {
 		  offScalar1 = secondFFS_[idiag]->
 		    evaluate(scale, widthOption(),inter.first,
 			     outwave_[iloc[1]].first [ihel[iloc[1]]],
 			     outwave_[iloc[0]].second[ihel[iloc[0]]]);
 		}
 	      }
 	      // intermediate vector
 	      else if(inter.first->iSpin()==PDT::Spin1) {
 		if(decay[iloc[0]]->id()<0&&
 		   decay[iloc[1]]->id()>0) {
 		  sign *= -1.;
 		  offVector1 = secondFFV_[idiag]->
 		    evaluate(scale, widthOption(),inter.first,
 			     outwave_[iloc[0]].first [ihel[iloc[0]]],
 			     outwave_[iloc[1]].second[ihel[iloc[1]]]);
 		}
 		else {
 		  offVector1 = secondFFV_[idiag]->
 		    evaluate(scale, widthOption(),inter.first,
 			     outwave_[iloc[1]].first [ihel[iloc[1]]],
 			     outwave_[iloc[0]].second[ihel[iloc[0]]]);
 		}
 	      }
 	      // unknown
 	      else
 		assert(false);
 	      // put it all together	      
 	      if(inter.first->iSpin()==PDT::Spin0) {	      
 		if(inter.second->iSpin()==PDT::Spin0) {
 		  diag = firstSSS_[idiag]->
 		    evaluate(scale,swave_,offScalar1,offScalar2);
 		}
 		else if(inter.second->iSpin()==PDT::Spin1) {
 		  diag = firstVSS_[idiag]->
 		    evaluate(scale,offVector2,offScalar1,swave_);
 		}
 	      }
 	      else if(inter.first->iSpin()==PDT::Spin1) {	      
 		if(inter.second->iSpin()==PDT::Spin0) {
 		  diag = firstVSS_[idiag]->
 		    evaluate(scale,offVector1,offScalar2,swave_);
 		}
 		else if(inter.second->iSpin()==PDT::Spin1) {
 		  diag = firstVVS_[idiag]->
 		    evaluate(scale,offVector1,offVector2,swave_);
 		}
 	      }
 	    }
 	    // second topology
 	    else {
 	      if(((isAntiParticle(decay[iloc[0]]) || isMajorana(decay[iloc[0]]))&&
 		  (isParticle    (decay[iloc[1]]) || isMajorana(decay[iloc[1]])))) {
 		sign *= -1.;
 		SpinorWaveFunction    inters = firstFFS_[idiag]->
 		  evaluate(scale,widthOption(),inter.first,
 			   outwave_[iloc[0]].first [ihel[iloc[0]]],swave_);
 		if(inter.second->iSpin()==PDT::Spin0) {
 		  diag = secondFFS_[idiag]->
 		    evaluate(scale,inters,outwave_[iloc[1]].second[ihel[iloc[1]]],
 			     offScalar2);
 		}
 		else {
 		  diag = secondFFV_[idiag]->
 		    evaluate(scale,inters,outwave_[iloc[1]].second[ihel[iloc[1]]],
 			     offVector2);
 		}
 	      }
 	      else {
 		SpinorBarWaveFunction inters = firstFFS_[idiag]->
 		  evaluate(scale,widthOption(),inter.first,
 			   outwave_[iloc[0]].second[ihel[iloc[0]]],swave_);
 		if(inter.second->iSpin()==PDT::Spin0) {
 		  diag = secondFFS_[idiag]->
 		    evaluate(scale,outwave_[iloc[1]].first [ihel[iloc[1]]],inters,
 			     offScalar2);
 		}
 		else {
 		  diag = secondFFV_[idiag]->
 		    evaluate(scale,outwave_[iloc[1]].first [ihel[iloc[1]]],inters,
 			     offVector2);
 		}
 	      }
 	    }
  	    // apply NO sign
  	    diag *= sign;
 	    // matrix element for the different colour flows
 	    if(ichan<0) {
 	      for(unsigned iy = 0; iy < dit->colourFlow.size(); ++iy) {
 		flows[dit->colourFlow[iy].first - 1] += 
 		  dit->colourFlow[iy].second * diag;
 	      }
 	      for(unsigned iy = 0; iy < dit->largeNcColourFlow.size(); ++iy) {
 		largeflows[dit->largeNcColourFlow[iy].first - 1] += 
 		  dit->largeNcColourFlow[iy].second * diag;
 	      }
 	    }
 	    else {
 	      for(unsigned iy = 0; iy < dit->colourFlow.size(); ++iy) {
 		if(dit->colourFlow[iy].first - 1!=colourFlow()) continue;
 		flows[dit->colourFlow[iy].first - 1] += 
 		  dit->colourFlow[iy].second * diag;
 	      }
 	      for(unsigned iy = 0; iy < dit->largeNcColourFlow.size(); ++iy) {
 		if(dit->colourFlow[iy].first - 1!=colourFlow()) continue;
 		largeflows[dit->largeNcColourFlow[iy].first - 1] += 
 		  dit->largeNcColourFlow[iy].second * diag;
 	      }
 	    }
 	    ++idiag;
 	  }
 	  // now add the flows to the me2 with appropriate colour factors
 	  for(unsigned int ix = 0; ix < ncf; ++ix) {
 	    (*mes[ix])(0,ihel[0],ihel[1],ihel[2],ihel[3]) =      flows[ix];
 	    (*mel[ix])(0,ihel[0],ihel[1],ihel[2],ihel[3]) = largeflows[ix];
 	  }
 	}
       }
     }
   }
   double me2(0.);
   if(ichan<0) {
     vector<double> pflows(ncf,0.);
     for(unsigned int ix = 0; ix < ncf; ++ix) {
       for(unsigned int iy = 0; iy < ncf; ++ iy) {
 	double con = cfactors[ix][iy]*(mes[ix]->contract(*mes[iy],rho_)).real();
 	me2 += con;
 	if(ix==iy) {
 	  con = nfactors[ix][iy]*(mel[ix]->contract(*mel[iy],rho_)).real();
 	  pflows[ix] += con;
 	}
       }
     }
     double ptotal(std::accumulate(pflows.begin(),pflows.end(),0.));
     ptotal *=UseRandom::rnd();
     for(unsigned int ix=0;ix<pflows.size();++ix) {
       if(ptotal<=pflows[ix]) {
 	colourFlow(ix);
 	ME(mes[ix]);
 	break;
       }
       ptotal-=pflows[ix];
     }
   }
   else {
     unsigned int iflow = colourFlow();
     me2 = nfactors[iflow][iflow]*(mel[iflow]->contract(*mel[iflow],rho_)).real();
   }
   // return the matrix element squared
   return me2*scale*UnitRemoval::InvE2;
 }
 
 // OLD TESTING CODE
 
 // extracted from StandardModel.h
 // public:
 
 //   virtual void StopCouplings(Energy2 &,tcPDPtr, tcPDPtr,
 // 			     double &, double &, double &,
 // 			     Complex &, Complex &,
 // 			     vector<Complex> &, vector<Complex> &,
 // 			     vector<Complex> &, 
 // 			     vector<Complex> &, vector<Complex> &, 
 // 			     vector<Complex> &, vector<Complex> &, 
 // 			     vector<Complex> &, vector<Complex> &, 
 // 			     vector<vector<Complex> > &, vector<vector<Complex> > &, 
 // 			     vector<vector<Complex> > &, vector<vector<Complex> > &, 
 // 			     vector<Complex> &, vector<Complex> &, 
 // 			     vector<Complex> &, vector<Complex> &,
 // 			     double &, double &) {
 //     assert(false);
 //   }
 
 // extracted from RunningMass.cc
   // if(id==5) return 4.8787783899999999*GeV;
   // if(id==15) return 1.7770999999999999*GeV;
 
 // extracted from MSSM.h
 
 // public:
 
 //   virtual void StopCouplings(Energy2 &, tcPDPtr, tcPDPtr,
 // 			     double & g, double & sw, double & cw,
 // 			     Complex & aL, Complex & aR,
 // 			     vector<Complex> & cL, vector<Complex> & cR,
 // 			     vector<Complex> & d,
 // 			     vector<Complex> & bL, vector<Complex> & bR,
 // 			     vector<Complex> & kL, vector<Complex> & kR,
 // 			     vector<Complex> & fL, vector<Complex> & fR,
 // 			     vector<vector<Complex> > & eL, vector<vector<Complex> > & eR,
 // 			     vector<vector<Complex> > & gL, vector<vector<Complex> > & gR,
 // 			     vector<Complex> & hL, vector<Complex> & hR,
 // 			     vector<Complex> & lL, vector<Complex> & lR,
 // 			     double & ytop, double & ytau);
 
 // extracted from MSSM.cc
 
 // void MSSM::StopCouplings(Energy2 & scale, tcPDPtr ferm, tcPDPtr anti, double & g, double & sw, double & cw,
 // 			 Complex & aL, Complex & aR,
 // 			 vector<Complex> & cL, vector<Complex> & cR,
 // 			 vector<Complex> & d,
 // 			 vector<Complex> & bL, vector<Complex> & bR,
 // 			     vector<Complex> & kL, vector<Complex> & kR,
 // 			 vector<Complex> & fL, vector<Complex> & fR,
 // 			 vector<vector<Complex> > & eL, vector<vector<Complex> > & eR,
 // 			 vector<vector<Complex> > & gL, vector<vector<Complex> > & gR,
 // 			 vector<Complex> & hL, vector<Complex> & hR,
 // 			 vector<Complex> & lL, vector<Complex> & lR,
 // 			 double & ytop, double & ytau) {
 //   MixingMatrixPtr stop = stopMix();
 //   MixingMatrixPtr sbot = sbottomMix();
 //   MixingMatrixPtr stau = stauMix();
 //   MixingMatrixPtr neut = neutralinoMix();
 //   MixingMatrixPtr vmix = charginoVMix();
 //   MixingMatrixPtr umix = charginoUMix();
 //   sw = sqrt(   sin2ThetaW());
 //   cw = sqrt(1.-sin2ThetaW());
 //   g  =  sqrt(4.0*Constants::pi*alphaEMMZ()/sin2ThetaW());
 //   Energy mb = mass(scale,getParticleData(ParticleID::b));
 //   Energy mt = mass(scale,getParticleData(ParticleID::t));
 //   Energy mw = getParticleData(ParticleID::Wplus)->mass();
 //   double tb = tanBeta();
 //   double sb = tb/sqrt(1 + sqr(tb));
 //   double cb = sqrt(1 - sqr(sb));
 //   Complex n1prime = (*neut)(0,0)*cw + (*neut)(0,1)*sw;
 //   Complex n2prime = (*neut)(0,1)*cw - (*neut)(0,0)*sw;
 //   double yt =  double(mt/mw)/sb/sqrt(2.);
 //   Complex bracketl = 2./ 3.*sw*( conj(n1prime) - sw*conj(n2prime)/cw );
 //   Complex bracketr = 2./3.*sw*n1prime - n2prime*(-0.5 + 2./3.*sqr(sw))/cw;
 //   ytop = mt/tb/mw;
 //   aL = -yt*conj((*neut)(0,3))*(*stop)(0,0) + sqrt(2.)*(*stop)(0,1)*bracketl;
 //   aR = -yt*     (*neut)(0,3) *(*stop)(0,1) - sqrt(2.)*(*stop)(0,0)*bracketr;
 //   cL.resize(2); cR.resize(2); d.resize(2.);
 //   kL.resize(2); kR.resize(2);
 //   bL.resize(2); bR.resize(2);
 //   double yb =  double(mb/mw)/cb/sqrt(2.);
 //   bracketl = -1./3.*sw*( conj(n1prime) - sw*conj(n2prime)/cw );
 //   bracketr = -1./3.*sw*n1prime - n2prime*(0.5  -1./3.*sqr(sw))/cw;
 //   for(unsigned int k=0;k<2;++k) {
 //     cL[k] =-yb*conj((*neut)(0,2))*(*sbot)(k,0) + sqrt(2.)*(*sbot)(k,1)*bracketl;
 //     cR[k] =-yb*     (*neut)(0,2) *(*sbot)(k,1) - sqrt(2.)*(*sbot)(k,0)*bracketr;
 //     d[k] = (*stop)(0,0)*(*sbot)(k,0);
 //     bL[k] = mb*conj((*umix)(k,1))/sqrt(2.)/mw/cb*(*stop)(0,0);
 //     bR[k] = -(*vmix)(k,0)*(*stop)(0,0)+mt*(*vmix)(k,1)/sqrt(2.)/mw/sb*(*stop)(0,1);
 //     kR[k] = -     (*neut)(0,3)*conj((*vmix)(k,1))/sqrt(2.)
 //       +     (*neut)(0,1) *conj((*vmix)(k,0));
 //     kL[k] =  conj((*neut)(0,2))*    (*umix)(k,1) /sqrt(2.)
 //       +conj((*neut)(0,1))*     (*umix)(k,0) ;
 //   }
 //   fL.resize(2); fR.resize(2);
 //   double qf = ferm->charge()/eplus;
 //   Energy mf = (abs(ferm->id())<5||(abs(ferm->id())>=11&&abs(ferm->id())<=14)) ? ZERO : mass(scale, ferm);
 //   Energy ma = (abs(anti->id())<5||(abs(anti->id())>=11&&abs(anti->id())<=14)) ? ZERO : mass(scale, anti);
 //   fL[0] = 0.;
 //   fR[0] = - sqrt(2.)*(qf*sw*n1prime - n2prime*(-0.5 + qf*sqr(sw))/cw);
 //   fL[1] = + sqrt(2.)*qf*sw*( conj(n1prime) - sw*conj(n2prime)/cw );
 //   fR[1] = 0.;
 //   eL.resize(2,vector<Complex>(2,0.));
 //   eR.resize(2,vector<Complex>(2,0.));
 //   for(unsigned int i=0;i<2;++i) {
 //     eR[i][0] = ma*conj((*umix)(i,1))/sqrt(2.)/mw/cb;
 //     eL[i][0] = -(*vmix)(i,0); 
 //     eL[i][1] = 0.;
 //     eR[i][1] = 0.;
 //   }
 //   hL.resize(2); hR.resize(2);
 //   double ya =  double(ma/mw)/cb/sqrt(2.);
 //   qf =-anti->charge()/eplus;
 //   bracketl = qf*sw*( conj(n1prime) - sw*conj(n2prime)/cw );
 //   bracketr = qf*sw*n1prime - n2prime*(0.5 +qf*sqr(sw))/cw;
 //   if(abs(anti->id())==ParticleID::tauminus) {
 //     for(unsigned int k=0;k<2;++k) {
 //       hR[k] =-ya*conj((*neut)(0,2))*(*stau)(k,0) + sqrt(2.)*(*stau)(k,1)*bracketl;
 //       hL[k] =-ya*     (*neut)(0,2) *(*stau)(k,1) - sqrt(2.)*(*stau)(k,0)*bracketr;
 //     }
 //   }
 //   else {
 //     hR[0] = 0.;
 //     hL[0] = - sqrt(2.)*bracketr;
 //     hR[1] = + sqrt(2.)*bracketl;
 //     hL[1] = 0.;
 //   }
 //   gL.resize(2,vector<Complex>(2,0.));
 //   gR.resize(2,vector<Complex>(2,0.)); 
 //   double y = ma/mw/sqrt(2.)/cb;
 //   ytau = ma/mw*tb;
 //   for(unsigned int i=0;i<2;++i) {
 //     if(abs(anti->id())==ParticleID::tauminus) {
 //       for(unsigned int j=0;j<2;++j) {
 // 	gL[i][j] = 0.;
 // 	gR[i][j] = -(*umix)(i,0)*(*stau)(j,0) + ya*(*stau)(j,1)*(*umix)(i,1);
 //       } 
 //     }
 //     else {
 //       gL[i][0] = 0.;
 //       gR[i][0] = -(*umix)(i,0); 
 //       gL[i][1] = 0.;
 //       gR[i][1] = 0.;
 //     }
 //   }
 //   double tw = sw/cw;
 //   lL.resize(2);
 //   lR.resize(2);
 //   for(unsigned int j = 0; j < 2; ++j) {
 //     lL[j] = -(conj((*neut)(0, 3)*(*vmix)(j,0) + ((*neut)(0,1) + (*neut)(0,0)*tw)*(*vmix)(j,1)/sqrt(2)))*cb;
 //     lR[j] = -(     (*neut)(0, 2)*(*umix)(j,0) - ((*neut)(0,1) + (*neut)(0,0)*tw)*(*umix)(j,1)/sqrt(2) )*sb;
 //   }
 // }
 
 // extracted from SSFFHVertex.cc
 // if(particle1->id()!=ParticleID::b) theMassLast.first  = theMSSM->mass(q2,particle1);
 // if(particle2->id()!=ParticleID::b) theMassLast.second = theMSSM->mass(q2,particle2);
 
 // extracted from FourBodyDecayConstructor.cc
 // from createDecayMode
   // unsigned int nferm=0;
   // tcPDPtr bottom,ferm,anti,chi;
   // for(OrderedParticles::const_iterator it=diagrams[0].outgoing.begin();
   //     it!=diagrams[0].outgoing.end();++it) {
   //   if((**it).iSpin()==PDT::Spin1Half) ++nferm;
   //   if(abs((**it).id())==ParticleID::b)
   //     bottom = *it;
   //   else if(abs((**it).id())>1000000)
   //     chi = *it;
   //   else if((**it).id()<0)
   //     anti = *it;
   //   else
   //     ferm = *it;
   // }
   // if(!bottom||!chi||!ferm||!anti) return;
   // if(ferm->id()-abs(anti->id())!=1) return;
   //if(anti->id()!=ParticleID::tauplus) return;
 // from decayList
   // set<PDPtr> new_particles;
   // for(set<PDPtr>::iterator it=particles.begin();it!=particles.end();++it) {
   //   if((**it).id()==ParticleID::SUSY_t_1) new_particles.insert(*it);
   // }
   // NBodyDecayConstructorBase::DecayList(new_particles);
 
 // extracted from StoFFFFDecayer.h
 
 // private :
 
 //   InvEnergy2 stopMatrixElement(const Particle & inpart,
 // 			       const ParticleVector & decay,
 // 			       InvEnergy2 me2) const;
 
 // #include "Herwig/Models/StandardModel/StandardModel.h"
 // InvEnergy2 StoFFFFDecayer::stopMatrixElement(const Particle & inpart,
 // 					     const ParticleVector & decay,
 // 					     InvEnergy2 me2) const {
 //   // extract the momenta and check the process
 //   bool found[4]={false,false,false,false};
 //   Lorentz5Momentum pb,pf,pfp,pChi;
 //   double col = 1.;
 //   tcPDPtr ferm,anti;
 //   for(unsigned int ix=0;ix<decay.size();++ix) {
 //     long id = decay[ix]->id();
 //     if(id==ParticleID::b) {
 //       found[0] = true;
 //       pb    = decay[ix]->momentum();
 //     }
 //     else if(id==ParticleID::SUSY_chi_10) {
 //       found[1] = true;
 //       pChi  = decay[ix]->momentum();
 //     }
 //     else if(abs(id)%2==0) {
 //       if(decay[ix]->dataPtr()->coloured()) col = 3.;
 //       found[2] = true;
 //       pf   = decay[ix]->momentum();
 //       ferm = decay[ix]->dataPtr();
 //     }
 //     else {
 //       found[3] = true;
 //       pfp  = decay[ix]->momentum();
 //       anti = decay[ix]->dataPtr();
 //     }
 //   }
 //   // check the process
 //   if(!found[0]||!found[1]||!found[2]||!found[3]) return ZERO;
 //   // extract the couplings we need
 //   HwSMPtr model = dynamic_ptr_cast<HwSMPtr>(generator()->standardModel());
 //   double sw(0.),cw(0.),g(0.);
 //   Energy mb = getParticleData(ParticleID::b)->mass();
 //   Energy mt = getParticleData(ParticleID::t)->mass();
 //   Energy mChi = getParticleData(ParticleID::SUSY_chi_10)->mass();
 //   Energy mw = getParticleData(ParticleID::Wplus)->mass();
 //   Energy mbt[2] = {getParticleData(ParticleID::SUSY_b_1)->mass(),
 // 		   getParticleData(ParticleID::SUSY_b_2)->mass()};
 //   Energy mP[2]  = {getParticleData(ParticleID::SUSY_chi_1plus)->mass(),
 // 		   getParticleData(ParticleID::SUSY_chi_2plus)->mass()}; 
 //   Energy msf[2]={ZERO,ZERO};
 //   tcPDPtr sf = getParticleData(1000000+abs(ferm->id()));
 //   msf[0] = sf->mass();
 //   sf = getParticleData(2000000+abs(ferm->id()));
 //   msf[1] = sf ? sf->mass() : 1e30*GeV;
 //   Energy msfp[2]={getParticleData(1000000+abs(anti->id()))->mass(),
 // 		  getParticleData(2000000+abs(anti->id()))->mass()};
 //   Complex aL(0.),aR(0.);
 //   vector<Complex> cL,cR,d,bL,bR,kL,kR,fL,fR,hL,hR,lL,lR;
 //   vector<vector<Complex> > eL,eR,gL,gR;
 //   double ytop,ytau;
 //   Energy2 scale = sqr(inpart.mass());
 //   model->StopCouplings(scale,ferm,anti,g,sw,cw,aL,aR,cL,cR,d,bL,bR,kL,kR,fL,fR,eL,eR,gL,gR,hL,hR,
 // 		       lL,lR,ytop,ytau);
 //   // compute the matrix element
 //   Lorentz5Momentum pw   = pf+pfp; pw.rescaleMass();
 //   Lorentz5Momentum ptop = pw+pb; ptop.rescaleMass();
 //   Lorentz5Momentum ptt  = inpart.momentum(); 
 //   Lorentz5Momentum pbt  = inpart.momentum()-pw; pbt.rescaleMass();
 //   Lorentz5Momentum pChiP= inpart.momentum()-pb; pb.rescaleMass();
 //   Lorentz5Momentum psf  = pChi+pf;psf.rescaleMass();
 //   Lorentz5Momentum psfp = pChi+pfp;psfp.rescaleMass();
   
 //   Energy2 ptpt = ptop*ptop;
 //   Energy2 pChipfp  = pChi*pfp;
 //   Energy2 ptopptop = ptop.m2();
 //   Energy2 pbpf     = pb*pf; 
 //   Energy2 pbpfp    = pb*pfp; 
 //   Energy2 ptoppfp  = ptop*pfp; 
 //   Energy2 pChipt   = pChi*ptop;
 //   Energy2 pChiptt   = pChi*ptt;
 //   Energy2 pfpfp    = pf*pfp;
 //   Energy2 pChipb   = pChi*pb;
 //   Energy2 pChipf   = pChi*pf;
 //   Energy2 pttptt   = ptt.m2();
 //   Energy2 pbptt  = pb*ptt;
 //   Energy2 pfpptt  = pfp*ptt;
 //   Energy2 pfppt  = pfp*ptop;
 //   Energy2 pfptt   = pf*ptt; 
 //   Energy2 ptptt   = ptop*ptt; 
 //   Energy2 pfpt   = pf*ptop; 
 //   Energy2 pbpt   = pb*ptop; 
 //   Energy2 pChiPpChiP=pChiP*pChiP;
 //   Energy2 pChipChiP=pChi*pChiP;
 //   Energy2 pbpChiP = pb*pChiP;
 //   Energy2 pfppChiP = pfp*pChiP;
 //   Energy2 ptpChiP = ptop*pChiP;
 //   Energy2 pttpChiP = ptt*pChiP;
 //   Energy2 pfpChiP = pf*pChiP;
 
 //   Energy mf = pf.mass();
 //   Energy mfp = pfp.mass();
 //   assert(model);
 //   InvEnergy2 pTop = 1./(ptop.m2()-sqr(mt));
 //   InvEnergy2 pW   = 1./(pw  .m2()-sqr(mw));
 //   InvEnergy2 pBT[2]  = {1./(pbt.m2()-sqr(mbt[0])),1./(pbt.m2()-sqr(mbt[1]))};
 //   InvEnergy2 pP[2]   = {1./(pChiP.m2()-sqr(mP[0])),1./(pChiP.m2()-sqr(mP[1]))};
 //   InvEnergy2 pSF [2]  = {1./(psf .m2()-sqr(msf [0])),1./(psf .m2()-sqr(msf [1]))};
 //   if(abs(ferm->id())==ParticleID::nu_e||abs(ferm->id())==ParticleID::nu_mu||abs(ferm->id())==ParticleID::nu_tau)
 //     pSF[1] = ZERO;
 //   InvEnergy2 pSFP[2]  = {1./(psfp.m2()-sqr(msfp[0])),1./(psfp.m2()-sqr(msfp[1]))};
 //   // top squared
 //   InvEnergy2 mett = pow(g,6)*sqr(pTop*pW)*
 //     ( norm(aR) * ( -4.*pChipfp*pbpf*ptopptop + 8.*pChipt*pbpf*ptoppfp ) +
 //       norm(aL) * (  4.*pChipfp*pbpf*sqr(mt))
 //       + real(aL*conj(aR)) * (  - 8*pbpf*ptoppfp*mChi*mt )
 //       );
 //   // colour factors
 //   mett *=col;
 //   // sbottom squared
 //   complex<InvEnergy2> mebb(ZERO);
 //   for(unsigned int i=0;i<2;++i) {
 //     for(unsigned int j=0;j<2;++j) {
 //       mebb += pow(g,6)*d[i]*d[j]*pBT[i]*pBT[j]*sqr(pW)*
 // 	(pChipb*(cR[i]*cR[j]+cL[i]*cL[j])- mChi*mb*(cL[j]*cR[i]+cL[i]*cR[j]))*
 // 	( - 4*pfpfp*pttptt + 8*pfptt*pfpptt + pfpfp*sqr(mfp) + pfpfp*sqr(mf)
 // 	  - 4*pfptt*sqr(mfp) - 4*pfpptt*sqr(mf) + 2*sqr(mf)*sqr(mfp) );
 //     }
 //   }
 //   // colour factors
 //   mebb *=col;
 //   // stop sbottom
 //   complex<InvEnergy2> metb(ZERO);
 //   for(unsigned int i=0;i<2;++i) {
 //     metb += pow(g,6)*d[i]*pTop*pBT[i]*sqr(pW)*cR[i]*
 //       (
 //        + aR*(   - 2*pChipb*pfpfp*ptptt + 2*pChipb*pfpt*
 //          pfpptt + 2*pChipb*pfptt*pfppt + 2*pChipf*pbpfp*ptptt - 
 //          2*pChipf*pbpt*pfpptt - 2*pChipf*pbptt*pfppt - 2*pChipfp
 //          *pbpf*ptptt - 2*pChipfp*pbpt*pfptt + 2*pChipfp*pbptt*
 //          pfpt + 2*pChipt*pbpf*pfpptt + 2*pChipt*pbpfp*pfptt - 2*
 //          pChipt*pbptt*pfpfp + 2*pChiptt*pbpf*pfppt - 2*pChiptt*
 //          pbpfp*pfpt + 2*pChiptt*pbpt*pfpfp)
 //        + aL*mChi*mt*(  - 2*pbpf*pfpptt - 2*pbpfp*pfptt  + 2*pbptt*pfpfp ));
 //   }
 //   // colour factors
 //   metb *=col;
 //   complex<InvEnergy2> mecc(ZERO);
 //   for(unsigned int i=0;i<2;++i) {
 //     for(unsigned int j=0;j<2;++j) {
 //       mecc += pow(g,6)*pP[i]*pP[j]*sqr(pW)*
 // 	(+ bR[i]*bR[j]*kR[i]*kR[j] * ( 16*pChipb*pChipf*pChipfp + 16*pChipb*pChipf*pfpfp + 16*pChipb*pChipf*sqr(mfp) + 16*pChipf*
 //          pChipfp*pbpf + 16*pChipf*pbpf*pfpfp + 16*pChipf*pbpf*sqr(mfp) + 8*pChipf*pbpfp*sqr(mfp) - 8*pChipf*pbpfp*sqr(mf) - 16*sqr(pChipf)*pbpfp )
 
 //        + bR[i]*bR[j]*kL[i]*kL[j] * ( 8*pChipfp*pbpf*mP[i]*mP[j] )
 
 //        + bL[i]*bL[j]*kR[i]*kR[j] * ( 8*pChipf*pbpfp*mP[i]*mP[j] )
 
 //        + bL[i]*bL[j]*kL[i]*kL[j] * ( 16*pChipb*pChipf*pChipfp + 16*pChipb*
 //          pChipfp*pfpfp + 16*pChipb*pChipfp*sqr(mf) + 16*pChipf*
 //          pChipfp*pbpfp - 8*pChipfp*pbpf*sqr(mfp) + 8*pChipfp*pbpf*
 //          sqr(mf) + 16*pChipfp*pbpfp*pfpfp + 16*pChipfp*pbpfp*sqr(mf) - 
 // 				     16*sqr(pChipfp)*pbpf )
 
 //        + mb*bL[j]*bR[i]*kR[i]*kR[j] * (  - 8*pChipf*pChipfp*mP[j] - 8*pChipf*pfpfp*mP[j] - 8*pChipf*sqr(mfp)*mP[j] )
 
 //        + mb*bL[j]*bR[i]*kL[i]*kL[j] * (  - 8*pChipf*pChipfp*mP[i] - 8*pChipfp*pfpfp*mP[i] - 8*pChipfp*sqr(mf)*mP[i] )
 
 //        + mb*bL[i]*bR[j]*kR[i]*kR[j] * (  - 8*pChipf*pChipfp*mP[i] - 8*pChipf*pfpfp*mP[i] - 8*pChipf*sqr(mfp)*mP[i] )
 
 //        + mb*bL[i]*bR[j]*kL[i]*kL[j] * (  - 8*pChipf*pChipfp*mP[j] - 8*pChipfp*pfpfp*mP[j] - 8*pChipfp*sqr(mf)*mP[j] )
 
 //        + mChi*bR[i]*bR[j]*kR[i]*kL[j] * (  - 4*pChipb*pfpfp*mP[j] + 4*pChipf*pbpfp*mP[j] - 4*pChipfp*pbpf*mP[j] - 8*pbpf*pfpfp*mP[j] - 4*pbpf*sqr(mfp)*mP[j] + 4*pbpfp*sqr(mf)*mP[j] )
 
 //        + mChi*bR[i]*bR[j]*kL[i]*kR[j] * (  - 4*pChipb*pfpfp*mP[i] + 4*pChipf*pbpfp*mP[i] - 4*pChipfp*pbpf*mP[i] - 8*pbpf*pfpfp*mP[i] - 4*
 //          pbpf*sqr(mfp)*mP[i] + 4*pbpfp*sqr(mf)*mP[i] )
 
 //        + mChi*bL[i]*bL[j]*kR[i]*kL[j] * (  - 4*pChipb*pfpfp*mP[i] - 4*pChipf*pbpfp*mP[i] + 4*pChipfp*pbpf*mP[i] + 4*pbpf*sqr(mfp)*mP[i] - 8*pbpfp*pfpfp*mP[i] - 4*pbpfp*sqr(mf)*mP[i] )
 
 //        + mChi*bL[i]*bL[j]*kL[i]*kR[j] * (  - 4*pChipb*pfpfp*mP[j] - 4*pChipf*pbpfp*mP[j] + 4*pChipfp*pbpf*mP[j] + 4*pbpf*sqr(mfp)*mP[j] - 8*
 //          pbpfp*pfpfp*mP[j] - 4*pbpfp*sqr(mf)*mP[j] )
 
 //        + mChi*mb*bL[j]*bR[i]*kR[i]*kL[j] * ( 8*pChipf*pfpfp + 8*pChipfp*
 // 					     pfpfp + 4*pfpfp*sqr(mfp) + 4*pfpfp*sqr(mf) + 8*sqr(pfpfp) )
 
 //        + mChi*mb*bL[j]*bR[i]*kL[i]*kR[j] * ( 4*pfpfp*mP[i]*mP[j] )
 
 //        + mChi*mb*bL[i]*bR[j]*kR[i]*kL[j] * ( 4*pfpfp*mP[i]*mP[j] )
 
 //        + mChi*mb*bL[i]*bR[j]*kL[i]*kR[j] * ( 8*pChipf*pfpfp + 8*pChipfp*
 // 					 pfpfp + 4*pfpfp*sqr(mfp) + 4*pfpfp*sqr(mf) + 8*sqr(pfpfp) )
 
 //        + sqr(mChi)*bR[i]*bR[j]*kR[i]*kR[j] * (  - 8*pChipf*pbpfp )
 
 //        + sqr(mChi)*bL[i]*bL[j]*kL[i]*kL[j] * (  - 8*pChipfp*pbpf )
 
 //        + mChi*sqr(mChi)*mb*bL[j]*bR[i]*kR[i]*kL[j] * ( 4*pfpfp )
 
 //        + mChi*sqr(mChi)*mb*bL[i]*bR[j]*kL[i]*kR[j] * ( 4*pfpfp ));
 
 //     }
 //   }
 //   mecc *=col;
 //   complex<InvEnergy2> metc(ZERO);
 //   for(unsigned int j=0;j<2;++j) {
 //     metc +=  pow(g,6)*pP[j]*pTop*sqr(pW)/sqrt(2.)*(
 //       + aR*bR[j]*kR[j] * (  - 8*pChipb*pChipf*pbpfp + 8*pChipb*pChipf*pfpfp - 8*pChipb*
 // 			pChipfp*pbpf - 8*pChipb*pChipfp*sqr(mf) + 8*pChipb*pbpf*pfpfp - 8*pChipb*pbpfp*
 //          sqr(mf) - 4*pChipb*pfpfp*sqr(mfp) - 4*
 // 			    pChipb*pfpfp*sqr(mf) - 8*pChipb*sqr(mf)*sqr(mfp) + 8*sqr(pChipb)*pfpfp + 8*pChipf*pChipfp*
 //          pbpf + 8*pChipf*pbpf*pbpfp + 16*
 //          pChipf*pbpf*pfpfp + 16*pChipf*pbpf*sqr(mfp) + 4*pChipf*pbpfp*sqr(mfp) - 4*pChipf*pbpfp*
 // 			    sqr(mf) - 8*sqr(pChipf)*pbpfp + 4*pChipfp*
 //          pbpf*sqr(mfp) - 4*pChipfp*pbpf*sqr(mf) - 8*
 // 			    pChipfp*sqr(pbpf) )
 
 //        + aR*mb*bL[j]*kR[j] * (  - 4*pChipb*pfpfp*mP[j] - 4*pChipf*pbpfp*mP[j] - 8*pChipf*pfpfp*mP[j]
 //           - 4*pChipf*sqr(mfp)*mP[j] + 4*pChipfp*
 //          pbpf*mP[j] + 4*pChipfp*sqr(mf)*mP[j] )
 
 //       + aR*sqr(mb)*bR[j]*kR[j] * ( 8*pChipf*pChipfp + 4*pChipf*sqr(mfp) + 4*pChipfp*sqr(mf) )
 
 //        + aR*mChi*bR[j]*kL[j] * (  - 8*pbpf*pbpfp*mP[j] - 8*pbpf*pfpfp*mP[j] - 8*pbpf*sqr(mfp)*mP[j] )
 
 //        + aR*mChi*mb*bL[j]*kL[j] * ( 8*sqr(mf)*sqr(mfp) + 8*
 //          pChipf*pbpfp + 8*pChipf*pfpfp + 8*
 //          pChipf*sqr(mfp) + 8*pbpfp*pfpfp + 8*
 //          pbpfp*sqr(mf) + 8*pfpfp*sqr(mfp) + 8*pfpfp*
 // 				    sqr(mf) + 8*sqr(pfpfp) )
 
 //        + aR*sqr(mChi)*bR[j]*kR[j] * ( 8*pbpf*pbpfp + 4
 //          *pbpf*sqr(mfp) + 4*pbpfp*sqr(mf) )
 
 //       + aR*sqr(mChi)*sqr(mb)*bR[j]*kR[j] * (  - 4*pfpfp )
 
 //        + aL*mt*bR[j]*kL[j] * ( 8*pChipfp*pbpf*mP[j] )
 
 //        + aL*mb*mt*bL[j]*kL[j] * (  - 8*pChipf*pChipfp - 8*pChipfp*pfpfp - 8*pChipfp*sqr(mf) )
 
 //        + aL*mChi*mt*bR[j]*kR[j] * (  - 4*pChipb*pfpfp + 4*pChipf*pbpfp - 4*pChipfp*pbpf - 8*pbpf*pfpfp - 4*pbpf*sqr(mfp) + 4*pbpfp*sqr(mf) )
 
 //       + aL*mChi*mb*mt*bL[j]*kR[j] * ( 4*pfpfp*mP[j] ));
 //   }
 //   metc *= col;
   
 //   complex<InvEnergy2> mebc(ZERO);
 //   for(unsigned int i=0;i<2;++i) {
 //     for(unsigned int j=0;j<2;++j) {
 //       mebc += pow(g,6)*pP[j]*sqr(pW)*d[i]*pBT[i]/sqrt(2.)*
 // 	(+ cR[i]*bR[j]*kR[j] * (  - 8*pChipb*pChipf*pfpptt + 4
 //          *pChipb*pChipf*sqr(mfp) - 8*pChipb*
 //          pChipfp*pfptt + 4*pChipb*pChipfp*sqr(mf) + 8*pChipb*pChiptt*pfpfp + 2*pChipb*
 //          pfpfp*sqr(mfp) + 2*pChipb*pfpfp*sqr(mf) - 4
 //          *pChipb*pfptt*sqr(mfp) - 4*pChipb*pfpptt*sqr(mf) + 4
 //          *pChipb*sqr(mf)*sqr(mfp) + 8*pChipf*pbpfp*
 //          pfptt + 2*pChipf*pbpfp*sqr(mfp) - 2*
 //          pChipf*pbpfp*sqr(mf) - 8*pChipf*pbptt*pfpfp - 4*pChipf*pbptt*sqr(mfp) - 8*pChipfp*pbpf*
 //          pfptt - 2*pChipfp*pbpf*sqr(mfp) + 2*
 //          pChipfp*pbpf*sqr(mf) + 4*pChipfp*pbptt*sqr(mf) + 8*pChiptt*pbpf*pfpfp + 4*pChiptt*pbpf*
 //          sqr(mfp) - 4*pChiptt*pbpfp*sqr(mf))
 
 //        + cL[i]*bL[j]*kL[j] * (  - 8*pChipb*pChipf*pfpptt + 4
 //          *pChipb*pChipf*sqr(mfp) - 8*pChipb*
 //          pChipfp*pfptt + 4*pChipb*pChipfp*sqr(mf) + 8*pChipb*pChiptt*pfpfp + 2*pChipb*
 //          pfpfp*sqr(mfp) + 2*pChipb*pfpfp*sqr(mf) - 4
 //          *pChipb*pfptt*sqr(mfp) - 4*pChipb*pfpptt*sqr(mf) + 4
 //          *pChipb*sqr(mf)*sqr(mfp) - 8*pChipf*pbpfp*
 //          pfpptt + 2*pChipf*pbpfp*sqr(mfp) - 2*
 //          pChipf*pbpfp*sqr(mf) + 4*pChipf*pbptt*sqr(mfp) + 8*pChipfp*pbpf*pfpptt - 2*pChipfp*pbpf
 //          *sqr(mfp) + 2*pChipfp*pbpf*sqr(mf) - 8*
 //          pChipfp*pbptt*pfpfp - 4*pChipfp*pbptt*sqr(mf) - 4*pChiptt*pbpf*sqr(mfp) + 8*pChiptt*
 //          pbpfp*pfpfp + 4*pChiptt*pbpfp*sqr(mf))
 
 //        + mb*cR[i]*bL[j]*kR[j] * ( 4*pChipf*pfpptt*mP[j] - 2*pChipf*sqr(mfp)*mP[j] + 4*pChipfp*pfptt*mP[j]
 //           - 2*pChipfp*sqr(mf)*mP[j] - 4*pChiptt*pfpfp*mP[j] )
 
 //        + mb*cL[i]*bR[j]*kL[j] * ( 4*pChipf*pfpptt*mP[j] - 2*pChipf*sqr(mfp)*mP[j] + 4*pChipfp*pfptt*mP[j]
 //           - 2*pChipfp*sqr(mf)*mP[j] - 4*pChiptt*pfpfp*mP[j] )
 
 //        + mChi*cR[i]*bR[j]*kL[j] * (  - 4*pbpf*pfpptt*mP[j] + 2*pbpf*sqr(mfp)*mP[j] - 4*pbpfp*pfptt*mP[j]
 //           + 2*pbpfp*sqr(mf)*mP[j] + 4*pbptt*pfpfp*mP[j] )
 
 //        + mChi*cL[i]*bL[j]*kR[j] * (  - 4*pbpf*pfpptt*mP[j] + 2*pbpf*sqr(mfp)*mP[j] - 4*pbpfp*pfptt*mP[j] + 2*pbpfp*sqr(mf)*mP[j] + 4*pbptt*pfpfp*mP[j] )
 
 //        + mChi*mb*cR[i]*bL[j]*kL[j] * (  - 4*sqr(mf)*sqr(mfp) + 4*pChipf*pfpptt - 2*pChipf*sqr(mfp) + 4*pChipfp*pfptt - 2*pChipfp*sqr(mf) - 4*pChiptt*pfpfp - 2*pfpfp*sqr(mfp) - 2*pfpfp*sqr(mf) + 4*pfptt*sqr(mfp) + 4*pfpptt*sqr(mf) )
 
 //        + mChi*mb*cL[i]*bR[j]*kR[j] * (  - 4*sqr(mf)*sqr(mfp) + 4*pChipf*pfpptt - 2*pChipf*sqr(mfp) + 4*pChipfp*pfptt - 2*pChipfp*sqr(mf) - 4*pChiptt*pfpfp - 2*pfpfp*sqr(mfp) - 2*pfpfp*sqr(mf) + 4*pfptt*sqr(mfp) + 4*pfpptt*sqr(mf) )
 
 //        + sqr(mChi)*cR[i]*bR[j]*kR[j] * ( 4*pbpf*pfpptt - 2*pbpf*sqr(mfp) + 4*pbpfp*pfptt - 2*pbpfp*sqr(mf) - 4*pbptt*pfpfp )
 
 // 	 + sqr(mChi)*cL[i]*bL[j]*kL[j] * ( 4*pbpf*pfpptt - 2*pbpf*sqr(mfp) + 4*pbpfp*pfptt - 2*pbpfp*sqr(mf) - 4*pbptt*pfpfp ));
 //     }
 //   }
 //   mebc *= col;
 //   complex<InvEnergy2> meff(ZERO);
 //   for(unsigned int i=0;i<2;++i) {
 //     for(unsigned int j=0;j<2;++j) {
 //       for(unsigned int k=0;k<2;++k) {
 // 	for(unsigned int l=0;l<2;++l) {
 // 	  meff += pow(g,6)*pP[i]*pP[j]*pSF[k]*pSF[l]*pChipf*(fR[k]*fR[l]+fL[k]*fL[l])*
 // 	    (
 // 	     + ( eR[i][k]*eR[j][l]*bR[i]*bR[j] + eL[i][k]*eL[j][l]*bL[i]*bL[j] )* ( 4.*pbpfp*mP[i]*mP[j] )
 // 	     + ( eR[i][k]*eR[j][l]*bL[i]*bL[j] + eL[i][k]*eL[j][l]*bR[i]*bR[j] )* (  - 4*pbpfp*pChiPpChiP + 
 // 	  								    8*pbpChiP*pfppChiP )
 // 	     +mb*mP[i]*( eR[i][k]*eR[j][l]*bL[j]*bR[i] + eL[i][k]*eL[j][l]*bL[i]*bR[j]  ) * (  - 4*pfppChiP )
 // 	     +mb*mP[j]*( eR[i][k]*eR[j][l]*bL[i]*bR[j] + eL[i][k]*eL[j][l]*bL[j]*bR[i]  ) * (  - 4*pfppChiP ));
 // 	}
 //       }
 //     }
 //   }
 //   meff *= col;
 //   complex<InvEnergy2> mepp(ZERO);
 //   for(unsigned int i=0;i<2;++i) {
 //     for(unsigned int j=0;j<2;++j) {
 //       for(unsigned int k=0;k<2;++k) {
 // 	for(unsigned int l=0;l<2;++l) {
 // 	  mepp += pow(g,6)*pP[i]*pP[j]*pSFP[k]*pSFP[l]*pChipfp*(hR[k]*hR[l]+hL[k]*hL[l])*
 // 	    ((gR[i][k]*gR[j][l]*bR[i]*bR[j] + gL[i][k]*gL[j][l]*bL[i]*bL[j]) * ( 4*pbpf*mP[i]*mP[j] ) +
 // 	     (gR[i][k]*gR[j][l]*bL[i]*bL[j] + gL[i][k]*gL[j][l]*bR[i]*bR[j]) * 
 // 	     (  - 4*pbpf*pChiPpChiP + 8*pbpChiP*pfpChiP ));
 // 	}
 //       }
 //     }
 //   }
 //   mepp *= col;
 //   complex<InvEnergy2> metf(ZERO);
 //   for(unsigned int j=0;j<2;++j) {
 //     for(unsigned int l=0;l<2;++l) {
 //       metf +=  pow(g,6)*pTop*pW*pP[j]*pSF[l]*
 // 	(+ aR*eL[j][l]*fR[l]*bR[j] * ( 2*pChipb*pfpfp*ptpChiP - 2*pChipb*pfpt*pfppChiP 
 // 				       - 2*pChipb*pfpChiP*pfppt - 2*pChipf*pbpfp*ptpChiP 
 // 				       + 2*pChipf*pbpt*pfppChiP + 2*pChipf*pbpChiP*pfppt 
 // 				       - 2*pChipfp*pbpf*ptpChiP + 2*pChipfp*pbpt*pfpChiP
 // 				       - 2*pChipfp*pbpChiP*pfpt + 2*pChipt*pbpf*pfppChiP 
 // 				       - 2*pChipt*pbpfp*pfpChiP + 2*pChipt*pbpChiP*pfpfp 
 // 				       + 2*pChipChiP*pbpf*pfppt + 2*pChipChiP*pbpfp*pfpt 
 // 				       - 2*pChipChiP*pbpt*pfpfp )
 // 	 + aL*mChi*mt*eL[j][l]*fR[l]*bR[j] * (  - 2*pbpf*pfppChiP + 2*pbpfp*pfpChiP - 2*pbpChiP*pfpfp )
 	 
 // 	 );
 //     }
 //   }
 //   metf *= col;
 //   // sbottom sfermion interference
 //   complex<InvEnergy2> mebf(ZERO);
 //   for(unsigned int i=0;i<2;++i) {
 //     for(unsigned int j=0;j<2;++j) {
 //       for(unsigned int l=0;l<2;++l) {
 // 	mebf += 2.*pow(g,6)*d[i]*pBT[i]*pW*pP[j]*pSF[l]*
 // 	  (cR[i]*eL[j][l]*fR[l]*bR[j] * ( pChipb*pfpfp*pttpChiP - pChipb*pfptt*pfppChiP - pChipb*pfpChiP*pfpptt +
 // 				      pChipf*pbpfp*pttpChiP - pChipf*pbptt*pfppChiP - pChipf*pbpChiP*pfpptt -
 // 				      pChipfp*pbpf*pttpChiP + pChipfp*pbptt*pfpChiP - pChipfp*pbpChiP*pfptt +
 // 				      pChiptt*pbpf*pfppChiP - pChiptt*pbpfp*pfpChiP + pChiptt*pbpChiP*pfpfp +
 // 				      pChipChiP*pbpf*pfpptt + pChipChiP*pbpfp*pfptt - pChipChiP*pbptt*pfpfp)
 // 	   + mChi*mP[j]*cL[i]*eL[j][l]*fR[l]*bL[j] * ( - pbpf*pfpptt - pbpfp*pfptt + pbptt*pfpfp ));
 //       }
 //     }
 //   }
 //   mebf *= col;
 //   // chi W sfermion interference
 //   complex<InvEnergy2> mecf(ZERO);
 //   for(unsigned int i=0;i<2;++i) {
 //     for(unsigned int j=0;j<2;++j) {
 //       for(unsigned int l=0;l<2;++l) {
 // 	mecf -= pow(g,6)*pP[i]*pW*pP[j]*pSF[l]*eL[j][l]*fR[l]/sqrt(2.)*
 // 	  (+ bR[i]*bR[j]*kR[i] * ( 8*pChipf*pbpfp*pChiPpChiP - 16*pChipf*pbpChiP*pfppChiP )
 // 	   + bR[i]*bR[j]*kL[i]*mChi*mP[i] *  ( 4*pbpf*pfppChiP - 4*pbpfp*pfpChiP + 4*pbpChiP*pfpfp)
 // 	   + bL[i]*bL[j]*kR[i]*mP[i]*mP[j] * (  - 8*pChipf*pbpfp )
 // 	   + bL[i]*bL[j]*kL[i]*mChi*mP[j]  * (-4*pbpf*pfppChiP + 4*pbpfp*pfpChiP + 4*pbpChiP*pfpfp)
 // 	   );
 //       }
 //     }
 //   }
 //   mecf *= col;
 
 //   complex<InvEnergy2> mebp(ZERO);
 //   for(unsigned int i=0;i<2;++i) {
 //     for(unsigned int j=0;j<2;++j) {
 //       for(unsigned int l=0;l<2;++l) {
 // 	mebp += pow(g,6)*d[i]*pBT[i]*pW*pP[j]*pSFP[l]*
 // 	  (
 // 	   + cL[i]*gR[j][l]*hL[l]*bL[j] * 
 // 	   (  - 2*pChipb*pfpfp*pttpChiP + 2*pChipb*pfptt*pfppChiP 
 // 	      + 2*pChipb*pfpChiP*pfpptt + 2*pChipf*pbpfp*pttpChiP 
 // 	      - 2*pChipf*pbptt*pfppChiP + 2*pChipf*pbpChiP*pfpptt
 // 	      - 2*pChipfp*pbpf*pttpChiP + 2*pChipfp*pbptt*pfpChiP
 // 	      + 2*pChipfp*pbpChiP*pfptt + 2*pChiptt*pbpf*pfppChiP
 // 	      - 2*pChiptt*pbpfp*pfpChiP - 2*pChiptt*pbpChiP*pfpfp
 // 	      - 2*pChipChiP*pbpf*pfpptt - 2*pChipChiP*pbpfp*pfptt
 // 	      + 2*pChipChiP*pbptt*pfpfp)
 				  
 // 	   + mChi*cR[i]*gR[j][l]*hL[l]*bR[j]*mP[j] * 
 // 	   ( 2*pbpf*pfpptt + 2*pbpfp*pfptt - 2*pbptt*pfpfp ));
 //       }
 //     }
 //   }
 //   mebp *= col;
 //   // chi W anti sfermion interference
 //   complex<InvEnergy2> mecp(ZERO);
 //   for(unsigned int i=0;i<2;++i) {
 //     for(unsigned int j=0;j<2;++j) {
 //       for(unsigned int l=0;l<1;++l) {
 // 	mecp +=pow(g,6)*pP[i]*pW*pP[j]*pSFP[l]/sqrt(2.)*gR[j][l]*hL[l]*
 // 	  (
 // 	   + bR[i]*bR[j]*kL[i] * (  - 8*pChipfp*pbpf*mP[i]*mP[j] )
 // 	   + bL[i]*bL[j]*kL[i] * ( 8*pChipfp*pbpf*pfppChiP + 8*pChipfp*pbpf*pChiPpChiP - 8*pChipfp*pbpfp*pfpChiP - 8*pChipfp*pbpChiP*pfpfp - 16*pChipfp*pbpChiP*pfpChiP)
 // 	   + mChi*bR[i]*bR[j]*kR[i]*mP[j]*( 4*pbpf*pfppChiP - 4*pbpfp*pfpChiP + 4*pbpChiP*pfpfp)
 // 	   + mChi*bL[i]*bL[j]*kR[i]*mP[i]*(  - 4*pbpf*pfppChiP + 8*pbpfp*pfpfp + 4*pbpfp*pfpChiP + 4*pbpChiP*pfpfp));
 //       }
 //     }
 //   }
 //   mecp *= col;
 //   // sfermion antisfermion interferences
 //   complex<InvEnergy2> mefp(ZERO);
 //   for(unsigned int i=0;i<2;++i) {
 //     for(unsigned int j=0;j<2;++j) {
 //       for(unsigned int k=0;k<1;++k) {
 // 	for(unsigned int l=0;l<2;++l) {
 // 	  mefp +=pow(g,6)*pP[i]*pP[j]*pSF[k]*pSFP[l]*fR[k]*gR[j][l]*
 // 	    (
 // 	     + eR[i][k]*hR[l]*bR[i]*bR[j]*mP[i]*mP[j] * 
 // 	     ( 2*pChipb*pfpfp - 2*pChipf*pbpfp - 2*pChipfp*pbpf )
 	     
 // 	     + eR[i][k]*hR[l]*bL[i]*bL[j]* 
 // 	     (  - 2*pChipb*pfpfp*pChiPpChiP + 2*pChipf*pbpfp*pChiPpChiP 
 // 		- 4*pChipf*pbpChiP*pfppChiP + 2*pChipfp*pbpf*pChiPpChiP 
 // 		- 4*pChipfp*pbpChiP*pfpChiP + 4*pChipChiP*pbpChiP*pfpfp)
 	     
 // 	     + eL[i][k]*hL[l]*bL[i]*bL[j]*mChi*mP[i] * 
 // 	     (-2*pbpf*pfppChiP + 2*pbpfp*pfpChiP + 2*pbpChiP*pfpfp )
 	     
 // 	     + eL[i][k]*hL[l]*bR[i]*bR[j]*mChi*mP[j] *
 // 	     ( 2*pbpf*pfppChiP - 2*pbpfp*pfpChiP + 2*pbpChiP*pfpfp ));
 // 	}
 //       }
 //     }
 //   }
 //   mefp *= col;
 //   // top higgs
 //   Energy mHiggs = getParticleData(ParticleID::Hplus)->mass();
 //   InvEnergy2 pH = 1./(pw.m2()-sqr(mHiggs));
 //   InvEnergy2 meht = 0.25*sqr(ytop*ytau)*pow(g,6)*sqr(pTop*pH)*pfpfp*
 //     ( norm(aR) *sqr(mt)*4*pChipb +
 //       norm(aL) * (  - 4*pChipb*ptpt + 8*pChipt*pbpt )
 //       + real(aL*conj(aR)) * mChi*mt * (  - 8*pbpt ));
 //   // colour factors
 //   meht *=col;
 //   // chargino higgs
 //   complex<InvEnergy2> mehc(ZERO);
 //   for(unsigned int i=0;i<2;++i) {
 //     for(unsigned int j=0;j<2;++j) {
 //       mehc += pow(g,6)*pP[i]*pP[j]*sqr(pH)*sqr(ytau)*pfpfp*
 //       (    + (bR[i]*bR[j]*lR[i]*lR[j]+bL[i]*bL[j]*lL[i]*lL[j])*mP[i]*mP[j]*2*pChipb
 //            + (bR[i]*bR[j]*lL[i]*lL[j]+bL[i]*bL[j]*lR[i]*lR[j])*(-2*pChipb*pChiPpChiP+4*pChipChiP*pbpChiP)
 //            + (bR[i]*bR[j]*lR[i]*lL[j]+bL[i]*bL[j]*lL[i]*lR[j])*mChi*mP[i]*2*pbpChiP
 //            + (bR[i]*bR[j]*lL[i]*lR[j]+bL[i]*bL[j]*lR[i]*lL[j])*mChi*mP[j]*2*pbpChiP);
 //     }
 //   }
 
 
 //    // hehbc =
 //    //     + cR1*d1*bR2*kR2 * ( 2*pChi.pb*pf.pfp*mP2 )
 
 //    //     + cL1*d1*bL2*kL2 * ( 2*pChi.pb*pf.pfp*mP2 )
 
 //    //     + mChi*cR1*d1*bR2*kL2 * ( 2*pb.pChiP*pf.pfp )
 
 //    //     + mChi*cL1*d1*bL2*kR2 * ( 2*pb.pChiP*pf.pfp );
 
 //   // InvEnergy2 meTotal = meff.real()+mecc.real()+2.*mecf.real();
 //   InvEnergy2 meTotal = abs(mehc.real());
 //   // if(abs(anti->id())==ParticleID::tauminus) {
 //   //   cerr << "testing inter " << (me2-mepp.real()-meff.real())*GeV2 << " " << 2.*mefp.real()*GeV2
 //   // 	 << " " << 0.5*(me2-mepp.real()-meff.real())/mefp.real() << "\n";
 //   //   cerr << "testing the matrix element " << meTotal*GeV2 << " "
 //   // 	 << me2*GeV2 << " " << meTotal/me2 << "\n";
 //   // }
 //   return meTotal;
 // }
 
 // extracted from main diagram loop
 
 
 	    // //\todo remove testing
 	    // top
 	    // if(!(abs(inter.first ->id())==ParticleID::t&&
 	    // 	 abs(inter.second->id())==ParticleID::Wplus)) {
 	    //   ++idiag;
 	    //   continue;
 	    // }
 	    // sbottom
 	    // if(!((abs(inter.first ->id())==ParticleID::SUSY_b_1||
 	    // 	  abs(inter.first ->id())==ParticleID::SUSY_b_2)&&
 	    // 	 abs(inter.second->id())==ParticleID::Wplus)) {
 	    //   ++idiag;
 	    //   continue;
 	    // }
 	    // chargino W
 	    // if(!((abs(inter.first ->id())==ParticleID::SUSY_chi_1plus||
 	    // 	  abs(inter.first ->id())==ParticleID::SUSY_chi_2plus)&&
 	    // 	 abs(inter.second->id())==ParticleID::Wplus)) {
 	    //   ++idiag;
 	    //   continue;
 	    // }
 	    // sneutrino
 	    // if(!((abs(inter.first ->id())==ParticleID::SUSY_chi_1plus||
 	    // 	  abs(inter.first ->id())==ParticleID::SUSY_chi_2plus)&&
 	    // 	 abs(inter.second->id())!=ParticleID::Wplus&&
 	    // 	 inter.second->id()<0)) {
 	    //   ++idiag;
 	    //   continue;
 	    // }
 	    // sneutrino
 	    // if(!((abs(inter.first ->id())==ParticleID::SUSY_chi_1plus||
 	    //  	  abs(inter.first ->id())==ParticleID::SUSY_chi_2plus)&&
 	    // 	 abs(inter.second->id())!=ParticleID::Wplus&&
 	    // 	 inter.second->id()<0)) {
 	    //   ++idiag;
 	    //   continue;
 	    // }
 	    // charged slepton
 	    // if(!((abs(inter.first ->id())==ParticleID::SUSY_chi_1plus||
 	    // 	  abs(inter.first ->id())==ParticleID::SUSY_chi_2plus)&&
 	    // 	 abs(inter.second->id())!=ParticleID::Wplus&&
 	    // 	 inter.second->id()>0)) {
 	    //   ++idiag;
 	    //   continue;
 	    // }
 	    // slepton sneutrino
 	    // if(!((abs(inter.first ->id())==ParticleID::SUSY_chi_1plus||
 	    // 	  abs(inter.first ->id())==ParticleID::SUSY_chi_2plus)&&
 	    // 	 abs(inter.second->id())!=ParticleID::Wplus&&
 	    // 	 abs(inter.second->id())!=ParticleID::Hplus&&
 	    // 	 inter.second->id()>0) &&
 	    //    !((abs(inter.first ->id())==ParticleID::SUSY_chi_1plus||
 	    //  	  abs(inter.first ->id())==ParticleID::SUSY_chi_2plus)&&
 	    //  	 abs(inter.second->id())!=ParticleID::Wplus&&
 	    //  	 abs(inter.second->id())!=ParticleID::Hplus&&
 	    //  	 inter.second->id()<0)) {
 	    //   ++idiag;
 	    //   continue;
 	    // }
 	    // chi W and charged slepton
 	    // if(!((abs(inter.first ->id())==ParticleID::SUSY_chi_1plus||
 	    // 	  abs(inter.first ->id())==ParticleID::SUSY_chi_2plus)&&
 	    // 	 abs(inter.second->id())==ParticleID::Wplus) &&
 	    //    !((abs(inter.first ->id())==ParticleID::SUSY_chi_1plus||
 	    // 	  abs(inter.first ->id())==ParticleID::SUSY_chi_2plus)&&
 	    // 	 abs(inter.second->id())!=ParticleID::Wplus&&
 	    // 	 inter.second->id()>0) ) {
 	    //   ++idiag;
 	    //   continue;
 	    // }
 	    // chi W and sneutrino
 	    // if(!((abs(inter.first ->id())==ParticleID::SUSY_chi_1plus||
 	    // 	  abs(inter.first ->id())==ParticleID::SUSY_chi_2plus)&&
 	    // 	 abs(inter.second->id())==ParticleID::Wplus) &&
 	    //    !((abs(inter.first ->id())==ParticleID::SUSY_chi_1plus||
 	    // 	  abs(inter.first ->id())==ParticleID::SUSY_chi_2plus)&&
 	    // 	 abs(inter.second->id())!=ParticleID::Wplus&&
 	    // 	 inter.second->id()<0) ) {
 	    //   ++idiag;
 	    //   continue;
 	    // }
 	    // top/sbottom interference
 	    // if(!(abs(inter.first ->id())==ParticleID::t&&
 	    // 	 abs(inter.second->id())==ParticleID::Wplus)&&
 	    //    !((abs(inter.first ->id())==ParticleID::SUSY_b_1||
 	    // 	  abs(inter.first ->id())==ParticleID::SUSY_b_2)&&
 	    // 	 abs(inter.second->id())==ParticleID::Wplus)) {
 	    //   ++idiag;
 	    //   continue;
 	    // }
 	    // top chiW interference
 	    // if(!(abs(inter.first ->id())==ParticleID::t&&
 	    // 	 abs(inter.second->id())==ParticleID::Wplus)&&
 	    //    !((abs(inter.first ->id())==ParticleID::SUSY_chi_1plus||
 	    //  	  abs(inter.first ->id())==ParticleID::SUSY_chi_2plus)&&
 	    //  	 abs(inter.second->id())==ParticleID::Wplus)) {
 	    //   ++idiag;
 	    //   continue;
 	    // }
 	    // bottom chiW interference
 	    // if(!((abs(inter.first ->id())==ParticleID::SUSY_b_1||
 	    //  	  abs(inter.first ->id())==ParticleID::SUSY_b_2)&&
 	    // 	 abs(inter.second->id())==ParticleID::Wplus)&&
 	    //    !((abs(inter.first ->id())==ParticleID::SUSY_chi_1plus||
 	    //   	  abs(inter.first ->id())==ParticleID::SUSY_chi_2plus)&&
 	    //   	 abs(inter.second->id())==ParticleID::Wplus)) {
 	    //   ++idiag;
 	    //   continue;
 	    // }
 	    // top charged slepton
 	    // if(!(abs(inter.first ->id())==ParticleID::t&&
 	    // 	 abs(inter.second->id())==ParticleID::Wplus) &&
 	    //    !((abs(inter.first ->id())==ParticleID::SUSY_chi_1plus||
 	    //  	  abs(inter.first ->id())==ParticleID::SUSY_chi_2plus)&&
 	    //  	 abs(inter.second->id())!=ParticleID::Wplus&&
 	    //  	 inter.second->id()>0)) {
 	    //   ++idiag;
 	    //   continue;
 	    // }
 	    // top sneutrino
 	    // if(!(abs(inter.first ->id())==ParticleID::t&&
 	    // 	 abs(inter.second->id())==ParticleID::Wplus) &&
 	    //    !((abs(inter.first ->id())==ParticleID::SUSY_chi_1plus||
 	    //  	  abs(inter.first ->id())==ParticleID::SUSY_chi_2plus)&&
 	    //  	 abs(inter.second->id())!=ParticleID::Wplus&&
 	    //  	 inter.second->id()<0)) {
 	    //   ++idiag;
 	    //   continue;
 	    // }
 	    // ~b sneutrino
 	    // if(!((abs(inter.first ->id())==ParticleID::SUSY_b_1||
 	    //   	  abs(inter.first ->id())==ParticleID::SUSY_b_2)&&
 	    //  	 abs(inter.second->id())==ParticleID::Wplus)&&
 	    //    !((abs(inter.first ->id())==ParticleID::SUSY_chi_1plus||
 	    //  	  abs(inter.first ->id())==ParticleID::SUSY_chi_2plus)&&
 	    //  	 abs(inter.second->id())!=ParticleID::Wplus&&
 	    //  	 inter.second->id()<0)) {
 	    //   ++idiag;
 	    //   continue;
 	    // }
 	    // ~b slepton
 	    // if(!((abs(inter.first ->id())==ParticleID::SUSY_b_1||
 	    //   	  abs(inter.first ->id())==ParticleID::SUSY_b_2)&&
 	    //  	 abs(inter.second->id())==ParticleID::Wplus)&&
 	    //    !((abs(inter.first ->id())==ParticleID::SUSY_chi_1plus||
 	    //  	  abs(inter.first ->id())==ParticleID::SUSY_chi_2plus)&&
 	    //  	 abs(inter.second->id())!=ParticleID::Wplus&&
 	    //  	 inter.second->id()>0)) {
 	    //   ++idiag;
 	    //   continue;
 	    // }
 
 
 	    // top H
 	    // if(!(abs(inter.first ->id())==ParticleID::t&&
 	    // 	 abs(inter.second->id())==ParticleID::Hplus)) {
 	    //   ++idiag;
 	    //   continue;
 	    // }
 	    // sbottom H
 	    // if(!((abs(inter.first ->id())==ParticleID::SUSY_b_1||
 	    // 	  abs(inter.first ->id())==ParticleID::SUSY_b_2)&&
 	    // 	 abs(inter.second->id())==ParticleID::Hplus)) {
 	    //   ++idiag;
 	    //   continue;
 	    // }
 	    // chargino H
 	    // if(!((abs(inter.first ->id())==ParticleID::SUSY_chi_1plus||
 	    // 	  abs(inter.first ->id())==ParticleID::SUSY_chi_2plus)&&
 	    // 	 abs(inter.second->id())==ParticleID::Hplus)) {
 	    //   ++idiag;
 	    //   continue;
 	    // }
 	    // top/sbottom interference
 	    // if(!(abs(inter.first ->id())==ParticleID::t&&
 	    // 	 abs(inter.second->id())==ParticleID::Hplus)&&
 	    //    !((abs(inter.first ->id())==ParticleID::SUSY_b_1||
 	    // 	  abs(inter.first ->id())==ParticleID::SUSY_b_2)&&
 	    // 	 abs(inter.second->id())==ParticleID::Hplus)) {
 	    //   ++idiag;
 	    //   continue;
 	    // }
 	    // top chiH interference
 	    // if(!(abs(inter.first ->id())==ParticleID::t&&
 	    // 	 abs(inter.second->id())==ParticleID::Hplus)&&
 	    //    !((abs(inter.first ->id())==ParticleID::SUSY_chi_1plus||
 	    //  	  abs(inter.first ->id())==ParticleID::SUSY_chi_2plus)&&
 	    //  	 abs(inter.second->id())==ParticleID::Hplus)) {
 	    //   ++idiag;
 	    //   continue;
 	    // }
 	    // bottom chiH interference
 	    // if(!((abs(inter.first ->id())==ParticleID::SUSY_b_1||
 	    //  	  abs(inter.first ->id())==ParticleID::SUSY_b_2)&&
 	    // 	 abs(inter.second->id())==ParticleID::Hplus)&&
 	    //    !((abs(inter.first ->id())==ParticleID::SUSY_chi_1plus||
 	    //   	  abs(inter.first ->id())==ParticleID::SUSY_chi_2plus)&&
 	    //   	 abs(inter.second->id())==ParticleID::Hplus)) {
 	    //   ++idiag;
 	    //   continue;
 	    // }
 	    // all Higgs
 	    // if(abs(inter.second->id())==ParticleID::Hplus) {
 	    //   ++idiag;
 	    //   continue;
 	    // }
 //reomved from end of me2()
 //InvEnergy2 output = stopMatrixElement(inpart,decay,me2*UnitRemoval::InvE2);
   // return output*scale;
diff --git a/Decay/General/StoFFVDecayer.cc b/Decay/General/StoFFVDecayer.cc
--- a/Decay/General/StoFFVDecayer.cc
+++ b/Decay/General/StoFFVDecayer.cc
@@ -1,387 +1,389 @@
 // -*- C++ -*-
 //
 // This is the implementation of the non-inlined, non-templated member
 // functions of the StoFFVDecayer class.
 //
 
 #include "StoFFVDecayer.h"
 #include "ThePEG/Utilities/DescribeClass.h"
 #include "ThePEG/Interface/ClassDocumentation.h"
 #include "ThePEG/Persistency/PersistentOStream.h"
 #include "ThePEG/Persistency/PersistentIStream.h"
 #include "Herwig/PDT/ThreeBodyAllOnCalculator.h"
 #include "Herwig/Decay/GeneralDecayMatrixElement.h"
 #include <numeric>
 
 using namespace Herwig;
 using namespace ThePEG;
 using namespace ThePEG::Helicity;
 
 IBPtr StoFFVDecayer::clone() const {
   return new_ptr(*this);
 }
 
 IBPtr StoFFVDecayer::fullclone() const {
   return new_ptr(*this);
 }
 
 void StoFFVDecayer::persistentOutput(PersistentOStream & os) const {
   os << sca_ << fer_ << vec_ << RSfer_ << four_;
 }
 
 void StoFFVDecayer::persistentInput(PersistentIStream & is, int) {
   is >> sca_ >> fer_ >> vec_ >> RSfer_ >> four_;
 }
 
 // The following static variable is needed for the type
 // description system in ThePEG.
 DescribeClass<StoFFVDecayer,GeneralThreeBodyDecayer>
 describeHerwigStoFFVDecayer("Herwig::StoFFVDecayer", "Herwig.so");
 
 void StoFFVDecayer::Init() {
 
   static ClassDocumentation<StoFFVDecayer> documentation
     ("The StoFFVDecayer class implements the general decay of a scalar to "
      "a two fermions and a vector.");
 
 }
 
 WidthCalculatorBasePtr StoFFVDecayer::
 threeBodyMEIntegrator(const DecayMode & ) const {
   vector<int> intype;
   vector<Energy> inmass,inwidth;
   vector<double> inpow,inweights;
   constructIntegratorChannels(intype,inmass,inwidth,inpow,inweights);
   return new_ptr(ThreeBodyAllOnCalculator<StoFFVDecayer>
 		 (inweights,intype,inmass,inwidth,inpow,*this,0,
 		  outgoing()[0]->mass(),outgoing()[1]->mass(),
 		  outgoing()[2]->mass(),relativeError()));
 }
 
 void StoFFVDecayer::doinit() {
   GeneralThreeBodyDecayer::doinit();
   if(outgoing().empty()) return;
   unsigned int ndiags = getProcessInfo().size();
   sca_.resize(ndiags);
   fer_.resize(ndiags);
   RSfer_.resize(ndiags);
   vec_.resize(ndiags);
   four_.resize(ndiags);
   for(unsigned int ix = 0;ix < ndiags; ++ix) {
     TBDiagram current = getProcessInfo()[ix];
     tcPDPtr offshell = current.intermediate;
     // four point vertex
     if(!offshell) {
       four_[ix] = dynamic_ptr_cast<AbstractFFVSVertexPtr>(current.vertices.first);
       continue;
     }
     if( offshell->CC() ) offshell = offshell->CC();
     if(offshell->iSpin() == PDT::Spin0) {
       AbstractVSSVertexPtr vert1 = dynamic_ptr_cast<AbstractVSSVertexPtr>
 	(current.vertices.first);
       AbstractFFSVertexPtr vert2 = dynamic_ptr_cast<AbstractFFSVertexPtr>
 	(current.vertices.second);
       if(!vert1||!vert2) throw Exception() 
 	<< "Invalid vertices for a scalar diagram in StoFFVDecayer::doinit()"
 	<< Exception::runerror;
       sca_[ix] = make_pair(vert1, vert2);
     }
     else if(offshell->iSpin() == PDT::Spin1Half) {
       AbstractFFSVertexPtr vert1 = dynamic_ptr_cast<AbstractFFSVertexPtr>
 	(current.vertices.first);
       AbstractFFVVertexPtr vert2 = dynamic_ptr_cast<AbstractFFVVertexPtr>
 	(current.vertices.second);
       if(!vert1||!vert2) throw Exception() 
 	<< "Invalid vertices for a fermion diagram in StoFFVDecayer::doinit()"
 	<< Exception::runerror;
       fer_[ix] = make_pair(vert1, vert2);
     }
     else if(offshell->iSpin() == PDT::Spin1) {
       AbstractVVSVertexPtr vert1 = dynamic_ptr_cast<AbstractVVSVertexPtr>
 	(current.vertices.first);
       AbstractFFVVertexPtr vert2 = dynamic_ptr_cast<AbstractFFVVertexPtr>
 	(current.vertices.second);
       if(!vert1||!vert2) throw Exception() 
 	<< "Invalid vertices for a vector diagram in StoFFVDecayer::doinit()"
 	<< Exception::runerror;
       vec_[ix] = make_pair(vert1, vert2);
     }
     else if(offshell->iSpin() == PDT::Spin3Half) {
       AbstractRFSVertexPtr vert1 = dynamic_ptr_cast<AbstractRFSVertexPtr>
 	(current.vertices.first);
       AbstractRFVVertexPtr vert2 = dynamic_ptr_cast<AbstractRFVVertexPtr>
 	(current.vertices.second);
       if(!vert1||!vert2) throw Exception() 
 	<< "Invalid vertices for a RS fermion diagram in StoFFVDecayer::doinit()"
 	<< Exception::runerror;
       RSfer_[ix] = make_pair(vert1, vert2);
     }
   }
 }
 
 double StoFFVDecayer::me2(const int ichan, const Particle & inpart,
 			  const ParticleVector & decay, MEOption meopt) const {
   // particle or CC of particle
   bool cc = (*getProcessInfo().begin()).incoming != inpart.id();
   // special handling or first/last call
   if(meopt==Initialize) {
     ScalarWaveFunction::
       calculateWaveFunctions(rho_,const_ptr_cast<tPPtr>(&inpart),
 			     Helicity::incoming);
     swave_ = ScalarWaveFunction(inpart.momentum(),inpart.dataPtr(),
 				Helicity::incoming);
+    // fix rho if no correlations
+    fixRho(rho_);
   }
   if(meopt==Terminate) {
     ScalarWaveFunction::
       constructSpinInfo(const_ptr_cast<tPPtr>(&inpart),
 			Helicity::incoming,true);
     for(unsigned int ix=0;ix<decay.size();++ix) {
       if(decay[ix]->dataPtr()->iSpin()==PDT::Spin1) {
 	VectorWaveFunction::constructSpinInfo(outVector_,decay[ix],
 					      Helicity::outgoing,true,false);
       }
       else {
 	SpinorWaveFunction::
 	  constructSpinInfo(outspin_[ix].first,decay[ix],Helicity::outgoing,true);
       }
     }
   }
   unsigned int ivec(0);
   bool massless(false);
   for(unsigned int ix = 0; ix < decay.size();++ix) {
     if(decay[ix]->dataPtr()->iSpin() == PDT::Spin1) {
       ivec = ix;
       massless = decay[ivec]->mass()==ZERO;
       VectorWaveFunction::
 	calculateWaveFunctions(outVector_, decay[ix], Helicity::outgoing,massless);
     }
     else {
       SpinorWaveFunction::
 	calculateWaveFunctions(outspin_[ix].first,decay[ix],Helicity::outgoing);
       outspin_[ix].second.resize(2);
       // Need a ubar and a v spinor
       if(outspin_[ix].first[0].wave().Type() == SpinorType::u) {
 	for(unsigned int iy = 0; iy < 2; ++iy) {
 	  outspin_[ix].second[iy] = outspin_[ix].first[iy].bar();
 	  outspin_[ix].first[iy].conjugate();
 	}
       }
       else {
 	for(unsigned int iy = 0; iy < 2; ++iy) {
 	  outspin_[ix].second[iy] = outspin_[ix].first[iy].bar();
 	  outspin_[ix].second[iy].conjugate();
 	}
       }
     }
   }
   const vector<vector<double> > cfactors(getColourFactors());
   const vector<vector<double> > nfactors(getLargeNcColourFactors());
   Energy2 scale(sqr(inpart.mass()));
   const size_t ncf(numberOfFlows());
   vector<Complex> flows(ncf, Complex(0.)), largeflows(ncf, Complex(0.));
   // setup the DecayMatrixElement
   vector<GeneralDecayMEPtr> 
     mes(ncf,new_ptr(GeneralDecayMatrixElement(PDT::Spin0,
 					      ivec == 0 ? PDT::Spin1 : PDT::Spin1Half,
 					      ivec == 1 ? PDT::Spin1 : PDT::Spin1Half,
 					      ivec == 2 ? PDT::Spin1 : PDT::Spin1Half)));
   vector<GeneralDecayMEPtr> 
     mel(ncf,new_ptr(GeneralDecayMatrixElement(PDT::Spin0,
 					      ivec == 0 ? PDT::Spin1 : PDT::Spin1Half,
 					      ivec == 1 ? PDT::Spin1 : PDT::Spin1Half,
 					      ivec == 2 ? PDT::Spin1 : PDT::Spin1Half)));
   //the channel possiblities
   static const unsigned int out2[3] = {1,0,0}, out3[3] = {2,2,1};
   for(unsigned int s1 = 0; s1 < 2; ++s1) {
     for(unsigned int s2 = 0; s2 < 2; ++s2) {
       for(unsigned int v1 = 0; v1 < 3; ++v1) {
 	if(massless&&v1==1) ++v1;
 	flows = vector<Complex>(ncf, Complex(0.));
 	largeflows = vector<Complex>(ncf, Complex(0.));
 	unsigned int idiag(0);
 	Complex diag;
 	for(vector<TBDiagram>::const_iterator dit=getProcessInfo().begin();
 	    dit!=getProcessInfo().end();++dit) {
 	  // channels if selecting
 	  if( ichan >= 0 && diagramMap()[ichan] != idiag ) {
 	    ++idiag;
 	    continue;
 	  }
 	  tcPDPtr offshell = dit->intermediate;
 	  if(offshell) {
 	    if(cc&&offshell->CC()) offshell=offshell->CC();
 	    unsigned int o2(out2[dit->channelType]), o3(out3[dit->channelType]);
 	    double sign = (o3 < o2) ? 1. : -1.;
 	    // intermediate scalar
 	    if(offshell->iSpin() == PDT::Spin0) {
 	      ScalarWaveFunction inters = sca_[idiag].first->
 		evaluate(scale, widthOption(), offshell, outVector_[v1], swave_);
 	      unsigned int h1(s1),h2(s2);
 	      if(o2 > o3) swap(h1, h2);
 	      if(decay[o2]->id() < 0 &&  decay[o3]->id() > 0) {
 		diag = -sign*sca_[idiag].second->
 		  evaluate(scale,outspin_[o2].first[h1],
 			   outspin_[o3].second[h2],inters);
 	      }
 	      else {
 		diag = sign*sca_[idiag].second->
 		  evaluate(scale, outspin_[o3].first [h2],
 			   outspin_[o2].second[h1],inters);
 	      }
 	    }
 	    // intermediate fermion
 	    else if(offshell->iSpin() == PDT::Spin1Half) {
 	      int iferm = (decay[o2]->dataPtr()->iSpin() == PDT::Spin1Half) 
 		? o2 : o3;
 	      unsigned int h1(s1),h2(s2);
 	      if(dit->channelType > iferm) swap(h1, h2);
 	      sign = iferm < dit->channelType ? 1. : -1.;
 	      if((decay[dit->channelType]->id() < 0 && decay[iferm]->id() > 0 ) ||
 		 (decay[dit->channelType]->id()*offshell->id()>0)) {
 		SpinorWaveFunction inters = fer_[idiag].first->
 		  evaluate(scale,widthOption(),offshell,
 			   outspin_[dit->channelType].first[h1], swave_);
 		diag = -sign*fer_[idiag].second->
 		  evaluate(scale,inters,outspin_[iferm].second[h2], outVector_[v1]);
 	      }
 	      else {
 		SpinorBarWaveFunction inters = fer_[idiag].first->
 		  evaluate(scale,widthOption(),offshell,
 			   outspin_[dit->channelType].second[h1],swave_);
 		diag =  sign*fer_[idiag].second->
 		  evaluate(scale,outspin_[iferm].first [h2],inters, outVector_[v1]);
 	      }
 	    }
 	    // intermediate vector
 	    else if(offshell->iSpin() == PDT::Spin1) {
 	      VectorWaveFunction interv = vec_[idiag].first->
 		evaluate(scale, widthOption(), offshell, outVector_[v1], swave_);
 	      unsigned int h1(s1),h2(s2);
 	      if(o2 > o3) swap(h1,h2);
 	      if(decay[o2]->id() < 0 && decay[o3]->id() > 0) {
 		diag =-sign*vec_[idiag].second->
 		  evaluate(scale, outspin_[o2].first[h1],
 			   outspin_[o3].second[h2], interv);
 	      }
 	      else {
 		diag = sign*vec_[idiag].second->
 		  evaluate(scale, outspin_[o3].first[h2],
 			   outspin_[o2].second[h1], interv);
 	      }
 	    }
 	    // intermediate RS fermion
 	    else if(offshell->iSpin() == PDT::Spin3Half) {
 	      int iferm = (decay[o2]->dataPtr()->iSpin() == PDT::Spin1Half) 
 		? o2 : o3;
 	      unsigned int h1(s1),h2(s2);
 	      if(dit->channelType > iferm) swap(h1, h2);
 	      sign = iferm < dit->channelType ? 1. : -1.;
 	      if((decay[dit->channelType]->id() < 0 && decay[iferm]->id() > 0 ) ||
 		 (decay[dit->channelType]->id()*offshell->id()>0)) {
 		RSSpinorWaveFunction inters = RSfer_[idiag].first->
 		  evaluate(scale,widthOption(),offshell,
 			   outspin_[dit->channelType].first[h1], swave_);
 		diag = -sign*RSfer_[idiag].second->
 		  evaluate(scale,inters,outspin_[iferm].second[h2], outVector_[v1]);
 	      }
 	      else {
 		RSSpinorBarWaveFunction inters = RSfer_[idiag].first->
 		  evaluate(scale,widthOption(),offshell,
 			   outspin_[dit->channelType].second[h1],swave_);
 		diag =  sign*RSfer_[idiag].second->
 		  evaluate(scale,outspin_[iferm].first [h2],inters, outVector_[v1]);
 	      }
 	    }
 	    // unknown
 	    else throw Exception()
 		   << "Unknown intermediate in StoFFVDecayer::me2()" 
 		   << Exception::runerror;
 	  }
 	  else {
 	    unsigned int o2 = ivec > 0 ? 0 : 1;
 	    unsigned int o3 = ivec < 2 ? 2 : 1;
 	    if(decay[o2]->id() < 0 && decay[o3]->id() > 0) {
 	      diag =-four_[idiag]->
 	    	evaluate(scale, outspin_[o2].first[s1],
 	    		 outspin_[o3].second[s2], outVector_[v1], swave_);
 	    }
 	    else {
 	      diag = four_[idiag]->
 	    	evaluate(scale, outspin_[o3].first[s2],
 	    		 outspin_[o2].second[s1], outVector_[v1], swave_);
 	    }
 	  }
 	  // matrix element for the different colour flows
 	  if(ichan < 0) {
 	    for(unsigned iy = 0; iy < dit->colourFlow.size(); ++iy) {
 	      flows[dit->colourFlow[iy].first - 1] += 
 		dit->colourFlow[iy].second * diag;
 	    }
 	    for(unsigned iy = 0; iy < dit->largeNcColourFlow.size(); ++iy) {
 	      largeflows[dit->largeNcColourFlow[iy].first - 1] += 
 		dit->largeNcColourFlow[iy].second * diag;
 	    }
 	  }
 	  else {
 	    for(unsigned iy = 0; iy < dit->colourFlow.size(); ++iy) {
 	      if(dit->colourFlow[iy].first - 1 != colourFlow()) continue;
 	      flows[dit->colourFlow[iy].first - 1] += 
 		dit->colourFlow[iy].second * diag;
 	    }
 	    for(unsigned iy = 0; iy < dit->largeNcColourFlow.size(); ++iy) {
 	      if(dit->colourFlow[iy].first - 1!=colourFlow()) continue;
 	      largeflows[dit->largeNcColourFlow[iy].first - 1] += 
 		dit->largeNcColourFlow[iy].second * diag;
 	    }
 	  }
 	  ++idiag;
 	} //end of diagrams
 	// now add the flows to the me2 with appropriate colour factors
 	for(unsigned int ix = 0; ix < ncf; ++ix) {
 	  if ( ivec == 0 ) { 
 	    (*mes[ix])(0, v1, s1, s2) = flows[ix];
 	    (*mel[ix])(0, v1, s1, s2) = largeflows[ix];
 	  }
 	  else if( ivec == 1 ) {
 	    (*mes[ix])(0, s1, v1, s2) = flows[ix];
 	    (*mel[ix])(0, s1, v1, s2) = largeflows[ix];
 	  }
 	  else if( ivec == 2 ) {
 	    (*mes[ix])(0, s1, s2, v1) = flows[ix];
 	    (*mel[ix])(0, s1, s2, v1) = largeflows[ix];
 	  }
 	}
       }
     }
   }
   double me2(0.);
   if(ichan < 0) {
     vector<double> pflows(ncf,0.);
     for(unsigned int ix = 0; ix < ncf; ++ix) {
       for(unsigned int iy = 0; iy < ncf; ++ iy) {
 	double con = cfactors[ix][iy]*(mes[ix]->contract(*mes[iy],rho_)).real();
 	me2 += con;
 	if(ix == iy) {
 	  con = nfactors[ix][iy]*(mel[ix]->contract(*mel[iy],rho_)).real();
 	  pflows[ix] += con;
 	}
       }
     }
     double ptotal(std::accumulate(pflows.begin(),pflows.end(),0.));
     ptotal *= UseRandom::rnd();
     for(unsigned int ix = 0;ix < pflows.size(); ++ix) {
       if(ptotal <= pflows[ix]) {
 	colourFlow(ix);
 	ME(mes[ix]);
 	break;
       }
       ptotal -= pflows[ix];
     }
   }
   else {
     unsigned int iflow = colourFlow();
     me2 = nfactors[iflow][iflow]*(mel[iflow]->contract(*mel[iflow],rho_)).real();
   }
   // return the matrix element squared
   return me2;
 }
diff --git a/Decay/General/StoSFFDecayer.cc b/Decay/General/StoSFFDecayer.cc
--- a/Decay/General/StoSFFDecayer.cc
+++ b/Decay/General/StoSFFDecayer.cc
@@ -1,422 +1,424 @@
 // -*- C++ -*-
 //
 // This is the implementation of the non-inlined, non-templated member
 // functions of the StoSFFDecayer class.
 //
 
 #include "StoSFFDecayer.h"
 #include "ThePEG/Utilities/DescribeClass.h"
 #include "ThePEG/Interface/ClassDocumentation.h"
 #include "ThePEG/Persistency/PersistentOStream.h"
 #include "ThePEG/Persistency/PersistentIStream.h"
 #include "Herwig/PDT/ThreeBodyAllOnCalculator.h"
 #include "Herwig/Decay/GeneralDecayMatrixElement.h"
 #include <numeric>
 
 using namespace Herwig;
 using namespace ThePEG;
 using namespace ThePEG::Helicity;
 
 IBPtr StoSFFDecayer::clone() const {
   return new_ptr(*this);
 }
 
 IBPtr StoSFFDecayer::fullclone() const {
   return new_ptr(*this);
 }
 
 void StoSFFDecayer::persistentOutput(PersistentOStream & os) const {
   os << sca_ << fer_ << vec_ << ten_ << RSfer_ << four_;
 }
 
 void StoSFFDecayer::persistentInput(PersistentIStream & is, int) {
   is >> sca_ >> fer_ >> vec_ >> ten_ >> RSfer_ >> four_;
 }
 
 // The following static variable is needed for the type
 // description system in ThePEG.
 DescribeClass<StoSFFDecayer,GeneralThreeBodyDecayer>
 describeHerwigStoSFFDecayer("Herwig::StoSFFDecayer", "Herwig.so");
 
 void StoSFFDecayer::Init() {
 
   static ClassDocumentation<StoSFFDecayer> documentation
     ("The StoSFFDecayer class implements the general decay of a scalar to "
      "a scalar and two fermions.");
 
 }
 
 WidthCalculatorBasePtr StoSFFDecayer::
 threeBodyMEIntegrator(const DecayMode & ) const {
   vector<int> intype;
   vector<Energy> inmass,inwidth;
   vector<double> inpow,inweights;
   constructIntegratorChannels(intype,inmass,inwidth,inpow,inweights);
   return new_ptr(ThreeBodyAllOnCalculator<StoSFFDecayer>
 		 (inweights,intype,inmass,inwidth,inpow,*this,0,
 		  outgoing()[0]->mass(),outgoing()[1]->mass(),outgoing()[2]->mass(),
 		  relativeError()));
 }
 
 void StoSFFDecayer::doinit() {
   GeneralThreeBodyDecayer::doinit();
   if(outgoing().empty()) return;
   unsigned int ndiags = getProcessInfo().size();
   sca_.resize(ndiags);
   fer_.resize(ndiags);
   RSfer_.resize(ndiags);
   vec_.resize(ndiags);
   ten_.resize(ndiags);
   four_.resize(ndiags);
   for(unsigned int ix = 0;ix < ndiags; ++ix) {
     TBDiagram current = getProcessInfo()[ix];
     tcPDPtr offshell = current.intermediate;
     // four point vertex
     if(!offshell) {
       four_[ix] = dynamic_ptr_cast<AbstractFFSSVertexPtr>(current.vertices.first);
       continue;
     }
     if( offshell->CC() ) offshell = offshell->CC();
     if(offshell->iSpin() == PDT::Spin0) {
       AbstractSSSVertexPtr vert1 = dynamic_ptr_cast<AbstractSSSVertexPtr>
 	(current.vertices.first);
       AbstractFFSVertexPtr vert2 = dynamic_ptr_cast<AbstractFFSVertexPtr>
 	(current.vertices.second);
       if(!vert1||!vert2) throw Exception() 
 	<< "Invalid vertices for a scalar diagram in StoSFFDecayer::doinit()"
 	<< Exception::runerror;
       sca_[ix] = make_pair(vert1, vert2);
     }
     else if(offshell->iSpin() == PDT::Spin1Half) {
       AbstractFFSVertexPtr vert1 = dynamic_ptr_cast<AbstractFFSVertexPtr>
 	(current.vertices.first);
       AbstractFFSVertexPtr vert2 = dynamic_ptr_cast<AbstractFFSVertexPtr>
 	(current.vertices.second);
       if(!vert1||!vert2) throw Exception() 
 	<< "Invalid vertices for a fermion diagram in StoSFFDecayer::doinit()"
 	<< Exception::runerror;
       fer_[ix] = make_pair(vert1, vert2);
     }
     else if(offshell->iSpin() == PDT::Spin1) {
       AbstractVSSVertexPtr vert1 = dynamic_ptr_cast<AbstractVSSVertexPtr>
 	(current.vertices.first);
       AbstractFFVVertexPtr vert2 = dynamic_ptr_cast<AbstractFFVVertexPtr>
 	(current.vertices.second);
       if(!vert1||!vert2) throw Exception() 
 	<< "Invalid vertices for a vector diagram in StoSFFDecayer::doinit()"
 	<< Exception::runerror;
       vec_[ix] = make_pair(vert1, vert2);
     }
     else if(offshell->iSpin() == PDT::Spin2) {
       AbstractSSTVertexPtr vert1 = dynamic_ptr_cast<AbstractSSTVertexPtr>
 	(current.vertices.first);
       AbstractFFTVertexPtr vert2 = dynamic_ptr_cast<AbstractFFTVertexPtr>
 	(current.vertices.second);
       if(!vert1||!vert2) throw Exception() 
 	<< "Invalid vertices for a tensor diagram in StoSFFDecayer::doinit()"
 	<< Exception::runerror;
       ten_[ix] = make_pair(vert1, vert2);
     }
     else if(offshell->iSpin() == PDT::Spin3Half) {
       AbstractRFSVertexPtr vert1 = dynamic_ptr_cast<AbstractRFSVertexPtr>
 	(current.vertices.first);
       AbstractRFSVertexPtr vert2 = dynamic_ptr_cast<AbstractRFSVertexPtr>
 	(current.vertices.second);
       if(!vert1||!vert2) throw Exception() 
 	<< "Invalid vertices for a RS fermion diagram in StoSFFDecayer::doinit()"
 	<< Exception::runerror;
       RSfer_[ix] = make_pair(vert1, vert2);
     }
   }
 }
 
 double StoSFFDecayer::me2(const int ichan, const Particle & inpart,
 			  const ParticleVector & decay,
 			  MEOption meopt) const {
   // particle or CC of particle
   bool cc = (*getProcessInfo().begin()).incoming != inpart.id();
   // special handling or first/last call
   if(meopt==Initialize) {
     ScalarWaveFunction::
       calculateWaveFunctions(rho_,const_ptr_cast<tPPtr>(&inpart),
 			     Helicity::incoming);
     swave_ = ScalarWaveFunction(inpart.momentum(),inpart.dataPtr(),
 				Helicity::incoming);
+    // fix rho if no correlations
+    fixRho(rho_);
   }
   if(meopt==Terminate) {
     ScalarWaveFunction::
       constructSpinInfo(const_ptr_cast<tPPtr>(&inpart),
 			Helicity::incoming,true);
     for(unsigned int ix=0;ix<decay.size();++ix) {
       if(decay[ix]->dataPtr()->iSpin()==PDT::Spin0) {
 	ScalarWaveFunction::constructSpinInfo(decay[ix],Helicity::outgoing,true);
       }
       else {
 	SpinorWaveFunction::
 	  constructSpinInfo(outspin_[ix].first,decay[ix],Helicity::outgoing,true);
       }
     }
     return 0.;
   }
   // get the wavefunctions for all the particles
   ScalarWaveFunction outScalar;
   unsigned int isca(0);
   for(unsigned int ix=0;ix<decay.size();++ix) {
     if(decay[ix]->dataPtr()->iSpin()==PDT::Spin0) {
       isca = ix;
       outScalar = ScalarWaveFunction(decay[ix]->momentum(),
 				     decay[ix]->dataPtr(),Helicity::outgoing);
     }
     else {
       SpinorWaveFunction::
 	calculateWaveFunctions(outspin_[ix].first,decay[ix],Helicity::outgoing);
       outspin_[ix].second.resize(2);
       if(outspin_[ix].first[0].wave().Type() == SpinorType::u) {
 	for(unsigned int iy = 0; iy < 2; ++iy) {
 	  outspin_[ix].second[iy] = outspin_[ix].first[iy].bar();
 	  outspin_[ix].first[iy].conjugate();
 	}
       }
       else {
 	for(unsigned int iy = 0; iy < 2; ++iy) {
 	  outspin_[ix].second[iy] = outspin_[ix].first[iy].bar();
 	  outspin_[ix].second[iy].conjugate();
 	}
       }
     }
   }
   const vector<vector<double> > cfactors(getColourFactors());
   const vector<vector<double> > nfactors(getLargeNcColourFactors());
   Energy2 scale(sqr(inpart.mass()));  
   const size_t ncf(numberOfFlows());
   vector<Complex> flows(ncf, Complex(0.)), largeflows(ncf, Complex(0.)); 
   vector<GeneralDecayMEPtr> 
     mes(ncf,new_ptr(GeneralDecayMatrixElement(PDT::Spin0,
 					      isca==0 ? PDT::Spin0 : PDT::Spin1Half,
 					      isca==1 ? PDT::Spin0 : PDT::Spin1Half,
 					      isca==2 ? PDT::Spin0 : PDT::Spin1Half)));
   vector<GeneralDecayMEPtr> 
     mel(ncf,new_ptr(GeneralDecayMatrixElement(PDT::Spin0,
 					      isca == 0 ? PDT::Spin0 : PDT::Spin1Half,
 					      isca == 1 ? PDT::Spin0 : PDT::Spin1Half,
 					      isca == 2 ? PDT::Spin0 : PDT::Spin1Half)));
   static const unsigned int out2[3]={1,0,0},out3[3]={2,2,1};
   for(unsigned int s1 = 0;s1 < 2; ++s1) {
     for(unsigned int s2 = 0;s2 < 2; ++s2) {
       flows = vector<Complex>(ncf, Complex(0.));
       largeflows = vector<Complex>(ncf, Complex(0.));
       unsigned int idiag(0);
       for(vector<TBDiagram>::const_iterator dit = getProcessInfo().begin();
 	  dit != getProcessInfo().end(); ++dit) {
 	// channels if selecting
 	if( ichan >= 0 && diagramMap()[ichan] != idiag ) {
 	  ++idiag;
 	  continue;
 	}
 	tcPDPtr offshell = dit->intermediate;
 	Complex diag;
 	if(offshell) {
 	  if(cc&&offshell->CC()) offshell=offshell->CC();
 	  double sign = out3[dit->channelType] < out2[dit->channelType] ? 1. : -1.;
 	  // intermediate scalar
 	  if     (offshell->iSpin() == PDT::Spin0) {
 	    ScalarWaveFunction inters = sca_[idiag].first->
 	      evaluate(scale, widthOption(), offshell, swave_, outScalar);
 	    unsigned int h1(s1),h2(s2);
 	    if(out2[dit->channelType]>out3[dit->channelType]) swap(h1,h2);
 	    if(decay[out2[dit->channelType]]->id()<0&&
 	       decay[out3[dit->channelType]]->id()>0) {
 	      diag =-sign*sca_[idiag].second->
 		evaluate(scale,
 			 outspin_[out2[dit->channelType]].first [h1],
 			 outspin_[out3[dit->channelType]].second[h2],inters);
 	    }
 	    else {
 	      diag = sign*sca_[idiag].second->
 		evaluate(scale,
 			 outspin_[out3[dit->channelType]].first [h2],
 			 outspin_[out2[dit->channelType]].second[h1],inters);
 	    }
 	  }
 	  // intermediate fermion
 	  else if(offshell->iSpin() == PDT::Spin1Half) {
 	    int iferm = 
 	      decay[out2[dit->channelType]]->dataPtr()->iSpin()==PDT::Spin1Half
 	      ? out2[dit->channelType] : out3[dit->channelType];
 	    unsigned int h1(s1),h2(s2);
 	    if(dit->channelType>iferm) swap(h1,h2);
 	    sign = iferm<dit->channelType ? 1. : -1.;
 	    
 	    
 	    if((decay[dit->channelType]->id() < 0 &&decay[iferm]->id() > 0 ) ||
 	       (decay[dit->channelType]->id()*offshell->id()>0)) {
 	      SpinorWaveFunction    inters = fer_[idiag].first->
 		evaluate(scale,widthOption(),offshell,
 			 outspin_[dit->channelType].first [h1],swave_);
 	      diag = -sign*fer_[idiag].second->
 		evaluate(scale,inters,outspin_[iferm].second[h2],outScalar);
 	    }
 	    else {
 	    SpinorBarWaveFunction inters = fer_[idiag].first->
 	      evaluate(scale,widthOption(),offshell,
 		       outspin_[dit->channelType].second[h1],swave_);
 	    diag =  sign*fer_[idiag].second->
 	      evaluate(scale,outspin_[iferm].first [h2],inters,outScalar);
 	    }
 	  }
 	  // intermediate vector
 	  else if(offshell->iSpin() == PDT::Spin1) {
 	    VectorWaveFunction interv = vec_[idiag].first->
 	      evaluate(scale, widthOption(), offshell, swave_, outScalar);
 	    unsigned int h1(s1),h2(s2);
 	    if(out2[dit->channelType]>out3[dit->channelType]) swap(h1,h2);
 	  if(decay[out2[dit->channelType]]->id()<0&&
 	     decay[out3[dit->channelType]]->id()>0) {
 	    diag =-sign*vec_[idiag].second->
 	      evaluate(scale,
 		       outspin_[out2[dit->channelType]].first [h1],
 		       outspin_[out3[dit->channelType]].second[h2],interv);
 	  }
 	  else {
 	    diag = sign*vec_[idiag].second->
 	      evaluate(scale,
 		       outspin_[out3[dit->channelType]].first [h2],
 		       outspin_[out2[dit->channelType]].second[h1],interv);
 	  }
 	  }
 	  // intermediate tensor
 	  else if(offshell->iSpin() == PDT::Spin2) {
 	    TensorWaveFunction intert = ten_[idiag].first->
 	      evaluate(scale, widthOption(), offshell, swave_, outScalar);
 	    unsigned int h1(s1),h2(s2);
 	    if(out2[dit->channelType]>out3[dit->channelType]) swap(h1,h2);
 	    if(decay[out2[dit->channelType]]->id()<0&&
 	       decay[out3[dit->channelType]]->id()>0) {
 	      diag =-sign*ten_[idiag].second->
 		evaluate(scale,
 			 outspin_[out2[dit->channelType]].first [h1],
 			 outspin_[out3[dit->channelType]].second[h2],intert);
 	    }
 	    else {
 	      diag = sign*ten_[idiag].second->
 		evaluate(scale,
 			 outspin_[out3[dit->channelType]].first [h2],
 			 outspin_[out2[dit->channelType]].second[h1],intert);
 	    }
 	  }
 	  // intermediate RS fermion
 	  else if(offshell->iSpin() == PDT::Spin3Half) {
 	    int iferm = 
 	      decay[out2[dit->channelType]]->dataPtr()->iSpin()==PDT::Spin1Half
 	      ? out2[dit->channelType] : out3[dit->channelType];
 	    unsigned int h1(s1),h2(s2);
 	    if(dit->channelType>iferm) swap(h1,h2);
 	    sign = iferm<dit->channelType ? 1. : -1.;
 	    if((decay[dit->channelType]->id() < 0 &&decay[iferm]->id() > 0 ) ||
 	       (decay[dit->channelType]->id()*offshell->id()>0)) {
 	      RSSpinorWaveFunction    inters = RSfer_[idiag].first->
 		evaluate(scale,widthOption(),offshell,
 			 outspin_[dit->channelType].first [h1],swave_);
 	      diag = -sign*RSfer_[idiag].second->
 		evaluate(scale,inters,outspin_[iferm].second[h2],outScalar);
 	    }
 	    else {
 	      RSSpinorBarWaveFunction inters = RSfer_[idiag].first->
 		evaluate(scale,widthOption(),offshell,
 			 outspin_[dit->channelType].second[h1],swave_);
 	      diag =  sign*RSfer_[idiag].second->
 		evaluate(scale,outspin_[iferm].first [h2],inters,outScalar);
 	    }
 	  }
 	  // unknown
 	  else throw Exception()
 		 << "Unknown intermediate in StoSFFDecayer::me2()" 
 		 << Exception::runerror;
 	}
 	// four point diagram
 	else {
 	    unsigned int o2 = isca > 0 ? 0 : 1;
 	    unsigned int o3 = isca < 2 ? 2 : 1;
 	    if(decay[o2]->id() < 0 && decay[o3]->id() > 0) {
 	      diag =-four_[idiag]->
 	    	evaluate(scale, outspin_[o2].first[s1],
 	    		 outspin_[o3].second[s2], outScalar, swave_);
 	    }
 	    else {
 	      diag = four_[idiag]->
 	    	evaluate(scale, outspin_[o3].first[s2],
 	    		 outspin_[o2].second[s1], outScalar, swave_);
 	    }
 	}
 	// matrix element for the different colour flows
 	if(ichan < 0) {
 	  for(unsigned iy = 0; iy < dit->colourFlow.size(); ++iy) {
 	    flows[dit->colourFlow[iy].first - 1] += 
 	      dit->colourFlow[iy].second * diag;
 	  }
 	  for(unsigned iy = 0; iy < dit->largeNcColourFlow.size(); ++iy) {
 	    largeflows[dit->largeNcColourFlow[iy].first - 1] += 
 	      dit->largeNcColourFlow[iy].second * diag;
 	  }
 	}
 	else {
 	  for(unsigned iy = 0; iy < dit->colourFlow.size(); ++iy) {
 	    if(dit->colourFlow[iy].first - 1 != colourFlow()) continue;
 	    flows[dit->colourFlow[iy].first - 1] += 
 	      dit->colourFlow[iy].second * diag;
 	  }
 	  for(unsigned iy = 0; iy < dit->largeNcColourFlow.size(); ++iy) {
 	    if(dit->colourFlow[iy].first - 1!=colourFlow()) continue;
 	    largeflows[dit->largeNcColourFlow[iy].first - 1] += 
 	      dit->largeNcColourFlow[iy].second * diag;
 	  }
 	}
 	++idiag;
       }
       for(unsigned int ix = 0; ix < ncf; ++ix) {
 	if(isca == 0) {
 	  (*mes[ix])(0, 0, s1, s2) = flows[ix];
 	  (*mel[ix])(0, 0, s1, s2) = largeflows[ix];
 	}
 	else if(isca == 1 ) { 
 	  (*mes[ix])(0, s1, 0, s2) = flows[ix];
 	  (*mel[ix])(0, s1, 0, s2) = largeflows[ix];
 	}
 	else if(isca == 2) { 
 	  (*mes[ix])(0, s1,s2, 0) = flows[ix];
 	  (*mel[ix])(0, s1,s2, 0) = largeflows[ix] ;
 	}
       }
     }
   }
   double me2(0.);
   if(ichan < 0) {
     vector<double> pflows(ncf,0.);
     for(unsigned int ix = 0; ix < ncf; ++ix) {
       for(unsigned int iy = 0; iy < ncf; ++ iy) {
 	double con = cfactors[ix][iy]*(mes[ix]->contract(*mes[iy],rho_)).real();
 	me2 += con;
 	if(ix == iy) {
 	  con = nfactors[ix][iy]*(mel[ix]->contract(*mel[iy],rho_)).real();
 	  pflows[ix] += con;
 	}
       }
     }
     double ptotal(std::accumulate(pflows.begin(),pflows.end(),0.));
     ptotal *= UseRandom::rnd();
     for(unsigned int ix = 0;ix < pflows.size(); ++ix) {
       if(ptotal <= pflows[ix]) {
 	colourFlow(ix);
 	ME(mes[ix]);
 	break;
       }
       ptotal -= pflows[ix];
     }
   }
   else {
     unsigned int iflow = colourFlow();
     me2 = nfactors[iflow][iflow]*(mel[iflow]->contract(*mel[iflow],rho_)).real();
   }
   // return the matrix element squared
   return me2;
 }
diff --git a/Decay/General/TFFDecayer.cc b/Decay/General/TFFDecayer.cc
--- a/Decay/General/TFFDecayer.cc
+++ b/Decay/General/TFFDecayer.cc
@@ -1,351 +1,353 @@
 // -*- C++ -*-
 //
 // TFFDecayer.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 TFFDecayer class.
 //
 
 #include "TFFDecayer.h"
 #include "ThePEG/Utilities/DescribeClass.h"
 #include "ThePEG/Interface/ClassDocumentation.h"
 #include "ThePEG/Persistency/PersistentOStream.h"
 #include "ThePEG/Persistency/PersistentIStream.h"
 #include "ThePEG/PDT/DecayMode.h"
 #include "ThePEG/Helicity/WaveFunction/TensorWaveFunction.h"
 #include "ThePEG/Helicity/WaveFunction/SpinorWaveFunction.h"
 #include "ThePEG/Helicity/WaveFunction/SpinorBarWaveFunction.h"
 #include "Herwig/Utilities/Kinematics.h"
 #include "Herwig/Decay/GeneralDecayMatrixElement.h"
 
 using namespace Herwig;
 using namespace ThePEG::Helicity;
 IBPtr TFFDecayer::clone() const {
   return new_ptr(*this);
 }
 
 IBPtr TFFDecayer::fullclone() const {
   return new_ptr(*this);
 }
 
 void TFFDecayer::setDecayInfo(PDPtr incoming, PDPair outgoing,
 			      vector<VertexBasePtr> vertex,
 			      map<ShowerInteraction,VertexBasePtr> &,
 			      const vector<map<ShowerInteraction,VertexBasePtr> > & outV,
 			      map<ShowerInteraction,VertexBasePtr> fourV) {
   decayInfo(incoming,outgoing);
   for(auto vert : vertex) {
     vertex_            .push_back(dynamic_ptr_cast<AbstractFFTVertexPtr>(vert));
     perturbativeVertex_.push_back(dynamic_ptr_cast<FFTVertexPtr>        (vert));
   }
   vector<ShowerInteraction> itemp={ShowerInteraction::QCD,ShowerInteraction::QED};
   for(auto & inter : itemp) {
     fourPointVertex_[inter] = dynamic_ptr_cast<AbstractFFVTVertexPtr>(fourV.at(inter));
     outgoingVertex1_[inter] = dynamic_ptr_cast<AbstractFFVVertexPtr> (outV[0].at(inter));
     outgoingVertex2_[inter] = dynamic_ptr_cast<AbstractFFVVertexPtr> (outV[1].at(inter));
   }
 }
 
 void TFFDecayer::persistentOutput(PersistentOStream & os) const {
   os << vertex_          << perturbativeVertex_
      << outgoingVertex1_ << outgoingVertex2_
      << fourPointVertex_;
 }
 
 void TFFDecayer::persistentInput(PersistentIStream & is, int) {
   is >> vertex_          >> perturbativeVertex_
      >> outgoingVertex1_ >> outgoingVertex2_
      >> fourPointVertex_;
 }
 
 // The following static variable is needed for the type
 // description system in ThePEG.
 DescribeClass<TFFDecayer,GeneralTwoBodyDecayer>
 describeHerwigTFFDecayer("Herwig::TFFDecayer", "Herwig.so");
 
 void TFFDecayer::Init() {
 
   static ClassDocumentation<TFFDecayer> documentation
     ("The TFFDecayer class implements the decay of a tensor particle "
      "to 2 fermions ");
   
 }
 
 double TFFDecayer::me2(const int , const Particle & inpart,
 		       const ParticleVector & decay,
 		       MEOption meopt) const {
   unsigned int iferm(0),ianti(1);
   if(!ME())
     ME(new_ptr(GeneralDecayMatrixElement(PDT::Spin2,PDT::Spin1Half,PDT::Spin1Half)));
   if(decay[0]->id()>=0) swap(iferm,ianti);
   if(meopt==Initialize) {
     TensorWaveFunction::
       calculateWaveFunctions(tensors_,rho_,const_ptr_cast<tPPtr>(&inpart),
 			     incoming,false);
+    // fix rho if no correlations
+    fixRho(rho_);
   }
   if(meopt==Terminate) {
     TensorWaveFunction::
       constructSpinInfo(tensors_,const_ptr_cast<tPPtr>(&inpart),
 			incoming,true,false);
     SpinorBarWaveFunction::
       constructSpinInfo(wavebar_,decay[iferm],outgoing,true);
     SpinorWaveFunction::
       constructSpinInfo(wave_   ,decay[ianti],outgoing,true);
     return 0.;
   }
   SpinorBarWaveFunction::
     calculateWaveFunctions(wavebar_,decay[iferm],outgoing);
   SpinorWaveFunction::
     calculateWaveFunctions(wave_   ,decay[ianti],outgoing);
   Energy2 scale(sqr(inpart.mass()));
   unsigned int thel,fhel,ahel;
   for(thel=0;thel<5;++thel) {
     for(fhel=0;fhel<2;++fhel) {
       for(ahel=0;ahel<2;++ahel) {
 	if(iferm > ianti) {
 	  (*ME())(thel,fhel,ahel) = 0.;
 	  for(auto vert : vertex_)
 	    (*ME())(thel,fhel,ahel) += 
 	      vert->evaluate(scale,wave_[ahel],
 			     wavebar_[fhel],tensors_[thel]);
 	}
 	else {
 	  (*ME())(thel,ahel,fhel) = 0.;
 	  for(auto vert : vertex_)
 	    (*ME())(thel,ahel,fhel) += 
 	      vert->evaluate(scale,wave_[ahel],
 			     wavebar_[fhel],tensors_[thel]);
 	}
       }
     }
   }
   double output = (ME()->contract(rho_)).real()/scale*UnitRemoval::E2;
   // colour and identical particle factors
   output *= colourFactor(inpart.dataPtr(),decay[0]->dataPtr(),
 			 decay[1]->dataPtr());
   // return the answer
   return output;
 }
 
 Energy TFFDecayer::partialWidth(PMPair inpart, PMPair outa, 
 				PMPair outb) const {
   if( inpart.second < outa.second + outb.second  ) return ZERO;
   if(perturbativeVertex_.size()==1 &&
      perturbativeVertex_[0]) {
     Energy2 scale = sqr(inpart.second);
     tcPDPtr in = inpart.first->CC() ? tcPDPtr(inpart.first->CC()) : inpart.first;
     perturbativeVertex_[0]->setCoupling(scale, in, outa.first, outb.first);
     double musq = sqr(outa.second/inpart.second);
     double b = sqrt(1- 4.*musq);
     double me2 = b*b*(5-2*b*b)*scale/120.*UnitRemoval::InvE2;
     Energy pcm = Kinematics::pstarTwoBodyDecay(inpart.second,outa.second,
 					outb.second);
     Energy output = norm(perturbativeVertex_[0]->norm())*me2*pcm/(8.*Constants::pi);
     // colour factor
     output *= colourFactor(inpart.first,outa.first,outb.first);
     // return the answer
     return output;
   }
   else {
     return GeneralTwoBodyDecayer::partialWidth(inpart,outa,outb);
   }
 }
 
 
 double TFFDecayer::threeBodyME(const int , const Particle & inpart,
 			       const ParticleVector & decay,
 			       ShowerInteraction inter, MEOption meopt) {
   // work out which is the fermion and antifermion
   int ianti(0), iferm(1), iglu(2);
   int itype[2];
   for(unsigned int ix=0;ix<2;++ix) {
     if(decay[ix]->dataPtr()->CC()) itype[ix] = decay[ix]->id()>0 ? 0:1;
     else                           itype[ix] = 2;
   }
   if(itype[0]==0 && itype[1]!=0) swap(iferm, ianti);
   if(itype[0]==2 && itype[1]==1) swap(iferm, ianti);
   if(itype[0]==0 && itype[1]==0 && decay[0]->dataPtr()->id()<decay[1]->dataPtr()->id()) 
     swap(iferm, ianti);
   if(itype[0]==1 && itype[1]==1 && decay[0]->dataPtr()->id()<decay[1]->dataPtr()->id()) 
     swap(iferm, ianti);
 
   if(meopt==Initialize) {
     // create tensor wavefunction for decaying particle
     TensorWaveFunction::
       calculateWaveFunctions(tensors3_, rho3_, const_ptr_cast<tPPtr>(&inpart), incoming, false);
   }
   // setup spin information when needed
   if(meopt==Terminate) {
     TensorWaveFunction::
       constructSpinInfo(tensors3_, const_ptr_cast<tPPtr>(&inpart),incoming,true, false);
     SpinorBarWaveFunction::
       constructSpinInfo(wavebar3_ ,decay[iferm],outgoing,true);
     SpinorWaveFunction::
       constructSpinInfo(wave3_    ,decay[ianti],outgoing,true);
     VectorWaveFunction::
       constructSpinInfo(gluon_    ,decay[iglu ],outgoing,true,false);
     return 0.;
   }
 
   // calculate colour factors and number of colour flows
   unsigned int nflow;
   vector<DVector> cfactors = getColourFactors(inpart, decay, nflow);
 
   vector<GeneralDecayMEPtr> ME(nflow,new_ptr(GeneralDecayMatrixElement(PDT::Spin2,     PDT::Spin1Half,
 								       PDT::Spin1Half, PDT::Spin1)));
   // create wavefunctions
   SpinorBarWaveFunction::
     calculateWaveFunctions(wavebar3_, decay[iferm],outgoing);
   SpinorWaveFunction::
     calculateWaveFunctions(wave3_   , decay[ianti],outgoing);
   VectorWaveFunction::
     calculateWaveFunctions(gluon_   , decay[iglu ],outgoing,true);
 
   // gauge invariance test
 #ifdef GAUGE_CHECK
   gluon_.clear();
   for(unsigned int ix=0;ix<3;++ix) {
     if(ix==1) gluon_.push_back(VectorWaveFunction());
     else {
       gluon_.push_back(VectorWaveFunction(decay[iglu ]->momentum(),
   				          decay[iglu ]->dataPtr(),10,
   					  outgoing));
     }
   }
 #endif
   
   if (! (outgoingVertex1_[inter] && outgoingVertex2_[inter]))
     throw Exception()
       << "Invalid vertices for QCD radiation in TFF decay in TFFDecayer::threeBodyME"
       << Exception::runerror;
 
   // identify fermion and/or anti-fermion vertex
   AbstractFFVVertexPtr outgoingVertexF = outgoingVertex1_[inter];
   AbstractFFVVertexPtr outgoingVertexA = outgoingVertex2_[inter];
 
   if(outgoingVertex1_[inter]!=outgoingVertex2_[inter] &&
      outgoingVertex1_[inter]->isIncoming(getParticleData(decay[ianti]->id())))
     swap (outgoingVertexF, outgoingVertexA);  
   
   if(! (inpart.dataPtr()->iColour()==PDT::Colour0)){
     throw Exception()
       << "Invalid vertices for QCD radiation in TFF decay in TFFDecayer::threeBodyME"
       << Exception::runerror;
   }
 
   Energy2 scale(sqr(inpart.mass()));
 
   const GeneralTwoBodyDecayer::CFlow & colourFlow
         = colourFlows(inpart, decay);
   double gs(0.);
   bool couplingSet(false);
 #ifdef GAUGE_CHECK
   double total=0.;
 #endif
   for(unsigned int it = 0; it < 5; ++it) {  
     for(unsigned int ifm = 0; ifm < 2; ++ifm) {
       for(unsigned int ia = 0; ia < 2; ++ia) {
 	for(unsigned int ig = 0; ig < 2; ++ig) {
 
 	  // radiation from outgoing fermion
 	  if((decay[iferm]->dataPtr()->coloured() && inter==ShowerInteraction::QCD) ||
 	     (decay[iferm]->dataPtr()->charged()  && inter==ShowerInteraction::QED) ) {
 	    assert(outgoingVertexF);
 	    // ensure you get correct outgoing particle from first vertex
 	    tcPDPtr off = decay[iferm]->dataPtr();
 	    if(off->CC()) off = off->CC();
 	    SpinorBarWaveFunction interS = 
 	      outgoingVertexF->evaluate(scale,3,off,wavebar3_[ifm],
 					gluon_[2*ig],decay[iferm]->mass());
 	  
 	    assert(wavebar3_[ifm].particle()->id()==interS.particle()->id());
 
 	    Complex diag = 0.;
 	    for(auto vertex : vertex_)
 	      diag += vertex->evaluate(scale,wave3_[ia], interS,tensors3_[it]);
 	    if(!couplingSet) {
 	      gs = abs(outgoingVertexF->norm());
 	      couplingSet = true;
 	    }
 	    for(unsigned int ix=0;ix<colourFlow[1].size();++ix) {
 	      (*ME[colourFlow[1][ix].first])(it, ifm, ia, ig) += 
 		colourFlow[1][ix].second*diag;
 	    }
 #ifdef GAUGE_CHECK
 	    total+=norm(diag);
 #endif
 	  }
 
 	  // radiation from outgoing antifermion
 	  if((decay[ianti]->dataPtr()->coloured() && inter==ShowerInteraction::QCD) ||
 	     (decay[ianti]->dataPtr()->charged()  && inter==ShowerInteraction::QED) ) {
 	    assert(outgoingVertexA);
 	    // ensure you get correct outgoing particle from first vertex
 	    tcPDPtr off = decay[ianti]->dataPtr();
 	    if(off->CC()) off = off->CC();
 	    SpinorWaveFunction  interS = 
 	      outgoingVertexA->evaluate(scale,3,off,wave3_[ia],
 					gluon_[2*ig],decay[ianti]->mass());
 	    
 	    assert(wave3_[ia].particle()->id()==interS.particle()->id());
 
 	    Complex diag = 0.;
 	    for(auto vertex : vertex_)
 	      diag += vertex->evaluate(scale,interS,wavebar3_[ifm],tensors3_[it]);
 	    if(!couplingSet) {
 	      gs = abs(outgoingVertexA->norm());
 	      couplingSet = true;
 	    }
 	    for(unsigned int ix=0;ix<colourFlow[2].size();++ix) {
 	      (*ME[colourFlow[2][ix].first])(it, ifm, ia, ig) += 
 		colourFlow[2][ix].second*diag;
 	    }
 #ifdef GAUGE_CHECK
 	    total+=norm(diag);
 #endif
 	  }
 
 	  // radiation from 4 point vertex
 	  if (fourPointVertex_[inter]) {
 	    Complex diag = fourPointVertex_[inter]->evaluate(scale, wave3_[ia], wavebar3_[ifm],
 							     gluon_[2*ig], tensors3_[it]);
 	    for(unsigned int ix=0;ix<colourFlow[3].size();++ix) {
 	      (*ME[colourFlow[3][ix].first])(it, ifm, ia, ig) += 
 		colourFlow[3][ix].second*diag;
 	    }
 #ifdef GAUGE_CHECK
 	    total+=norm(diag);
 #endif
 	  }
 	}
       }
     }
   }
 
   // contract matrices 
   double output=0.;
   for(unsigned int ix=0; ix<nflow; ++ix){
     for(unsigned int iy=0; iy<nflow; ++iy){
       output+=cfactors[ix][iy]*(ME[ix]->contract(*ME[iy],rho3_)).real();
     }
   }
   // divide by alpha_(s,em)
   output *= (4.*Constants::pi)/sqr(gs);
 #ifdef GAUGE_CHECK
   double ratio = output/total;
   if(abs(ratio)>1e-20) {
     generator()->log() << "Test of gauge invariance in decay\n" << inpart << "\n";
     for(unsigned int ix=0;ix<decay.size();++ix)
       generator()->log() << *decay[ix] << "\n";
     generator()->log() << "Test of gauge invariance " << ratio << "\n";
   }
 #endif
   // return the answer
   return output;
 }
 
diff --git a/Decay/General/TSSDecayer.cc b/Decay/General/TSSDecayer.cc
--- a/Decay/General/TSSDecayer.cc
+++ b/Decay/General/TSSDecayer.cc
@@ -1,130 +1,132 @@
 // -*- C++ -*-
 //
 // TSSDecayer.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 TSSDecayer class.
 //
 
 #include "TSSDecayer.h"
 #include "ThePEG/Utilities/DescribeClass.h"
 #include "ThePEG/Interface/ClassDocumentation.h"
 #include "ThePEG/Persistency/PersistentOStream.h"
 #include "ThePEG/Persistency/PersistentIStream.h"
 #include "Herwig/Utilities/Kinematics.h"
 #include "ThePEG/PDT/DecayMode.h"
 #include "ThePEG/Helicity/WaveFunction/ScalarWaveFunction.h"
 #include "ThePEG/Helicity/WaveFunction/TensorWaveFunction.h"
 #include "Herwig/Decay/GeneralDecayMatrixElement.h"
 
 using namespace Herwig;
 using namespace ThePEG::Helicity;
 
 IBPtr TSSDecayer::clone() const {
   return new_ptr(*this);
 }
 
 IBPtr TSSDecayer::fullclone() const {
   return new_ptr(*this);
 }
 
 
 void TSSDecayer::setDecayInfo(PDPtr incoming, PDPair outgoing,
 			      vector<VertexBasePtr> vertex,
 			      map<ShowerInteraction,VertexBasePtr> & ,
 			      const vector<map<ShowerInteraction,VertexBasePtr> > & ,
 			      map<ShowerInteraction,VertexBasePtr> ) {
   decayInfo(incoming,outgoing);
   for(auto vert : vertex) {
     vertex_            .push_back(dynamic_ptr_cast<AbstractSSTVertexPtr>(vert));
     perturbativeVertex_.push_back(dynamic_ptr_cast<SSTVertexPtr>        (vert));
   }
 }
 
 
 void TSSDecayer::persistentOutput(PersistentOStream & os) const {
   os << vertex_ << perturbativeVertex_;
 }
 
 void TSSDecayer::persistentInput(PersistentIStream & is, int) {
   is >> vertex_ >> perturbativeVertex_;
 }
 
 // The following static variable is needed for the type
 // description system in ThePEG.
 DescribeClass<TSSDecayer,GeneralTwoBodyDecayer>
 describeHerwigTSSDecayer("Herwig::TSSDecayer", "Herwig.so");
 
 void TSSDecayer::Init() {
 
   static ClassDocumentation<TSSDecayer> documentation
     ("This class implements the decay of a tensor particle into "
      "2 scalars.");
 
 }
 
 double TSSDecayer::me2(const int , const Particle & inpart,
 		       const ParticleVector & decay,
 		       MEOption meopt) const {
   if(!ME())
     ME(new_ptr(GeneralDecayMatrixElement(PDT::Spin2,PDT::Spin0,PDT::Spin0)));
   if(meopt==Initialize) {
     TensorWaveFunction::
       calculateWaveFunctions(tensors_,rho_,const_ptr_cast<tPPtr>(&inpart),
 			     incoming,false);
+    // fix rho if no correlations
+    fixRho(rho_);
   }
   if(meopt==Terminate) {
     TensorWaveFunction::
       constructSpinInfo(tensors_,const_ptr_cast<tPPtr>(&inpart),
 			incoming,true,false);
     for(unsigned int ix=0;ix<2;++ix)
       ScalarWaveFunction::
 	constructSpinInfo(decay[ix],outgoing,true);
     return 0.;
   }
   ScalarWaveFunction sca1(decay[0]->momentum(),decay[0]->dataPtr(),outgoing);
   ScalarWaveFunction sca2(decay[1]->momentum(),decay[1]->dataPtr(),outgoing);
   Energy2 scale(sqr(inpart.mass()));
   for(unsigned int thel=0;thel<5;++thel) {
     (*ME())(thel,0,0) =0.;
     for(auto vert : vertex_)
       (*ME())(thel,0,0) += vert->evaluate(scale,sca1,sca2,tensors_[thel]); 
   }
   double output = (ME()->contract(rho_)).real()/scale*UnitRemoval::E2;
   // colour and identical particle factors
   output *= colourFactor(inpart.dataPtr(),decay[0]->dataPtr(),
 			 decay[1]->dataPtr());
   // return the answer
   return output;
 }
 
 
 Energy TSSDecayer::partialWidth(PMPair inpart, PMPair outa, 
 				PMPair outb) const {
   if( inpart.second < outa.second + outb.second  ) return ZERO;
   if(perturbativeVertex_.size()==1 &&
      perturbativeVertex_[0]) {
     Energy2 scale(sqr(inpart.second));
     tcPDPtr in = inpart.first->CC() ? tcPDPtr(inpart.first->CC()) : inpart.first;
     perturbativeVertex_[0]->setCoupling(scale, outa.first, outb.first, in);
     double musq = sqr(outa.second/inpart.second);
     double b = sqrt(1. - 4.*musq);
     double me2 = scale*pow(b,4)/120*UnitRemoval::InvE2;
     Energy pcm = Kinematics::pstarTwoBodyDecay(inpart.second,outa.second,
 					outb.second);
     Energy output = norm(perturbativeVertex_[0]->norm())*me2*pcm/(8.*Constants::pi);
     // colour factor
     output *= colourFactor(inpart.first,outa.first,outb.first);
     // return the answer
     return output;
   }
   else {
     return GeneralTwoBodyDecayer::partialWidth(inpart,outa,outb);
   }
 }
 
diff --git a/Decay/General/TVVDecayer.cc b/Decay/General/TVVDecayer.cc
--- a/Decay/General/TVVDecayer.cc
+++ b/Decay/General/TVVDecayer.cc
@@ -1,338 +1,340 @@
 // -*- C++ -*-
 //
 // TVVDecayer.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 TVVDecayer class.
 //
 
 #include "TVVDecayer.h"
 #include "ThePEG/Utilities/DescribeClass.h"
 #include "ThePEG/Interface/ClassDocumentation.h"
 #include "ThePEG/Persistency/PersistentOStream.h"
 #include "ThePEG/Persistency/PersistentIStream.h"
 #include "ThePEG/PDT/DecayMode.h"
 #include "ThePEG/Helicity/WaveFunction/VectorWaveFunction.h"
 #include "ThePEG/Helicity/WaveFunction/TensorWaveFunction.h"
 #include "Herwig/Utilities/Kinematics.h"
 #include "ThePEG/Helicity/LorentzTensor.h"
 #include "Herwig/Decay/GeneralDecayMatrixElement.h"
 using namespace Herwig;
 using namespace ThePEG::Helicity;
 
 IBPtr TVVDecayer::clone() const {
   return new_ptr(*this);
 }
 
 IBPtr TVVDecayer::fullclone() const {
   return new_ptr(*this);
 }
 
 void TVVDecayer::setDecayInfo(PDPtr incoming, PDPair outgoing,
 			      vector<VertexBasePtr> vertex,
 			      map<ShowerInteraction,VertexBasePtr> &,
 			      const vector<map<ShowerInteraction,VertexBasePtr> > & outV,
 			      map<ShowerInteraction,VertexBasePtr> fourV) {
   decayInfo(incoming,outgoing);
   for(auto vert : vertex) {
     vertex_            .push_back(dynamic_ptr_cast<AbstractVVTVertexPtr>(vert));
     perturbativeVertex_.push_back(dynamic_ptr_cast<VVTVertexPtr>        (vert));
   }
   vector<ShowerInteraction> itemp={ShowerInteraction::QCD,ShowerInteraction::QED};
   for(auto & inter : itemp) {
     fourPointVertex_[inter] = dynamic_ptr_cast<AbstractVVVTVertexPtr>(fourV.at(inter));
     outgoingVertex1_[inter] = dynamic_ptr_cast<AbstractVVVVertexPtr> (outV[0].at(inter));
     outgoingVertex2_[inter] = dynamic_ptr_cast<AbstractVVVVertexPtr> (outV[1].at(inter));
   }
 }
 
 void TVVDecayer::persistentOutput(PersistentOStream & os) const {
   os << vertex_          << perturbativeVertex_
      << outgoingVertex1_ << outgoingVertex2_
      << fourPointVertex_;
 }
 
 void TVVDecayer::persistentInput(PersistentIStream & is, int) {
   is >> vertex_          >> perturbativeVertex_
      >> outgoingVertex1_ >> outgoingVertex2_
      >> fourPointVertex_;
 }
 
 // The following static variable is needed for the type
 // description system in ThePEG.
 DescribeClass<TVVDecayer,GeneralTwoBodyDecayer>
 describeHerwigTVVDecayer("Herwig::TVVDecayer", "Herwig.so");
 
 void TVVDecayer::Init() {
 
   static ClassDocumentation<TVVDecayer> documentation
     ("This class implements the decay of a tensor to 2 vector bosons");
 
 }
 
 double TVVDecayer::me2(const int , const Particle & inpart,
 		       const ParticleVector & decay,
 		       MEOption meopt) const {
   if(!ME())
     ME(new_ptr(GeneralDecayMatrixElement(PDT::Spin2,PDT::Spin1,PDT::Spin1)));
   bool photon[2];
   for(unsigned int ix=0;ix<2;++ix)
     photon[ix] = decay[ix]->mass()==ZERO;
   if(meopt==Initialize) {
     TensorWaveFunction::
       calculateWaveFunctions(tensors_,rho_,const_ptr_cast<tPPtr>(&inpart),
 			     incoming,false);
+    // fix rho if no correlations
+    fixRho(rho_);
   }
   if(meopt==Terminate) {
     TensorWaveFunction::
       constructSpinInfo(tensors_,const_ptr_cast<tPPtr>(&inpart),
 			incoming,true,false);
     for(unsigned int ix=0;ix<2;++ix)
       VectorWaveFunction::
 	constructSpinInfo(vectors_[ix],decay[ix],outgoing,true,photon[ix]);
     return 0.;
   }
   for(unsigned int ix=0;ix<2;++ix)
     VectorWaveFunction::
       calculateWaveFunctions(vectors_[ix],decay[ix],outgoing,photon[ix]);
   Energy2 scale(sqr(inpart.mass()));
   unsigned int thel,v1hel,v2hel;
   for(thel=0;thel<5;++thel) {
     for(v1hel=0;v1hel<3;++v1hel) {
       for(v2hel=0;v2hel<3;++v2hel) {
 	(*ME())(thel,v1hel,v2hel) = 0.;
 	  for(auto vert : vertex_)
 	    (*ME())(thel,v1hel,v2hel) += vert->evaluate(scale,
 							vectors_[0][v1hel],
 							vectors_[1][v2hel],
 							tensors_[thel]);
 	if(photon[1]) ++v2hel;
       }
       if(photon[0]) ++v1hel;
     }
   }
   double output = (ME()->contract(rho_)).real()/scale*UnitRemoval::E2;
   // colour and identical particle factors
   output *= colourFactor(inpart.dataPtr(),decay[0]->dataPtr(),
 			 decay[1]->dataPtr());
   // return the answer
   return output;
 }
   
 Energy TVVDecayer::partialWidth(PMPair inpart, PMPair outa, 
 				PMPair outb) const {
   if( inpart.second < outa.second + outb.second  ) return ZERO;
   if(perturbativeVertex_.size()==1 &&
      perturbativeVertex_[0]) {
     Energy2 scale(sqr(inpart.second));
     tcPDPtr in = inpart.first->CC() ? tcPDPtr(inpart.first->CC()) : inpart.first;
     perturbativeVertex_[0]->setCoupling(scale, outa.first, outb.first, in);
     double mu2 = sqr(outa.second/inpart.second);
     double b = sqrt(1 - 4.*mu2);
     Energy pcm = Kinematics::pstarTwoBodyDecay(inpart.second,outa.second,
 					outb.second);
     Energy2 me2;
     if(outa.second > ZERO && outb.second > ZERO)
       me2 = scale*(30 - 20.*b*b + 3.*pow(b,4))/120.; 
     else 
       me2 = scale/10.;
     
     Energy output = norm(perturbativeVertex_[0]->norm())*me2*pcm
       /(8.*Constants::pi)*UnitRemoval::InvE2;
     // colour factor
     output *= colourFactor(inpart.first,outa.first,outb.first);
     // return the answer
     return output;
   }
   else {
     return GeneralTwoBodyDecayer::partialWidth(inpart,outa,outb);
   }
 }
 
 double TVVDecayer::threeBodyME(const int , const Particle & inpart,
 			       const ParticleVector & decay,
 			       ShowerInteraction inter, MEOption meopt) {
   bool massless[2];
   for(unsigned int ix=0;ix<2;++ix)
     massless[ix] = decay[ix]->mass()==ZERO;
   int iglu(2);  
   if(meopt==Initialize) {
     // create tensor wavefunction for decaying particle
     TensorWaveFunction::
       calculateWaveFunctions(tensors3_, rho3_, const_ptr_cast<tPPtr>(&inpart), incoming, false);
   }
   // setup spin information when needed
   if(meopt==Terminate) {
     TensorWaveFunction::
       constructSpinInfo(tensors3_, const_ptr_cast<tPPtr>(&inpart),incoming,true, false);
     for(unsigned int ix=0;ix<2;++ix)
       VectorWaveFunction::
 	constructSpinInfo(vectors3_[ix],decay[ix   ],outgoing,true, massless[ix]);
     VectorWaveFunction::
         constructSpinInfo(gluon_       ,decay[iglu ],outgoing,true,false);
     return 0.;
   }
 
   // calculate colour factors and number of colour flows
   unsigned int nflow;
   vector<DVector> cfactors = getColourFactors(inpart, decay, nflow);
 
   vector<GeneralDecayMEPtr> ME(nflow,new_ptr(GeneralDecayMatrixElement(PDT::Spin2, PDT::Spin1,
 								       PDT::Spin1, PDT::Spin1)));
   // create wavefunctions
   for(unsigned int ix=0;ix<2;++ix)
     VectorWaveFunction::
       calculateWaveFunctions(vectors3_[ix],decay[ix   ],outgoing,massless[ix]);
   VectorWaveFunction::
       calculateWaveFunctions(gluon_       ,decay[iglu ],outgoing,true);
 
   // gauge test
 #ifdef GAUGE_CHECK
   gluon_.clear();
   for(unsigned int ix=0;ix<3;++ix) {
     if(ix==1) gluon_.push_back(VectorWaveFunction());
     else {
       gluon_.push_back(VectorWaveFunction(decay[iglu ]->momentum(),
   				          decay[iglu ]->dataPtr(),10,
   					  outgoing));
     }
   }
 #endif
   
   // work out which vector each outgoing vertex corresponds to 
   if(outgoingVertex1_[inter]!=outgoingVertex2_[inter] &&
      outgoingVertex1_[inter]->isIncoming(getParticleData(decay[1]->id())))
     swap(outgoingVertex1_[inter], outgoingVertex2_[inter]);
   
   if (! (outgoingVertex1_[inter] && outgoingVertex2_[inter]))
     throw Exception()
       << "Invalid vertices for radiation in TVV decay in TVVDecayer::threeBodyME"
       << Exception::runerror;
 
   if( !(!inpart.dataPtr()->coloured() && inter ==ShowerInteraction::QCD) &&
       !(!inpart.dataPtr()->charged()  && inter ==ShowerInteraction::QED))
     throw Exception()
       << "Invalid vertices for radiation in TVV decay in TVVDecayer::threeBodyME"
       << Exception::runerror;
 
 
   Energy2 scale(sqr(inpart.mass()));
 
   const GeneralTwoBodyDecayer::CFlow & colourFlow
         = colourFlows(inpart, decay);
   double gs(0.);
   bool couplingSet(false);
 #ifdef GAUGE_CHECK
   double total=0.;
 #endif
   for(unsigned int it = 0; it < 5; ++it) {  
     for(unsigned int iv0 = 0; iv0 < 3; ++iv0) {
       for(unsigned int iv1 = 0; iv1 < 3; ++iv1) {
 	for(unsigned int ig = 0; ig < 2; ++ig) {
 
 	  // radiation from first outgoing vector
 	  if((decay[0]->dataPtr()->coloured() && inter==ShowerInteraction::QCD) ||
 	     (decay[0]->dataPtr()->charged()  && inter==ShowerInteraction::QED) ) {
 	    assert(outgoingVertex1_[inter]);
 	    // ensure you get correct outgoing particle from first vertex
 	    tcPDPtr off = decay[0]->dataPtr();
 	    if(off->CC()) off = off->CC();
 	    VectorWaveFunction vectInter = 
 	      outgoingVertex1_[inter]->evaluate(scale,3,off,gluon_[2*ig],
 						 vectors3_[0][iv0],decay[0]->mass());
 	  
 	    assert(vectors3_[0][iv0].particle()->PDGName()==vectInter.particle()->PDGName());
 
 	    Complex diag = 0.;
 	    for(auto vertex : vertex_)
 	      diag += vertex->evaluate(scale,vectors3_[1][iv1], 
 				       vectInter,tensors3_[it]);
 	    if(!couplingSet) {
 	      gs = abs(outgoingVertex1_[inter]->norm());
 	      couplingSet = true;
 	    }
 	    for(unsigned int ix=0;ix<colourFlow[1].size();++ix) {
 	      (*ME[colourFlow[1][ix].first])(it, iv0, iv1, ig) += 
 		colourFlow[1][ix].second*diag;
 	    }
 #ifdef GAUGE_CHECK
 	    total+=norm(diag);
 #endif
 	  }
 
 	  // radiation from second outgoing vector
 	  if((decay[1]->dataPtr()->coloured() && inter==ShowerInteraction::QCD) ||
 	     (decay[1]->dataPtr()->charged()  && inter==ShowerInteraction::QED) ) {
 	    assert(outgoingVertex2_[inter]);
 	    // ensure you get correct outgoing particle from first vertex
 	    tcPDPtr off = decay[1]->dataPtr();
 	    if(off->CC()) off = off->CC();
 	    VectorWaveFunction  vectInter = 
 	      outgoingVertex2_[inter]->evaluate(scale,3,off,vectors3_[1][iv1],
 						gluon_[2*ig],decay[1]->mass());
 	    
 	    assert(vectors3_[1][iv1].particle()->PDGName()==vectInter.particle()->PDGName());
 	    
 	    Complex diag = 0.;
 	    for(auto vertex : vertex_)
 	      diag += vertex->evaluate(scale,vectInter,vectors3_[0][iv0],
 					tensors3_[it]);
 	    if(!couplingSet) {
 	      gs = abs(outgoingVertex2_[inter]->norm());
 	      couplingSet = true;
 	    }
 	    for(unsigned int ix=0;ix<colourFlow[2].size();++ix) {
 	      (*ME[colourFlow[2][ix].first])(it, iv0, iv1, ig) += 
 		colourFlow[2][ix].second*diag;
 	    }
 #ifdef GAUGE_CHECK
 	    total+=norm(diag);
 #endif
 	  }
 
 	  // radiation from 4 point vertex
 	  if (fourPointVertex_[inter]) {
 	    Complex diag = fourPointVertex_[inter]->evaluate(scale, vectors3_[0][iv0],
 							     vectors3_[1][iv1],gluon_[2*ig], 
 							     tensors3_[it]);
 	    for(unsigned int ix=0;ix<colourFlow[3].size();++ix) {
 	      (*ME[colourFlow[3][ix].first])(it, iv0, iv1, ig) += 
 		colourFlow[3][ix].second*diag;
 	    }
 #ifdef GAUGE_CHECK
 	    total+=norm(diag);
 #endif
 	  }
 	}
 	if(massless[1]) ++iv1;
       }
       if(massless[0]) ++iv0;
     }
   }
 
   // contract matrices 
   double output=0.;
   for(unsigned int ix=0; ix<nflow; ++ix){
     for(unsigned int iy=0; iy<nflow; ++iy){
       output+=cfactors[ix][iy]*(ME[ix]->contract(*ME[iy],rho3_)).real();
     }
   }
   // divide by alpha_(s,em)
   output *= (4.*Constants::pi)/sqr(gs);
 #ifdef GAUGE_CHECK
   double ratio = output/total;
   if(abs(ratio)>1e-20) {
     generator()->log() << "Test of gauge invariance in decay\n" << inpart << "\n";
     for(unsigned int ix=0;ix<decay.size();++ix)
       generator()->log() << *decay[ix] << "\n";
     generator()->log() << "Test of gauge invariance " << ratio << "\n";
   }
 #endif
   // return the answer
   return output;
 }
diff --git a/Decay/General/VFFDecayer.cc b/Decay/General/VFFDecayer.cc
--- a/Decay/General/VFFDecayer.cc
+++ b/Decay/General/VFFDecayer.cc
@@ -1,470 +1,472 @@
 // -*- C++ -*-
 //
 // VFFDecayer.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 VFFDecayer class.
 //
 
 #include "VFFDecayer.h"
 #include "ThePEG/Utilities/DescribeClass.h"
 #include "ThePEG/Interface/ClassDocumentation.h"
 #include "ThePEG/Persistency/PersistentOStream.h"
 #include "ThePEG/Persistency/PersistentIStream.h"
 #include "ThePEG/PDT/DecayMode.h"
 #include "ThePEG/Helicity/WaveFunction/VectorWaveFunction.h"
 #include "ThePEG/Helicity/WaveFunction/SpinorWaveFunction.h"
 #include "ThePEG/Helicity/WaveFunction/SpinorBarWaveFunction.h"
 #include "Herwig/Utilities/Kinematics.h"
 #include "ThePEG/Helicity/Vertex/Vector/FFVVertex.h"
 #include "Herwig/Decay/GeneralDecayMatrixElement.h"
 using namespace Herwig;
 using namespace ThePEG::Helicity;
 IBPtr VFFDecayer::clone() const {
   return new_ptr(*this);
 }
 
 IBPtr VFFDecayer::fullclone() const {
   return new_ptr(*this);
 }
 
 void VFFDecayer::setDecayInfo(PDPtr incoming, PDPair outgoing,
 			      vector<VertexBasePtr> vertex,
 			      map<ShowerInteraction,VertexBasePtr> & inV,
 			      const vector<map<ShowerInteraction,VertexBasePtr> > & outV,
 			      map<ShowerInteraction,VertexBasePtr> ) {
   decayInfo(incoming,outgoing);
   for(auto vert : vertex) {
     vertex_            .push_back(dynamic_ptr_cast<AbstractFFVVertexPtr>(vert));
     perturbativeVertex_.push_back(dynamic_ptr_cast<FFVVertexPtr>        (vert));
   }
   vector<ShowerInteraction> itemp={ShowerInteraction::QCD,ShowerInteraction::QED};
   for(auto & inter : itemp) {
     incomingVertex_[inter] = dynamic_ptr_cast<AbstractVVVVertexPtr>(inV.at(inter));
     outgoingVertex1_[inter] = dynamic_ptr_cast<AbstractFFVVertexPtr>(outV[0].at(inter));
     outgoingVertex2_[inter] = dynamic_ptr_cast<AbstractFFVVertexPtr>(outV[1].at(inter));
   }
 }
 
 void VFFDecayer::persistentOutput(PersistentOStream & os) const {
   os << vertex_           << perturbativeVertex_
      << incomingVertex_   << outgoingVertex1_
      << outgoingVertex2_;
 }
 
 void VFFDecayer::persistentInput(PersistentIStream & is, int) {
   is >> vertex_           >> perturbativeVertex_
      >> incomingVertex_   >> outgoingVertex1_
      >> outgoingVertex2_;
 }
 
 // The following static variable is needed for the type
 // description system in ThePEG.
 DescribeClass<VFFDecayer,GeneralTwoBodyDecayer>
 describeHerwigVFFDecayer("Herwig::VFFDecayer", "Herwig.so");
 
 void VFFDecayer::Init() {
 
   static ClassDocumentation<VFFDecayer> documentation
     ("The VFFDecayer implements the matrix element for the"
      " decay of a vector to fermion-antifermion pair");
 
 }
 
 double VFFDecayer::me2(const int , const Particle & inpart,
 		       const ParticleVector & decay, 
 		       MEOption meopt) const {
   int iferm(1),ianti(0);
   if(decay[0]->id()>0) swap(iferm,ianti);
   if(!ME())
     ME(new_ptr(GeneralDecayMatrixElement(PDT::Spin1,PDT::Spin1Half,PDT::Spin1Half)));
   if(meopt==Initialize) {
     VectorWaveFunction::calculateWaveFunctions(vectors_,rho_,
 					       const_ptr_cast<tPPtr>(&inpart),
 					       incoming,false);
+    // fix rho if no correlations
+    fixRho(rho_);
   }
   if(meopt==Terminate) {
     VectorWaveFunction::constructSpinInfo(vectors_,const_ptr_cast<tPPtr>(&inpart),
 					  incoming,true,false);
     SpinorBarWaveFunction::
       constructSpinInfo(wavebar_,decay[iferm],outgoing,true);
     SpinorWaveFunction::
       constructSpinInfo(wave_   ,decay[ianti],outgoing,true);
     return 0.;
   }
   SpinorBarWaveFunction::
     calculateWaveFunctions(wavebar_,decay[iferm],outgoing);
   SpinorWaveFunction::
     calculateWaveFunctions(wave_   ,decay[ianti],outgoing);
   // compute the matrix element
   Energy2 scale(inpart.mass()*inpart.mass());
   for(unsigned int ifm = 0; ifm < 2; ++ifm) { //loop over fermion helicities
     for(unsigned int ia = 0; ia < 2; ++ia) {// loop over antifermion helicities
       for(unsigned int vhel = 0; vhel < 3; ++vhel) {//loop over vector helicities
 	if(iferm > ianti) {
 	  (*ME())(vhel, ia, ifm) = 0.;
 	  for(auto vert : vertex_)
 	    (*ME())(vhel, ia, ifm) += 
 	      vert->evaluate(scale,wave_[ia],
 			     wavebar_[ifm],vectors_[vhel]);
 	}
 	else {
 	  (*ME())(vhel,ifm,ia)= 0.;
 	  for(auto vert : vertex_)
 	    (*ME())(vhel,ifm,ia) +=
 	      vert->evaluate(scale,wave_[ia],
 			     wavebar_[ifm],vectors_[vhel]);
 	}
       }
     }
   }
   double output=(ME()->contract(rho_)).real()/scale*UnitRemoval::E2;
   // colour and identical particle factors
   output *= colourFactor(inpart.dataPtr(),decay[0]->dataPtr(),
 			 decay[1]->dataPtr());
   // return the answer
   return output;
 }
 
 Energy VFFDecayer::partialWidth(PMPair inpart, PMPair outa, 
 				PMPair outb) const {
   if( inpart.second < outa.second + outb.second  ) return ZERO;
   if(perturbativeVertex_.size()==1 &&
      perturbativeVertex_[0]) {
     double mu1(outa.second/inpart.second), mu2(outb.second/inpart.second);
     tcPDPtr in = inpart.first->CC() ? tcPDPtr(inpart.first->CC()) : inpart.first;
     perturbativeVertex_[0]->setCoupling(sqr(inpart.second), outa.first, outb.first,in);
     Complex cl(perturbativeVertex_[0]->left()), cr(perturbativeVertex_[0]->right());
     double me2 = (norm(cl) + norm(cr))*( sqr(sqr(mu1) - sqr(mu2)) 
 					 + sqr(mu1) + sqr(mu2) - 2.)
       - 6.*(cl*conj(cr) + cr*conj(cl)).real()*mu1*mu2;
     Energy pcm = Kinematics::pstarTwoBodyDecay(inpart.second,outa.second,
 					outb.second);
     Energy output = -norm(perturbativeVertex_[0]->norm())*me2*pcm / 
       (24.*Constants::pi);
     // colour factor
     output *= colourFactor(inpart.first,outa.first,outb.first);
     // return the answer
     return output;
   }
   else {
     return GeneralTwoBodyDecayer::partialWidth(inpart,outa,outb);
   }
 }
 
 
 double VFFDecayer::threeBodyME(const int , const Particle & inpart,
 			       const ParticleVector & decay,
 			       ShowerInteraction inter, MEOption meopt) {
   // work out which is the fermion and antifermion
   int ianti(0), iferm(1), iglu(2);
   int itype[2];
   for(unsigned int ix=0;ix<2;++ix) {
     if(decay[ix]->dataPtr()->CC()) itype[ix] = decay[ix]->id()>0 ? 0:1;
     else                           itype[ix] = 2;
   }
   if(itype[0]==0 && itype[1]!=0) swap(iferm, ianti);
   if(itype[0]==2 && itype[1]==1) swap(iferm, ianti);
   if(itype[0]==0 && itype[1]==0 && decay[0]->dataPtr()->id()<decay[1]->dataPtr()->id()) 
     swap(iferm, ianti);
   if(itype[0]==1 && itype[1]==1 && decay[0]->dataPtr()->id()<decay[1]->dataPtr()->id()) 
     swap(iferm, ianti);
 
   if(meopt==Initialize) {
     // create vector wavefunction for decaying particle
     VectorWaveFunction::calculateWaveFunctions(vector3_, rho3_, const_ptr_cast<tPPtr>(&inpart), 
 					       incoming, false);
   }
   // setup spin information when needed
   if(meopt==Terminate) {
     VectorWaveFunction::
       constructSpinInfo(vector3_ ,const_ptr_cast<tPPtr>(&inpart),outgoing,true,false);
     SpinorBarWaveFunction::
       constructSpinInfo(wavebar3_,decay[iferm],outgoing,true);
     SpinorWaveFunction::
       constructSpinInfo(wave3_   ,decay[ianti],outgoing,true);
     VectorWaveFunction::
       constructSpinInfo(gluon_   ,decay[iglu ],outgoing,true,false);
     return 0.;
   }
 
   // calculate colour factors and number of colour flows
   unsigned int nflow;
   vector<DVector> cfactors = getColourFactors(inpart, decay, nflow);
 
   vector<GeneralDecayMEPtr> ME(nflow,new_ptr(GeneralDecayMatrixElement(PDT::Spin1,     PDT::Spin1Half,
 								       PDT::Spin1Half, PDT::Spin1)));
   // create wavefunctions
   SpinorBarWaveFunction::
     calculateWaveFunctions(wavebar3_, decay[iferm],outgoing);
   SpinorWaveFunction::
     calculateWaveFunctions(wave3_   , decay[ianti],outgoing);
   VectorWaveFunction::
     calculateWaveFunctions(gluon_   , decay[iglu ],outgoing,true);
 
   // gauge invariance test
 #ifdef GAUGE_CHECK
   gluon_.clear();
   for(unsigned int ix=0;ix<3;++ix) {
     if(ix==1) gluon_.push_back(VectorWaveFunction());
     else {
       gluon_.push_back(VectorWaveFunction(decay[iglu ]->momentum(),
   				          decay[iglu ]->dataPtr(),10,
   					  outgoing));
     }
   }
 #endif
 
   // identify fermion and/or anti-fermion vertex
   AbstractFFVVertexPtr outgoingVertexF;
   AbstractFFVVertexPtr outgoingVertexA;
   identifyVertices(iferm, ianti, inpart, decay, outgoingVertexF, outgoingVertexA,inter);
 
   Energy2 scale(sqr(inpart.mass()));
 
   const GeneralTwoBodyDecayer::CFlow & colourFlow
         = colourFlows(inpart, decay);
   double gs(0.);
   bool couplingSet(false);
 #ifdef GAUGE_CHECK
   double total=0.;
 #endif
   for(unsigned int iv = 0; iv < 3; ++iv) {
     for(unsigned int ifm = 0; ifm < 2; ++ifm) {
       for(unsigned int ia = 0; ia < 2; ++ia) {
 	for(unsigned int ig = 0; ig < 2; ++ig) {
 	  // radiation from the incoming vector
 	  if((inpart.dataPtr()->coloured() && inter==ShowerInteraction::QCD) ||
 	     (inpart.dataPtr()->charged()  && inter==ShowerInteraction::QED) ) {
 	    assert(incomingVertex_[inter]);
 	    
 	    VectorWaveFunction vectorInter = 
 	      incomingVertex_[inter]->evaluate(scale,3,inpart.dataPtr(),vector3_[iv],
 						gluon_[2*ig],inpart.mass());
 	    
 	    assert(vector3_[iv].particle()->id()==vectorInter.particle()->id());
 
 	    Complex diag = 0.;
 	    for(auto vertex : vertex_)
 	      diag += vertex->evaluate(scale,wave3_[ia],wavebar3_[ifm],vectorInter);
 	    if(!couplingSet) {
               gs = abs(incomingVertex_[inter]->norm());
 	      couplingSet = true;
 	    }
 	    for(unsigned int ix=0;ix<colourFlow[0].size();++ix) {
 	      (*ME[colourFlow[0][ix].first])(iv, ia, ifm, ig) += 
 		 colourFlow[0][ix].second*diag;
 	    }
 #ifdef GAUGE_CHECK
 	    total+=norm(diag);
 #endif
 	  }
   
 	  // radiation from outgoing fermion
 	  if((decay[iferm]->dataPtr()->coloured() && inter==ShowerInteraction::QCD) ||
 	     (decay[iferm]->dataPtr()->charged()  && inter==ShowerInteraction::QED) ) {
 	    assert(outgoingVertexF);
 	    // ensure you get correct outgoing particle from first vertex
 	    tcPDPtr off = decay[iferm]->dataPtr();
 	    if(off->CC()) off = off->CC();
 	    SpinorBarWaveFunction interS = 
 	      outgoingVertexF->evaluate(scale,3,off,wavebar3_[ifm],
 						gluon_[2*ig],decay[iferm]->mass());
 	    
 	    assert(wavebar3_[ifm].particle()->id()==interS.particle()->id());
 	    
 	    Complex diag = 0.;
 	    for(auto vertex : vertex_)
 	      diag += vertex->evaluate(scale,wave3_[ia], interS,vector3_[iv]);
 	    if(!couplingSet) {
 	      gs = abs(outgoingVertexF->norm());
 	      couplingSet = true;
 	    }
 	    for(unsigned int ix=0;ix<colourFlow[1].size();++ix) {
 	      (*ME[colourFlow[1][ix].first])(iv, ia, ifm, ig) += 
 		colourFlow[1][ix].second*diag;
 	    }
 #ifdef GAUGE_CHECK
 	    total+=norm(diag);
 #endif
 	  }
 
 	  // radiation from outgoing antifermion
 	  if((decay[ianti]->dataPtr()->coloured() && inter==ShowerInteraction::QCD) ||
 	     (decay[ianti]->dataPtr()->charged()  && inter==ShowerInteraction::QED) ) {
 	    assert(outgoingVertexA);
 	    // ensure you get correct outgoing particle from first vertex
 	    tcPDPtr off = decay[ianti]->dataPtr();
 	    if(off->CC()) off = off->CC();
 	    SpinorWaveFunction  interS = 
 	      outgoingVertexA->evaluate(scale,3,off,wave3_[ia],
 						gluon_[2*ig],decay[ianti]->mass());
 
 	    assert(wave3_[ia].particle()->id()==interS.particle()->id());
 
 	    Complex diag = 0.;
 	    for(auto vertex : vertex_)
 	      diag += vertex->evaluate(scale,interS,wavebar3_[ifm],vector3_[iv]);
 	    if(!couplingSet) {
 	      gs = abs(outgoingVertexA->norm());
 	      couplingSet = true;
 	    }
 	    for(unsigned int ix=0;ix<colourFlow[2].size();++ix) {
 	      (*ME[colourFlow[2][ix].first])(iv, ia, ifm, ig) += 
 		colourFlow[2][ix].second*diag;
 	    }
 #ifdef GAUGE_CHECK
 	    total+=norm(diag);
 #endif
 	  }
 	}
       }
     }
   }
 
   // contract matrices 
   double output=0.;
   for(unsigned int ix=0; ix<nflow; ++ix){
     for(unsigned int iy=0; iy<nflow; ++iy){
       output+=cfactors[ix][iy]*(ME[ix]->contract(*ME[iy],rho3_)).real();
     }
   }
   // divide by alpha_(S,EM)
   output*=(4.*Constants::pi)/sqr(gs);
 #ifdef GAUGE_CHECK
   double ratio = output/total;
   if(abs(ratio)>1e-20) {
     generator()->log() << "Test of gauge invariance in decay\n" << inpart << "\n";
     for(unsigned int ix=0;ix<decay.size();++ix)
       generator()->log() << *decay[ix] << "\n";
     generator()->log() << "Test of gauge invariance " << ratio << "\n";
   }
 #endif
   //return output
   return output;
 }
 
 
 void VFFDecayer::identifyVertices(const int iferm, const int ianti,
 				  const Particle & inpart, const ParticleVector & decay, 
 				  AbstractFFVVertexPtr & outgoingVertexF, 
 				  AbstractFFVVertexPtr & outgoingVertexA,
 				  ShowerInteraction inter){
   // QCD vertices
   if(inter==ShowerInteraction::QCD) {
     // work out which fermion each outgoing vertex corresponds to 
     // two outgoing vertices
     if( inpart.dataPtr()       ->iColour()==PDT::Colour0     &&
 	((decay[iferm]->dataPtr()->iColour()==PDT::Colour3     &&
 	  decay[ianti]->dataPtr()->iColour()==PDT::Colour3bar) ||
 	 (decay[iferm]->dataPtr()->iColour()==PDT::Colour8     &&
 	  decay[ianti]->dataPtr()->iColour()==PDT::Colour8))){
       if(outgoingVertex1_[inter]==outgoingVertex2_[inter]){
 	outgoingVertexF = outgoingVertex1_[inter];
 	outgoingVertexA = outgoingVertex2_[inter];
       }
       else if (outgoingVertex1_[inter]->isIncoming(const_ptr_cast<tPDPtr>(decay[iferm]->dataPtr()))){
 	outgoingVertexF = outgoingVertex1_[inter];
 	outgoingVertexA = outgoingVertex2_[inter];
       }
       else if (outgoingVertex2_[inter]->isIncoming(const_ptr_cast<tPDPtr>(decay[iferm]->dataPtr()))){
 	outgoingVertexF = outgoingVertex2_[inter];
 	outgoingVertexA = outgoingVertex1_[inter];
       }
     }
     else if(inpart.dataPtr()       ->iColour()==PDT::Colour8 &&
 	    decay[iferm]->dataPtr()->iColour()==PDT::Colour3 &&
 	    decay[ianti]->dataPtr()->iColour()==PDT::Colour3bar){
       if(outgoingVertex1_[inter]==outgoingVertex2_[inter]){
 	outgoingVertexF = outgoingVertex1_[inter];
 	outgoingVertexA = outgoingVertex2_[inter];
       }
       else if (outgoingVertex1_[inter]->isIncoming(const_ptr_cast<tPDPtr>(decay[iferm]->dataPtr()))){
 	outgoingVertexF = outgoingVertex1_[inter];
 	outgoingVertexA = outgoingVertex2_[inter];
       }
       else if (outgoingVertex2_[inter]->isIncoming(const_ptr_cast<tPDPtr>(decay[iferm]->dataPtr()))){
 	outgoingVertexF = outgoingVertex2_[inter];
 	outgoingVertexA = outgoingVertex1_[inter];
       }
     }
     
     // one outgoing vertex
     else if(inpart.dataPtr()->iColour()==PDT::Colour3){
       if(decay[iferm]->dataPtr()->iColour()==PDT::Colour3 &&  
 	 decay[ianti]->dataPtr()->iColour()==PDT::Colour0){
 	if     (outgoingVertex1_[inter]) outgoingVertexF = outgoingVertex1_[inter];
 	else if(outgoingVertex2_[inter]) outgoingVertexF = outgoingVertex2_[inter];
       }
       else if (decay[iferm]->dataPtr()->iColour()==PDT::Colour3 &&
 	       decay[ianti]->dataPtr()->iColour()==PDT::Colour8){
 	if (outgoingVertex1_[inter]->isIncoming(const_ptr_cast<tPDPtr>(decay[ianti]->dataPtr()))){
 	  outgoingVertexF = outgoingVertex2_[inter];
 	  outgoingVertexA = outgoingVertex1_[inter];
 	}
 	else {
 	  outgoingVertexF = outgoingVertex1_[inter];
 	  outgoingVertexA = outgoingVertex2_[inter];
 	}
       }
     }
     else if(inpart.dataPtr()->iColour()==PDT::Colour3bar){
       if(decay[ianti]->dataPtr()->iColour()==PDT::Colour3bar &&  
 	 decay[iferm]->dataPtr()->iColour()==PDT::Colour0){
 	if     (outgoingVertex1_[inter]) outgoingVertexA = outgoingVertex1_[inter];
 	else if(outgoingVertex2_[inter]) outgoingVertexA = outgoingVertex2_[inter];
       }
       else if (decay[iferm]->dataPtr()->iColour()==PDT::Colour8 &&
 	       decay[ianti]->dataPtr()->iColour()==PDT::Colour3bar){
 	if (outgoingVertex1_[inter]->isIncoming(const_ptr_cast<tPDPtr>(decay[iferm]->dataPtr()))){
 	  outgoingVertexF = outgoingVertex1_[inter];
 	  outgoingVertexA = outgoingVertex2_[inter];
 	}
 	else {
 	  outgoingVertexF = outgoingVertex2_[inter];
 	  outgoingVertexA = outgoingVertex1_[inter];
 	}
       }
     }
     else if(inpart.dataPtr()->iColour()==PDT::Colour6 ||
 	    inpart.dataPtr()->iColour()==PDT::Colour6bar) {
       if (outgoingVertex1_[inter]->isIncoming(const_ptr_cast<tPDPtr>(decay[iferm]->dataPtr()))) {
 	outgoingVertexF = outgoingVertex1_[inter];
 	outgoingVertexA = outgoingVertex2_[inter];
       }
       else {
 	outgoingVertexF = outgoingVertex2_[inter];
 	outgoingVertexA = outgoingVertex1_[inter];
       }
     }
     
     if (! ((incomingVertex_[inter]  && (outgoingVertexF  || outgoingVertexA)) ||
 	   ( outgoingVertexF &&  outgoingVertexA)))
       throw Exception()
 	<< "Invalid vertices for QCD radiation in VFF decay in VFFDecayer::identifyVertices"
 	<< Exception::runerror;
   }
   // QED
   else {
     if(decay[iferm]->dataPtr()->charged()) {
       if (outgoingVertex1_[inter] &&
 	  outgoingVertex1_[inter]->isIncoming(const_ptr_cast<tPDPtr>(decay[iferm]->dataPtr())))
 	outgoingVertexF = outgoingVertex1_[inter];
       else
 	outgoingVertexF = outgoingVertex2_[inter];
     }
     if(decay[ianti]->dataPtr()->charged()) {
       if (outgoingVertex1_[inter] &&
 	  outgoingVertex1_[inter]->isIncoming(const_ptr_cast<tPDPtr>(decay[ianti]->dataPtr())))
 	outgoingVertexA = outgoingVertex1_[inter];
       else
 	outgoingVertexA = outgoingVertex2_[inter];
     }
   }
 }
 
diff --git a/Decay/General/VSSDecayer.cc b/Decay/General/VSSDecayer.cc
--- a/Decay/General/VSSDecayer.cc
+++ b/Decay/General/VSSDecayer.cc
@@ -1,416 +1,418 @@
 // -*- C++ -*-
 //
 // VSSDecayer.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 VSSDecayer class.
 //
 
 #include "VSSDecayer.h"
 #include "ThePEG/Utilities/DescribeClass.h"
 #include "ThePEG/Interface/ClassDocumentation.h"
 #include "ThePEG/Persistency/PersistentOStream.h"
 #include "ThePEG/Persistency/PersistentIStream.h"
 #include "ThePEG/PDT/DecayMode.h"
 #include "Herwig/Utilities/Kinematics.h"
 #include "ThePEG/Helicity/WaveFunction/ScalarWaveFunction.h"
 #include "ThePEG/Helicity/WaveFunction/VectorWaveFunction.h"
 #include "Herwig/Decay/GeneralDecayMatrixElement.h"
 
 using namespace Herwig;
 using namespace ThePEG::Helicity;
 
 IBPtr VSSDecayer::clone() const {
   return new_ptr(*this);
 }
 
 IBPtr VSSDecayer::fullclone() const {
   return new_ptr(*this);
 }
 
 void VSSDecayer::setDecayInfo(PDPtr incoming, PDPair outgoing,
 			      vector<VertexBasePtr> vertex,
 			      map<ShowerInteraction,VertexBasePtr> & inV,
 			      const vector<map<ShowerInteraction,VertexBasePtr> > & outV,
 			      map<ShowerInteraction,VertexBasePtr> ) {
   decayInfo(incoming,outgoing);
   for(auto vert : vertex) {
     vertex_            .push_back(dynamic_ptr_cast<AbstractVSSVertexPtr>(vert));
     perturbativeVertex_.push_back(dynamic_ptr_cast<VSSVertexPtr>        (vert));
   }
   vector<ShowerInteraction> itemp={ShowerInteraction::QCD,ShowerInteraction::QED};
   for(auto & inter : itemp) {
     incomingVertex_[inter] = dynamic_ptr_cast<AbstractVVVVertexPtr>(inV.at(inter));
     outgoingVertex1_[inter] = dynamic_ptr_cast<AbstractVSSVertexPtr>(outV[0].at(inter));
     outgoingVertex2_[inter] = dynamic_ptr_cast<AbstractVSSVertexPtr>(outV[1].at(inter));
   }
 }
 
 void VSSDecayer::persistentOutput(PersistentOStream & os) const {
   os << vertex_           << perturbativeVertex_
      << incomingVertex_   << outgoingVertex1_
      << outgoingVertex2_;
 }
 
 void VSSDecayer::persistentInput(PersistentIStream & is, int) {
   is >> vertex_           >> perturbativeVertex_
      >> incomingVertex_   >> outgoingVertex1_
      >> outgoingVertex2_;
 }
 
 // The following static variable is needed for the type
 // description system in ThePEG.
 DescribeClass<VSSDecayer,GeneralTwoBodyDecayer>
 describeHerwigVSSDecayer("Herwig::VSSDecayer", "Herwig.so");
 
 void VSSDecayer::Init() {
 
   static ClassDocumentation<VSSDecayer> documentation
     ("This implements the decay of a vector to 2 scalars");
 
 }
 
 double VSSDecayer::me2(const int , const Particle & inpart,
  		       const ParticleVector & decay, 
 		       MEOption meopt) const {
   if(!ME())
     ME(new_ptr(GeneralDecayMatrixElement(PDT::Spin1,PDT::Spin0,PDT::Spin0)));
   if(meopt==Initialize) {
     VectorWaveFunction::calculateWaveFunctions(vectors_,rho_,
 					       const_ptr_cast<tPPtr>(&inpart),
 					       incoming,false);
+    // fix rho if no correlations
+    fixRho(rho_);
   }
   if(meopt==Terminate) {
     VectorWaveFunction::constructSpinInfo(vectors_,const_ptr_cast<tPPtr>(&inpart),
 					  incoming,true,false);
     for(unsigned int ix=0;ix<2;++ix)
       ScalarWaveFunction::
 	constructSpinInfo(decay[ix],outgoing,true);
     return 0.;
   }
   ScalarWaveFunction sca1(decay[0]->momentum(),decay[0]->dataPtr(),outgoing);
   ScalarWaveFunction sca2(decay[1]->momentum(),decay[1]->dataPtr(),outgoing);
   Energy2 scale(sqr(inpart.mass()));
   for(unsigned int ix=0;ix<3;++ix) {
     (*ME())(ix,0,0) = 0.;
     for(auto vert : vertex_)
       (*ME())(ix,0,0) += vert->evaluate(scale,vectors_[ix],sca1,sca2);
   }
   double output=(ME()->contract(rho_)).real()/scale*UnitRemoval::E2;
   // colour and identical particle factors
   output *= colourFactor(inpart.dataPtr(),decay[0]->dataPtr(),
 			 decay[1]->dataPtr());
   // return the answer
   return output;
 }
 
 Energy VSSDecayer::partialWidth(PMPair inpart, PMPair outa, 
 				PMPair outb) const {
   if( inpart.second < outa.second + outb.second  ) return ZERO;
   if(perturbativeVertex_.size()==1 &&
      perturbativeVertex_[0]) {
     tcPDPtr in = inpart.first->CC() ? tcPDPtr(inpart.first->CC()) : inpart.first;
     perturbativeVertex_[0]->setCoupling(sqr(inpart.second), in, outa.first,
 				     outb.first);
     double mu1sq = sqr(outa.second/inpart.second);
     double mu2sq = sqr(outb.second/inpart.second);
     double me2 = sqr(mu1sq - mu2sq) - 2.*(mu1sq + mu2sq);
     Energy pcm = Kinematics::pstarTwoBodyDecay(inpart.second,outa.second,
 					outb.second);
     Energy output = -norm(perturbativeVertex_[0]->norm())*me2*pcm /
       (24.*Constants::pi);
     // colour factor
     output *= colourFactor(inpart.first,outa.first,outb.first);
     // return the answer
     return output;
   }
   else {
     return GeneralTwoBodyDecayer::partialWidth(inpart,outa,outb);
   }
 }
 
 double VSSDecayer::threeBodyME(const int , const Particle & inpart,
 			       const ParticleVector & decay,
 			       ShowerInteraction inter, MEOption meopt) {
   // work out which is the scalar and anti-scalar
   int ianti(0), iscal(1), iglu(2);
   int itype[2];
   for(unsigned int ix=0;ix<2;++ix) {
     if(decay[ix]->dataPtr()->CC()) itype[ix] = decay[ix]->id()>0 ? 0:1;
     else                           itype[ix] = 2;
   }
   if(itype[0]==0 && itype[1]!=0) swap(ianti, iscal);
   if(itype[0]==2 && itype[1]==1) swap(ianti, iscal);
   if(itype[0]==0 && itype[1]==0 && abs(decay[0]->dataPtr()->id())>abs(decay[1]->dataPtr()->id())) 
     swap(iscal, ianti);
   if(itype[0]==1 && itype[1]==1 && abs(decay[0]->dataPtr()->id())<abs(decay[1]->dataPtr()->id())) 
     swap(iscal, ianti);
 
  if(meopt==Initialize) {
     // create vector wavefunction for decaying particle
     VectorWaveFunction::calculateWaveFunctions(vector3_, rho3_, const_ptr_cast<tPPtr>(&inpart), 
 					       incoming, false);
   }
   // setup spin information when needed
   if(meopt==Terminate) {
     VectorWaveFunction::
       constructSpinInfo(vector3_ ,const_ptr_cast<tPPtr>(&inpart),outgoing,true,false);
     ScalarWaveFunction::constructSpinInfo(       decay[iscal],outgoing,true);
     ScalarWaveFunction::constructSpinInfo(       decay[ianti],outgoing,true);
     VectorWaveFunction::constructSpinInfo(gluon_,decay[iglu ],outgoing,true,false);
     return 0.;
   }
 
   // calculate colour factors and number of colour flows
   unsigned int nflow;
   vector<DVector> cfactors = getColourFactors(inpart, decay, nflow);
   vector<GeneralDecayMEPtr> ME(nflow,new_ptr(GeneralDecayMatrixElement(PDT::Spin1, PDT::Spin0,
 								       PDT::Spin0, PDT::Spin1)));
 
   // create wavefunctions
   ScalarWaveFunction scal(decay[iscal]->momentum(), decay[iscal]->dataPtr(),outgoing);
   ScalarWaveFunction anti(decay[ianti]->momentum(), decay[ianti]->dataPtr(),outgoing);
   VectorWaveFunction::calculateWaveFunctions(gluon_,decay[iglu ],outgoing,true);
 
   // gauge test
 #ifdef GAUGE_CHECK
   gluon_.clear();
   for(unsigned int ix=0;ix<3;++ix) {
     if(ix==1) gluon_.push_back(VectorWaveFunction());
     else {
       gluon_.push_back(VectorWaveFunction(decay[iglu ]->momentum(),
   					  decay[iglu ]->dataPtr(),10,
   					  outgoing));
     }
   }
 #endif
 
   // identify scalar and/or anti-scalar vertex
   AbstractVSSVertexPtr outgoingVertexS;
   AbstractVSSVertexPtr outgoingVertexA;
   identifyVertices(iscal, ianti, inpart, decay, outgoingVertexS, outgoingVertexA,inter);
 
   Energy2 scale(sqr(inpart.mass()));
 
   const GeneralTwoBodyDecayer::CFlow & colourFlow
         = colourFlows(inpart, decay);
   double gs(0.);
   bool couplingSet(false);
 #ifdef GAUGE_CHECK
   double total=0.;
 #endif
   for(unsigned int iv = 0; iv < 3; ++iv) {
     for(unsigned int ig = 0; ig < 2; ++ig) {
       // radiation from the incoming vector
       if((inpart.dataPtr()->coloured() && inter==ShowerInteraction::QCD) ||
 	 (inpart.dataPtr()->charged()  && inter==ShowerInteraction::QED) ) {
 	assert(incomingVertex_[inter]);	
 	VectorWaveFunction vectorInter = 
 	  incomingVertex_[inter]->evaluate(scale,3,inpart.dataPtr(),vector3_[iv],
 					    gluon_[2*ig],inpart.mass());
 	
 	assert(vector3_[iv].particle()->id()==vectorInter.particle()->id());
 	
 	Complex diag = 0.;
 	for(auto vertex : vertex_)
 	  diag += vertex->evaluate(scale,vectorInter,scal,anti);
 	if(!couplingSet) {
 	  gs = abs(incomingVertex_[inter]->norm());
 	  couplingSet = true;
 	}
 	for(unsigned int ix=0;ix<colourFlow[0].size();++ix) {
 	  (*ME[colourFlow[0][ix].first])(iv, 0, 0, ig) += 
 	    colourFlow[0][ix].second*diag;
 	}
 #ifdef GAUGE_CHECK
       total+=norm(diag);
 #endif
       }
       // radiation from the outgoing scalar
       if((decay[iscal]->dataPtr()->coloured() && inter==ShowerInteraction::QCD) ||
 	 (decay[iscal]->dataPtr()->charged()  && inter==ShowerInteraction::QED) ) {
 	assert(outgoingVertexS);
 	// ensure you get correct outgoing particle from first vertex
 	tcPDPtr off = decay[iscal]->dataPtr();
 	if(off->CC()) off = off->CC();
 	ScalarWaveFunction scalarInter = 
 	  outgoingVertexS->evaluate(scale,3,off,gluon_[2*ig],scal,decay[iscal]->mass());
 	
 	assert(scal.particle()->id()==scalarInter.particle()->id());
 	
 	Complex diag = 0.;
 	for(auto vertex : vertex_)
 	  diag += vertex->evaluate(scale,vector3_[iv],anti,scalarInter);
 	if(!couplingSet) {
 	  gs = abs(outgoingVertexS->norm());
 	  couplingSet = true;
 	}
 	for(unsigned int ix=0;ix<colourFlow[1].size();++ix) {
 	  (*ME[colourFlow[1][ix].first])(iv, 0, 0, ig) += 
 	    colourFlow[1][ix].second*diag;
 	}
 #ifdef GAUGE_CHECK
       total+=norm(diag);
 #endif
       }
       
       if((decay[ianti]->dataPtr()->coloured() && inter==ShowerInteraction::QCD) ||
 	 (decay[ianti]->dataPtr()->charged()  && inter==ShowerInteraction::QED) ) {
 	assert(outgoingVertexA);
 	// ensure you get correct outgoing particle from first vertex
 	tcPDPtr off = decay[ianti]->dataPtr();
 	if(off->CC()) off = off->CC();
 	ScalarWaveFunction scalarInter = 
 	  outgoingVertexA->evaluate(scale,3,off, gluon_[2*ig],anti,decay[ianti]->mass());
 	
 	assert(anti.particle()->id()==scalarInter.particle()->id());
 	
 	Complex diag = 0.;
 	for(auto vertex : vertex_)
 	  diag += vertex->evaluate(scale,vector3_[iv],scal,scalarInter);
 	if(!couplingSet) {
 	  gs = abs(outgoingVertexA->norm());
 	  couplingSet = true;
 	}
 	for(unsigned int ix=0;ix<colourFlow[2].size();++ix) {
 	  (*ME[colourFlow[2][ix].first])(iv, 0, 0, ig) += 
 	    colourFlow[2][ix].second*diag;
 	}
 #ifdef GAUGE_CHECK
       total+=norm(diag);
 #endif
       }
     }
   }
 
   // contract matrices 
   double output=0.;
   for(unsigned int ix=0; ix<nflow; ++ix){
     for(unsigned int iy=0; iy<nflow; ++iy){
       output+=cfactors[ix][iy]*(ME[ix]->contract(*ME[iy],rho3_)).real();
     }
   }
   // divide by alpha_(S,EM)
   output*=(4.*Constants::pi)/sqr(gs);
 #ifdef GAUGE_CHECK
   double ratio = output/total;
   if(abs(ratio)>1e-20) {
     generator()->log() << "Test of gauge invariance in decay\n" << inpart << "\n";
     for(unsigned int ix=0;ix<decay.size();++ix)
       generator()->log() << *decay[ix] << "\n";
     generator()->log() << "Test of gauge invariance " << ratio << "\n";
   }
 #endif
   // return the answer
   return output;
 }
 
 
 void VSSDecayer::identifyVertices(const int iscal, const int ianti,
 				  const Particle & inpart, const ParticleVector & decay, 
 				  AbstractVSSVertexPtr & outgoingVertexS, 
 				  AbstractVSSVertexPtr & outgoingVertexA,
 				  ShowerInteraction inter){
   if(inter==ShowerInteraction::QCD) {
     // work out which scalar each outgoing vertex corresponds to 
     // two outgoing vertices
     if( inpart.dataPtr()       ->iColour()==PDT::Colour0     &&
 	((decay[iscal]->dataPtr()->iColour()==PDT::Colour3     &&
 	  decay[ianti]->dataPtr()->iColour()==PDT::Colour3bar) ||
 	 (decay[iscal]->dataPtr()->iColour()==PDT::Colour8     &&
 	  decay[ianti]->dataPtr()->iColour()==PDT::Colour8))){
       if(outgoingVertex1_[inter]==outgoingVertex2_[inter]){
 	outgoingVertexS = outgoingVertex1_[inter];
 	outgoingVertexA = outgoingVertex2_[inter];
       }
       else if (outgoingVertex1_[inter]->isIncoming(getParticleData(decay[iscal]->id()))){
 	outgoingVertexS = outgoingVertex1_[inter];
 	outgoingVertexA = outgoingVertex2_[inter];
       }
       else if (outgoingVertex2_[inter]->isIncoming(getParticleData(decay[iscal]->id()))){
 	outgoingVertexS = outgoingVertex2_[inter];
 	outgoingVertexA = outgoingVertex1_[inter];
       }
     }
     else if(inpart.dataPtr()       ->iColour()==PDT::Colour8 &&
 	    decay[iscal]->dataPtr()->iColour()==PDT::Colour3 &&
 	    decay[ianti]->dataPtr()->iColour()==PDT::Colour3bar){
       if(outgoingVertex1_[inter]==outgoingVertex2_[inter]){
 	outgoingVertexS = outgoingVertex1_[inter];
 	outgoingVertexA = outgoingVertex2_[inter];
       }
       else if (outgoingVertex1_[inter]->isIncoming(getParticleData(decay[iscal]->id()))){
 	outgoingVertexS = outgoingVertex1_[inter];
 	outgoingVertexA = outgoingVertex2_[inter];
       }
       else if (outgoingVertex2_[inter]->isIncoming(getParticleData(decay[iscal]->id()))){
 	outgoingVertexS = outgoingVertex2_[inter];
 	outgoingVertexA = outgoingVertex1_[inter];
       }
     }
     
     // one outgoing vertex
     else if(inpart.dataPtr()->iColour()==PDT::Colour3){
       if(decay[iscal]->dataPtr()->iColour()==PDT::Colour3 &&  
 	 decay[ianti]->dataPtr()->iColour()==PDT::Colour0){
 	if     (outgoingVertex1_[inter]) outgoingVertexS = outgoingVertex1_[inter];
 	else if(outgoingVertex2_[inter]) outgoingVertexS = outgoingVertex2_[inter];
       }
     else if (decay[iscal]->dataPtr()->iColour()==PDT::Colour3 &&
 	     decay[ianti]->dataPtr()->iColour()==PDT::Colour8){
       if (outgoingVertex1_[inter]->isIncoming(getParticleData(decay[ianti]->dataPtr()->id()))){
 	outgoingVertexS = outgoingVertex2_[inter];
 	outgoingVertexA = outgoingVertex1_[inter];
       }
       else {
 	outgoingVertexS = outgoingVertex1_[inter];
 	outgoingVertexA = outgoingVertex2_[inter];
       }
     }
     }
     else if(inpart.dataPtr()->iColour()==PDT::Colour3bar){
       if(decay[ianti]->dataPtr()->iColour()==PDT::Colour3bar &&  
 	 decay[iscal]->dataPtr()->iColour()==PDT::Colour0){
 	if     (outgoingVertex1_[inter]) outgoingVertexA = outgoingVertex1_[inter];
 	else if(outgoingVertex2_[inter]) outgoingVertexA = outgoingVertex2_[inter];
       }
       else if (decay[iscal]->dataPtr()->iColour()==PDT::Colour8 &&
 	       decay[ianti]->dataPtr()->iColour()==PDT::Colour3bar){
 	if (outgoingVertex1_[inter]->isIncoming(getParticleData(decay[iscal]->dataPtr()->id()))){
 	  outgoingVertexS = outgoingVertex1_[inter];
 	  outgoingVertexA = outgoingVertex2_[inter];
 	}
 	else {
 	  outgoingVertexS = outgoingVertex2_[inter];
 	  outgoingVertexA = outgoingVertex1_[inter];
 	}
       }
     }
     
     if (! ((incomingVertex_[inter]  && (outgoingVertexS  || outgoingVertexA)) ||
 	   ( outgoingVertexS &&  outgoingVertexA)))
       throw Exception()
 	<< "Invalid vertices for QCD radiation in VSS decay in VSSDecayer::identifyVertices"
 	<< Exception::runerror;
   }
   else {
     if(decay[iscal]->dataPtr()->charged()) {
       if (outgoingVertex1_[inter] &&
 	  outgoingVertex1_[inter]->isIncoming(const_ptr_cast<tPDPtr>(decay[iscal]->dataPtr())))
 	outgoingVertexS = outgoingVertex1_[inter];
       else
 	outgoingVertexS = outgoingVertex2_[inter];
     }
     if(decay[ianti]->dataPtr()->charged()) {
       if (outgoingVertex1_[inter] &&
 	  outgoingVertex1_[inter]->isIncoming(const_ptr_cast<tPDPtr>(decay[ianti]->dataPtr())))
 	outgoingVertexA = outgoingVertex1_[inter];
       else
 	outgoingVertexA = outgoingVertex2_[inter];
     }
   }
 }
diff --git a/Decay/General/VVSDecayer.cc b/Decay/General/VVSDecayer.cc
--- a/Decay/General/VVSDecayer.cc
+++ b/Decay/General/VVSDecayer.cc
@@ -1,313 +1,315 @@
 // -*- C++ -*-
 //
 // This is the implementation of the non-inlined, non-templated member
 // functions of the VVSDecayer class.
 //
 
 #include "VVSDecayer.h"
 #include "ThePEG/Utilities/DescribeClass.h"
 #include "ThePEG/Interface/ClassDocumentation.h"
 #include "ThePEG/Persistency/PersistentOStream.h"
 #include "ThePEG/Persistency/PersistentIStream.h"
 #include "Herwig/Decay/GeneralDecayMatrixElement.h"
 
 using namespace Herwig;
 using namespace ThePEG::Helicity;
 IBPtr VVSDecayer::clone() const {
   return new_ptr(*this);
 }
 
 IBPtr VVSDecayer::fullclone() const {
   return new_ptr(*this);
 }
 void VVSDecayer::setDecayInfo(PDPtr incoming, PDPair outgoing,
 			      vector<VertexBasePtr> vertex,
 			      map<ShowerInteraction,VertexBasePtr> & inV,
 			      const vector<map<ShowerInteraction,VertexBasePtr> > & outV,
 			      map<ShowerInteraction,VertexBasePtr>) {
   decayInfo(incoming,outgoing);
   for(auto vert : vertex) {
     vertex_            .push_back(dynamic_ptr_cast<AbstractVVSVertexPtr>(vert));
     perturbativeVertex_.push_back(dynamic_ptr_cast<VVSVertexPtr>        (vert));
   }
   vector<ShowerInteraction> itemp={ShowerInteraction::QCD,ShowerInteraction::QED};
   for(auto & inter : itemp) {
     incomingVertex_[inter]  = dynamic_ptr_cast<AbstractVVVVertexPtr>(inV.at(inter));
     outgoingVertexS_[inter] = AbstractVSSVertexPtr();
     outgoingVertexV_[inter] = AbstractVVVVertexPtr();  
     if(outV[0].at(inter)) {
       if (outV[0].at(inter)->getName()==VertexType::VSS)
 	outgoingVertexS_[inter]   = dynamic_ptr_cast<AbstractVSSVertexPtr>(outV[0].at(inter));
       else
 	outgoingVertexV_[inter]   = dynamic_ptr_cast<AbstractVVVVertexPtr>(outV[0].at(inter));
     }
     if(outV[1].at(inter)) {
       if (outV[1].at(inter)->getName()==VertexType::VSS)
 	outgoingVertexS_[inter]   = dynamic_ptr_cast<AbstractVSSVertexPtr>(outV[1].at(inter));
       else 
 	outgoingVertexV_[inter]   = dynamic_ptr_cast<AbstractVVVVertexPtr>(outV[1].at(inter));
     }
   }
 }
 
 void VVSDecayer::persistentOutput(PersistentOStream & os) const {
   os << vertex_ << perturbativeVertex_
      << incomingVertex_ << outgoingVertexS_ << outgoingVertexV_;
 }
 
 void VVSDecayer::persistentInput(PersistentIStream & is, int) {
   is >> vertex_ >> perturbativeVertex_
      >> incomingVertex_ >> outgoingVertexS_ >> outgoingVertexV_;
 }
 
 // The following static variable is needed for the type
 // description system in ThePEG.
 DescribeClass<VVSDecayer,GeneralTwoBodyDecayer>
 describeHerwigVVSDecayer("Herwig::VVSDecayer", "Herwig.so");
 
 void VVSDecayer::Init() {
 
   static ClassDocumentation<VVSDecayer> documentation
     ("The VVSDecayer class implements the decay of a vector"
      " to a vector and a scalar");
 
 }
 
 double VVSDecayer::me2(const int , const Particle & inpart,
  		       const ParticleVector & decay,
 		       MEOption meopt) const {
   bool massless = ( decay[0]->id()==ParticleID::gamma || 
 		    decay[0]->id()==ParticleID::g );
   if(!ME())
     ME(new_ptr(GeneralDecayMatrixElement(PDT::Spin1,PDT::Spin1,PDT::Spin0)));
   if(meopt==Initialize) {
     VectorWaveFunction::calculateWaveFunctions(vectors_[0],rho_,
 					       const_ptr_cast<tPPtr>(&inpart),
 					       incoming,false);
+    // fix rho if no correlations
+    fixRho(rho_);
   }
   if(meopt==Terminate) {
     VectorWaveFunction::constructSpinInfo(vectors_[0],const_ptr_cast<tPPtr>(&inpart),
 					  incoming,true,false);
     VectorWaveFunction::
       constructSpinInfo(vectors_[1],decay[0],outgoing,true,massless);
     ScalarWaveFunction::
       constructSpinInfo(decay[1],outgoing,true);
     return 0.;
   }
   VectorWaveFunction::
     calculateWaveFunctions(vectors_[1],decay[0],outgoing,massless);
   ScalarWaveFunction sca(decay[1]->momentum(),decay[1]->dataPtr(),outgoing);
   Energy2 scale(sqr(inpart.mass()));
   for(unsigned int in=0;in<3;++in) {
     for(unsigned int out=0;out<3;++out) {
       if(massless&&out==1) ++out;
       (*ME())(in,out,0) = 0.;
       for(auto vert : vertex_)
 	(*ME())(in,out,0) += 
 	  vert->evaluate(scale,vectors_[0][in],vectors_[1][out],sca);
     }
   }
   double output=(ME()->contract(rho_)).real()/scale*UnitRemoval::E2;
   // colour and identical particle factors
   output *= colourFactor(inpart.dataPtr(),decay[0]->dataPtr(),
 			 decay[1]->dataPtr());
   // return the answer
   return output;
 }
 
 Energy VVSDecayer::partialWidth(PMPair inpart, PMPair outa, 
 				PMPair outb) const {
   if( inpart.second < outa.second + outb.second  ) return ZERO;
   if(perturbativeVertex_.size()==1 &&
      perturbativeVertex_[0]) {
     Energy2 scale(sqr(inpart.second));
     double mu1sq = sqr(outa.second/inpart.second);
     double mu2sq = sqr(outb.second/inpart.second);
     tcPDPtr in = inpart.first->CC() ? tcPDPtr(inpart.first->CC()) : inpart.first;
     if( outb.first->iSpin() == PDT::Spin0 )
       perturbativeVertex_[0]->setCoupling(sqr(inpart.second), in, 
 				       outa.first, outb.first);
     else {
       perturbativeVertex_[0]->setCoupling(sqr(inpart.second), in, 
 				       outb.first, outa.first);
       swap(mu1sq, mu2sq);
     }
     double vn = norm(perturbativeVertex_[0]->norm());
     if(vn == ZERO || mu1sq == ZERO) return ZERO;
     double me2 = 2. + 0.25*sqr(1. + mu1sq - mu2sq)/mu1sq;
     Energy pcm = Kinematics::pstarTwoBodyDecay(inpart.second,outa.second,
 					outb.second);
     Energy output = vn*me2*pcm/(24.*Constants::pi)/scale*UnitRemoval::E2;
     // colour factor
     output *= colourFactor(inpart.first,outa.first,outb.first);
     // return the answer
     return output;
   }
   else {
     return GeneralTwoBodyDecayer::partialWidth(inpart,outa,outb);
   }
 }
 
 double VVSDecayer::threeBodyME(const int , const Particle & inpart,
 			       const ParticleVector & decay,
 			       ShowerInteraction inter, MEOption meopt) {
   unsigned int ivec(0),isca(1);
   if(decay[ivec]->dataPtr()->iSpin()!=PDT::Spin1) swap(ivec,isca);
   if(meopt==Initialize) {
     // create vector wavefunction for decaying particle
     VectorWaveFunction::calculateWaveFunctions(vectors3_[0], rho3_,
 					       const_ptr_cast<tPPtr>(&inpart), 
 					       incoming, false);
   }
   if(meopt==Terminate) {
     VectorWaveFunction::
       constructSpinInfo(vectors3_[0] ,const_ptr_cast<tPPtr>(&inpart),outgoing,true,false);
     VectorWaveFunction::
       constructSpinInfo(vectors3_[1],decay[ivec],outgoing,true,false); 
     ScalarWaveFunction::
       constructSpinInfo(decay[isca],outgoing,true);
     VectorWaveFunction::
       constructSpinInfo(gluon_      ,decay[2],outgoing,true,false);
     return 0.;
   }
   // calculate colour factors and number of colour flows
   unsigned int nflow;
   vector<DVector> cfactors = getColourFactors(inpart, decay, nflow);
   vector<GeneralDecayMEPtr> ME(nflow,new_ptr(GeneralDecayMatrixElement(PDT::Spin1, PDT::Spin1,
 								       PDT::Spin0, PDT::Spin1)));
   bool massless= decay[ivec]->mass()!=ZERO;
   // create wavefunctions
   VectorWaveFunction::calculateWaveFunctions(vectors3_[1],decay[0],outgoing,massless);
   ScalarWaveFunction scal(decay[isca]->momentum(),  decay[isca]->dataPtr(),outgoing);
   VectorWaveFunction::calculateWaveFunctions(gluon_      ,decay[2],outgoing,true);
 
   // gauge test
 #ifdef GAUGE_CHECK
   gluon_.clear();
   for(unsigned int ix=0;ix<3;++ix) {
     if(ix==1) gluon_.push_back(VectorWaveFunction());
     else {
       gluon_.push_back(VectorWaveFunction(decay[2]->momentum(),
   					  decay[2]->dataPtr(),10,
   					  outgoing));
     }
   }
 #endif
 
   Energy2 scale(sqr(inpart.mass()));
   
   const GeneralTwoBodyDecayer::CFlow & colourFlow
     = colourFlows(inpart, decay);
   double gs(0.);
   bool couplingSet(false);
 #ifdef GAUGE_CHECK
   double total=0.;
 #endif
 
    for(unsigned int iv0 = 0; iv0 < 3; ++iv0) {
      for(unsigned int iv1 = 0; iv1 < 3; ++iv1) {
        if(massless && iv1==1) continue;
        for(unsigned int ig = 0; ig < 2; ++ig) {
 	 // radiation from the incoming vector
 	 if((inpart.dataPtr()->coloured() && inter==ShowerInteraction::QCD) ||
 	    (inpart.dataPtr()->charged()  && inter==ShowerInteraction::QED) ) {
 	   assert(incomingVertex_[inter]);
 	   VectorWaveFunction vectorInter = 
 	     incomingVertex_[inter]->evaluate(scale,3,inpart.dataPtr(),vectors3_[0][iv0],
 					      gluon_[2*ig],inpart.mass());
 	   
 	   assert(vectors3_[0][iv0].particle()->id()==vectorInter.particle()->id());
 	   Complex diag = 0.;
 	   for(auto vertex : vertex_)
 	     diag += vertex->evaluate(scale,vectorInter,vectors3_[1][iv1],scal);
 	   if(!couplingSet) {
 	     gs = abs(incomingVertex_[inter]->norm());
 	     couplingSet = true;
 	   }
 	   for(unsigned int ix=0;ix<colourFlow[0].size();++ix) {
 	     (*ME[colourFlow[0][ix].first])(iv0, iv1, 0, ig) += 
 	       colourFlow[0][ix].second*diag;
 	   }
 #ifdef GAUGE_CHECK
 	   total+=norm(diag);
 #endif
 	 }
 	 // radiation from the outgoing vector
 	 if((decay[ivec]->dataPtr()->coloured() && inter==ShowerInteraction::QCD) ||
 	    (decay[ivec]->dataPtr()->charged()  && inter==ShowerInteraction::QED) ) {
 	   assert(outgoingVertexV_[inter]);
 	   // ensure you get correct outgoing particle from first vertex
 	   tcPDPtr off = decay[ivec]->dataPtr();
 	   if(off->CC()) off = off->CC();
 	   VectorWaveFunction vectorInter = 
 	     outgoingVertexV_[inter]->evaluate(scale,3,off,gluon_[2*ig],vectors3_[1][iv1],decay[ivec]->mass());
 	   
 	   assert(vectors3_[1][iv1].particle()->id()==vectorInter.particle()->id());
 	   
 	   Complex diag = 0.;
 	   for(auto vertex : vertex_)
 	     diag += vertex->evaluate(scale,vectors3_[0][iv0],vectorInter,scal);
 	   if(!couplingSet) {
 	     gs = abs(outgoingVertexV_[inter]->norm());
 	     couplingSet = true;
 	   }
 	   for(unsigned int ix=0;ix<colourFlow[1].size();++ix) {
 	     (*ME[colourFlow[1][ix].first])(iv0, iv1, 0, ig) += 
 	       colourFlow[1][ix].second*diag;
 	   }
 #ifdef GAUGE_CHECK
 	   total+=norm(diag);
 #endif
 	 }
 	 // radiation from the outgoing scalar
 	 if((decay[isca]->dataPtr()->coloured() && inter==ShowerInteraction::QCD) ||
 	    (decay[isca]->dataPtr()->charged()  && inter==ShowerInteraction::QED) ) {
 	   assert(outgoingVertexS_[inter]);
 	   // ensure you get correct outgoing particle from first vertex
 	   tcPDPtr off = decay[isca]->dataPtr();
 	   if(off->CC()) off = off->CC();
 	   ScalarWaveFunction scalarInter = 
 	     outgoingVertexS_[inter]->evaluate(scale,3,off,gluon_[2*ig],scal,decay[isca]->mass());
 	
 	   assert(scal.particle()->id()==scalarInter.particle()->id());
 	 
 	   Complex diag = 0.;
 	   for(auto vertex : vertex_)
 	     diag += vertex->evaluate(scale,vectors3_[0][iv0],vectors3_[1][iv1],scalarInter);
 	   if(!couplingSet) {
 	     gs = abs(outgoingVertexS_[inter]->norm());
 	     couplingSet = true;
 	   }
 	   for(unsigned int ix=0;ix<colourFlow[2].size();++ix) {
 	     (*ME[colourFlow[2][ix].first])(iv0, iv1, 0, ig) += 
 	       colourFlow[2][ix].second*diag;
 	   }
 #ifdef GAUGE_CHECK
 	   total+=norm(diag);
 #endif
 	 }
        }
      }
    }
    
    // contract matrices 
    double output=0.;
    for(unsigned int ix=0; ix<nflow; ++ix){
      for(unsigned int iy=0; iy<nflow; ++iy){
        output+=cfactors[ix][iy]*(ME[ix]->contract(*ME[iy],rho3_)).real();
      }
    }
    // divide by alpha_(S,EM)
    output*=(4.*Constants::pi)/sqr(gs);
 #ifdef GAUGE_CHECK
    double ratio = output/total;
    if(abs(ratio)>1e-20) {
      generator()->log() << "Test of gauge invariance in decay\n" << inpart << "\n";
      for(unsigned int ix=0;ix<decay.size();++ix)
        generator()->log() << *decay[ix] << "\n";
      generator()->log() << "Test of gauge invariance " << ratio << "\n";
    }
 #endif
    // return the answer
    return output;
 }
diff --git a/Decay/General/VVVDecayer.cc b/Decay/General/VVVDecayer.cc
--- a/Decay/General/VVVDecayer.cc
+++ b/Decay/General/VVVDecayer.cc
@@ -1,441 +1,443 @@
 // -*- C++ -*-
 //
 // VVVDecayer.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 VVVDecayer class.
 //
 
 #include "VVVDecayer.h"
 #include "ThePEG/Utilities/DescribeClass.h"
 #include "ThePEG/Interface/ClassDocumentation.h"
 #include "ThePEG/Persistency/PersistentOStream.h"
 #include "ThePEG/Persistency/PersistentIStream.h"
 #include "ThePEG/PDT/DecayMode.h"
 #include "ThePEG/Helicity/WaveFunction/VectorWaveFunction.h"
 #include "Herwig/Utilities/Kinematics.h"
 #include "Herwig/Decay/GeneralDecayMatrixElement.h"
 
 using namespace Herwig;
 using namespace ThePEG::Helicity;
 
 IBPtr VVVDecayer::clone() const {
   return new_ptr(*this);
 }
 
 IBPtr VVVDecayer::fullclone() const {
   return new_ptr(*this);
 }
 
 void VVVDecayer::setDecayInfo(PDPtr incoming, PDPair outgoing,
 			      vector<VertexBasePtr> vertex,
 			      map<ShowerInteraction,VertexBasePtr> & inV,
 			      const vector<map<ShowerInteraction,VertexBasePtr> > & outV,
 			      map<ShowerInteraction,VertexBasePtr> fourV) {
   decayInfo(incoming,outgoing);
   for(auto vert : vertex) {
     vertex_             .push_back(dynamic_ptr_cast<AbstractVVVVertexPtr>(vert));
     perturbativeVertex_ .push_back(dynamic_ptr_cast<VVVVertexPtr>        (vert));
   }
   vector<ShowerInteraction> itemp={ShowerInteraction::QCD,ShowerInteraction::QED};
   for(auto & inter : itemp) {
     incomingVertex_[inter]  = dynamic_ptr_cast<AbstractVVVVertexPtr>(inV.at(inter));
     outgoingVertex1_[inter] = dynamic_ptr_cast<AbstractVVVVertexPtr>(outV[0].at(inter));
     outgoingVertex2_[inter] = dynamic_ptr_cast<AbstractVVVVertexPtr>(outV[1].at(inter));
     fourPointVertex_[inter] = dynamic_ptr_cast<AbstractVVVVVertexPtr>(fourV.at(inter));
   }
 }
 
 void VVVDecayer::persistentOutput(PersistentOStream & os) const {
   os << vertex_ << perturbativeVertex_
      << incomingVertex_  << outgoingVertex1_
      << outgoingVertex2_ << fourPointVertex_;
 }
 
 void VVVDecayer::persistentInput(PersistentIStream & is, int) {
   is >> vertex_ >> perturbativeVertex_
      >> incomingVertex_   >> outgoingVertex1_
      >> outgoingVertex2_ >> fourPointVertex_;
 }
 
 // The following static variable is needed for the type
 // description system in ThePEG.
 DescribeClass<VVVDecayer,GeneralTwoBodyDecayer>
 describeHerwigVVVDecayer("Herwig::VVVDecayer", "Herwig.so");
 
 void VVVDecayer::Init() {
 
   static ClassDocumentation<VVVDecayer> documentation
     ("The VVVDecayer class implements the decay of a vector boson "
      "into 2 vector bosons");
 
 }
 
 double VVVDecayer::me2(const int , const Particle & inpart,
                        const ParticleVector & decay,
 		       MEOption meopt) const {
   if(!ME())
     ME(new_ptr(GeneralDecayMatrixElement(PDT::Spin1,PDT::Spin1,PDT::Spin1)));
   bool massless[2];
   for(unsigned int ix=0;ix<2;++ix) 
     massless[ix] = (decay[ix]->id()==ParticleID::gamma ||
 		    decay[ix]->id()==ParticleID::g);
   if(meopt==Initialize) {
     VectorWaveFunction::calculateWaveFunctions(vectors_[0],rho_,
 					       const_ptr_cast<tPPtr>(&inpart),
 					       incoming,false);
+    // fix rho if no correlations
+    fixRho(rho_);
   }
   if(meopt==Terminate) {
     VectorWaveFunction::constructSpinInfo(vectors_[0],const_ptr_cast<tPPtr>(&inpart),
 					  incoming,true,false);
     for(unsigned int ix=0;ix<2;++ix)
       VectorWaveFunction::
 	constructSpinInfo(vectors_[ix+1],decay[ix],outgoing,true,massless[ix]);
     return 0.;
   }
   for(unsigned int ix=0;ix<2;++ix)
     VectorWaveFunction::
       calculateWaveFunctions(vectors_[ix+1],decay[ix],outgoing,massless[ix]);
   Energy2 scale(sqr(inpart.mass()));
   for(unsigned int iv3=0;iv3<3;++iv3) {
     for(unsigned int iv2=0;iv2<3;++iv2) {
       for(unsigned int iv1=0;iv1<3;++iv1) {
 	(*ME())(iv1,iv2,iv3) = 0.;
 	for(auto vert : vertex_) {
 	  (*ME())(iv1,iv2,iv3) += vert->
 	    evaluate(scale,vectors_[1][iv2],vectors_[2][iv3],vectors_[0][iv1]);
 	}
       }
     }
   }
   double output = (ME()->contract(rho_)).real()/scale*UnitRemoval::E2;
   // colour and identical particle factors
   output *= colourFactor(inpart.dataPtr(),decay[0]->dataPtr(),
 			 decay[1]->dataPtr());
   // return the answer
   return output;
 }
 
 Energy VVVDecayer::partialWidth(PMPair inpart, PMPair outa, 
 				PMPair outb) const {
   if( inpart.second < outa.second + outb.second  ) return ZERO;
   if(perturbativeVertex_.size()==1 &&
      perturbativeVertex_[0]) {
     tcPDPtr in = inpart.first->CC() ? tcPDPtr(inpart.first->CC()) : inpart.first;
     perturbativeVertex_[0]->setCoupling(sqr(inpart.second), in,
 					outa.first, outb.first);
     double mu1(outa.second/inpart.second), mu1sq(sqr(mu1)),
       mu2(outb.second/inpart.second), mu2sq(sqr(mu2));
     double vn = norm(perturbativeVertex_[0]->norm());
     if(vn == ZERO || mu1sq == ZERO || mu2sq == ZERO) return ZERO;
     double me2 = 
       (mu1 - mu2 - 1.)*(mu1 - mu2 + 1.)*(mu1 + mu2 - 1.)*(mu1 + mu2 + 1.)
       * (sqr(mu1sq) + sqr(mu2sq) + 10.*(mu1sq*mu2sq + mu1sq + mu2sq) + 1.)
       /4./mu1sq/mu2sq;
     Energy pcm = Kinematics::pstarTwoBodyDecay(inpart.second,outa.second,
 					outb.second);
     Energy pWidth = vn*me2*pcm/24./Constants::pi;
     // colour factor
     pWidth *= colourFactor(inpart.first,outa.first,outb.first);
     // return the answer
     return pWidth;
   }
   else {
     return GeneralTwoBodyDecayer::partialWidth(inpart,outa,outb);
   }
 }
 
 double VVVDecayer::threeBodyME(const int , const Particle & inpart,
 			       const ParticleVector & decay,
 			       ShowerInteraction inter, MEOption meopt) {
   if(meopt==Initialize) {
     // create vector wavefunction for decaying particle
     VectorWaveFunction::calculateWaveFunctions(vector3_, rho3_, const_ptr_cast<tPPtr>(&inpart), 
 					       incoming, false);
   }
   if(meopt==Terminate) {
     VectorWaveFunction::
       constructSpinInfo(vector3_ ,const_ptr_cast<tPPtr>(&inpart),outgoing,true,false);
     VectorWaveFunction::
       constructSpinInfo(vectors3_[0],decay[0],outgoing,true,false);
     VectorWaveFunction::
       constructSpinInfo(vectors3_[1],decay[1],outgoing,true,false);
     VectorWaveFunction::
       constructSpinInfo(gluon_      ,decay[2],outgoing,true,false);
     return 0.;
   }
   // calculate colour factors and number of colour flows
   unsigned int nflow;
   vector<DVector> cfactors = getColourFactors(inpart, decay, nflow);
   vector<GeneralDecayMEPtr> ME(nflow,new_ptr(GeneralDecayMatrixElement(PDT::Spin1, PDT::Spin1,
 								       PDT::Spin1, PDT::Spin1)));
   bool massless[2];
   for(unsigned int ix=0;ix<2;++ix)
     massless[ix] = decay[ix]->mass()!=ZERO;
   // create wavefunctions
   VectorWaveFunction::calculateWaveFunctions(vectors3_[0],decay[0],outgoing,massless[0]);
   VectorWaveFunction::calculateWaveFunctions(vectors3_[1],decay[1],outgoing,massless[1]);
   VectorWaveFunction::calculateWaveFunctions(gluon_      ,decay[2],outgoing,true);
 
   // gauge test
 #ifdef GAUGE_CHECK
   gluon_.clear();
   for(unsigned int ix=0;ix<3;++ix) {
     if(ix==1) gluon_.push_back(VectorWaveFunction());
     else {
       gluon_.push_back(VectorWaveFunction(decay[2]->momentum(),
   					  decay[2]->dataPtr(),10,
   					  outgoing));
     }
   }
 #endif
 
   // get the outgoing vertices
   AbstractVVVVertexPtr outgoingVertex1;
   AbstractVVVVertexPtr outgoingVertex2;
   identifyVertices(inpart,decay, outgoingVertex1, outgoingVertex2,inter);
 
   Energy2 scale(sqr(inpart.mass()));
 
   const GeneralTwoBodyDecayer::CFlow & colourFlow
         = colourFlows(inpart, decay);
   double gs(0.);
   bool couplingSet(false);
 #ifdef GAUGE_CHECK
   double total=0.;
 #endif
 
    for(unsigned int iv0 = 0; iv0 < 3; ++iv0) {
      for(unsigned int iv1 = 0; iv1 < 3; ++iv1) {
        if(massless[0] && iv1==1) continue;
        for(unsigned int iv2 = 0; iv2 < 3; ++iv2) {
 	 if(massless[1] && iv2==1) continue;
 	 for(unsigned int ig = 0; ig < 2; ++ig) {
 	   // radiation from the incoming vector
 	   if((inpart.dataPtr()->coloured() && inter==ShowerInteraction::QCD) ||
 	      (inpart.dataPtr()->charged()  && inter==ShowerInteraction::QED) ) {
 	     assert(incomingVertex_[inter]);
 	     VectorWaveFunction vectorInter = 
 	       incomingVertex_[inter]->evaluate(scale,3,inpart.dataPtr(),vector3_[iv0],
 						gluon_[2*ig],inpart.mass());
 	     
 	     assert(vector3_[iv0].particle()->id()==vectorInter.particle()->id());
 	     
 	     Complex diag = 0.;
 	     for(auto vertex : vertex_)
 	       diag += vertex->evaluate(scale,vectorInter,vectors3_[0][iv1],
 					vectors3_[1][iv2]);
 	     if(!couplingSet) {
 	       gs = abs(incomingVertex_[inter]->norm());
 	       couplingSet = true;
 	     }
 	     for(unsigned int ix=0;ix<colourFlow[0].size();++ix) {
 	       (*ME[colourFlow[0][ix].first])(iv0, iv1, iv2, ig) += 
 		 colourFlow[0][ix].second*diag;
 	     }
 #ifdef GAUGE_CHECK
 	     total+=norm(diag);
 #endif
 	   }
 	   // radiation from the 1st outgoing vector
 	   if((decay[0]->dataPtr()->coloured() && inter==ShowerInteraction::QCD) ||
 	      (decay[0]->dataPtr()->charged()  && inter==ShowerInteraction::QED) ) {
 	     assert(outgoingVertex1);
 	     // ensure you get correct outgoing particle from first vertex
 	     tcPDPtr off = decay[0]->dataPtr();
 	     if(off->CC()) off = off->CC();
 	     VectorWaveFunction vectorInter = 
 	       outgoingVertex1->evaluate(scale,3,off,gluon_[2*ig],vectors3_[0][iv1],decay[0]->mass());
 	     
 	     assert(vectors3_[0][iv1].particle()->id()==vectorInter.particle()->id());
 	     
 	     Complex diag = 0.;
 	     for(auto vertex : vertex_)
 	       diag += vertex->evaluate(scale,vector3_[iv0],vectorInter,vectors3_[1][iv2]);
 	     if(!couplingSet) {
 	       gs = abs(outgoingVertex1->norm());
 	       couplingSet = true;
 	     }
 	     for(unsigned int ix=0;ix<colourFlow[1].size();++ix) {
 	       (*ME[colourFlow[1][ix].first])(iv0, iv1, iv2, ig) += 
 		 colourFlow[1][ix].second*diag;
 	     }
 #ifdef GAUGE_CHECK
 	     total+=norm(diag);
 #endif
 	   }
 	   // radiation from the second outgoing vector
 	   if((decay[1]->dataPtr()->coloured() && inter==ShowerInteraction::QCD) ||
 	      (decay[1]->dataPtr()->charged()  && inter==ShowerInteraction::QED) ) {
 	     assert(outgoingVertex2);
 	     // ensure you get correct outgoing particle from first vertex
 	     tcPDPtr off = decay[1]->dataPtr();
 	     if(off->CC()) off = off->CC();
 	     VectorWaveFunction vectorInter = 
 	       outgoingVertex2->evaluate(scale,3,off, gluon_[2*ig],vectors3_[1][iv2],decay[1]->mass());
 	     
 	     assert(vectors3_[1][iv2].particle()->id()==vectorInter.particle()->id());
 	     
 	     Complex diag = 0.;
 	     for(auto vertex : vertex_)
 	       diag += vertex->evaluate(scale,vector3_[iv0],vectors3_[0][iv1],vectorInter);
 	     if(!couplingSet) {
 	       gs = abs(outgoingVertex2->norm());
 	       couplingSet = true;
 	     }
 	     for(unsigned int ix=0;ix<colourFlow[2].size();++ix) {
 	       (*ME[colourFlow[2][ix].first])(iv0, iv1, iv2, ig) += 
 		 colourFlow[2][ix].second*diag;
 	     }
 #ifdef GAUGE_CHECK
 	     total+=norm(diag);
 #endif
 	   }
 	   // 4-point vertex
 	   if (fourPointVertex_[inter]) {
 	     Complex diag = fourPointVertex_[inter]->evaluate(scale,0, vector3_[iv0],
 							      vectors3_[0][iv1],
 							      vectors3_[1][iv2],gluon_[2*ig]);
 	     for(unsigned int ix=0;ix<colourFlow[2].size();++ix) {
 	       (*ME[colourFlow[3][ix].first])(iv0, iv1, iv2, ig) += 
 		 colourFlow[3][ix].second*diag;
 	     }
 #ifdef GAUGE_CHECK
 	     total+=norm(diag);
 #endif
 	   }
 	 }
        }
      }
    }
    
    // contract matrices 
    double output=0.;
    for(unsigned int ix=0; ix<nflow; ++ix){
      for(unsigned int iy=0; iy<nflow; ++iy){
        output+=cfactors[ix][iy]*(ME[ix]->contract(*ME[iy],rho3_)).real();
      }
    }
    // divide by alpha_(S,EM)
    output*=(4.*Constants::pi)/sqr(gs);
 #ifdef GAUGE_CHECK
    double ratio = output/total;
    if(abs(ratio)>1e-20) {
      generator()->log() << "Test of gauge invariance in decay\n" << inpart << "\n";
      for(unsigned int ix=0;ix<decay.size();++ix)
        generator()->log() << *decay[ix] << "\n";
      generator()->log() << "Test of gauge invariance " << ratio << "\n";
    }
 #endif
    // return the answer
    return output;
 }
 
 void VVVDecayer::identifyVertices(const Particle & inpart, const ParticleVector & decay, 
 				  AbstractVVVVertexPtr & outgoingVertex1, 
 				  AbstractVVVVertexPtr & outgoingVertex2,
 				  ShowerInteraction inter) {
   if(inter==ShowerInteraction::QCD) {
     // work out which scalar each outgoing vertex corresponds to 
     // two outgoing vertices
     if( inpart.dataPtr()       ->iColour()==PDT::Colour0     &&
 	((decay[0]->dataPtr()->iColour()==PDT::Colour3     &&
 	  decay[1]->dataPtr()->iColour()==PDT::Colour3bar) ||
 	 (decay[0]->dataPtr()->iColour()==PDT::Colour8     &&
 	  decay[1]->dataPtr()->iColour()==PDT::Colour8))){
       if(outgoingVertex1_[inter]==outgoingVertex2_[inter]){
 	outgoingVertex1 = outgoingVertex1_[inter];
 	outgoingVertex2 = outgoingVertex2_[inter];
       }
       else if (outgoingVertex1_[inter]->isIncoming(getParticleData(decay[0]->id()))){
 	outgoingVertex1 = outgoingVertex1_[inter];
 	outgoingVertex2 = outgoingVertex2_[inter];
       }
       else if (outgoingVertex2_[inter]->isIncoming(getParticleData(decay[0]->id()))){
 	outgoingVertex1 = outgoingVertex2_[inter];
 	outgoingVertex2 = outgoingVertex1_[inter];
       }
     }
     else if(inpart.dataPtr()       ->iColour()==PDT::Colour8 &&
 	    decay[0]->dataPtr()->iColour()==PDT::Colour3 &&
 	    decay[1]->dataPtr()->iColour()==PDT::Colour3bar){
       if(outgoingVertex1_[inter]==outgoingVertex2_[inter]){
 	outgoingVertex1 = outgoingVertex1_[inter];
 	outgoingVertex2 = outgoingVertex2_[inter];
       }
       else if (outgoingVertex1_[inter]->isIncoming(getParticleData(decay[0]->id()))){
 	outgoingVertex1 = outgoingVertex1_[inter];
 	outgoingVertex2 = outgoingVertex2_[inter];
       }
       else if (outgoingVertex2_[inter]->isIncoming(getParticleData(decay[0]->id()))){
 	outgoingVertex1 = outgoingVertex2_[inter];
 	outgoingVertex2 = outgoingVertex1_[inter];
       }
     }
     
     // one outgoing vertex
     else if(inpart.dataPtr()->iColour()==PDT::Colour3){
       if(decay[0]->dataPtr()->iColour()==PDT::Colour3 &&  
 	 decay[1]->dataPtr()->iColour()==PDT::Colour0){
 	if     (outgoingVertex1_[inter]) outgoingVertex1 = outgoingVertex1_[inter];
 	else if(outgoingVertex2_[inter]) outgoingVertex1 = outgoingVertex2_[inter];
       }
       else if (decay[0]->dataPtr()->iColour()==PDT::Colour3 &&
 	       decay[1]->dataPtr()->iColour()==PDT::Colour8){
 	if (outgoingVertex1_[inter]->isIncoming(getParticleData(decay[1]->dataPtr()->id()))){
 	  outgoingVertex1 = outgoingVertex2_[inter];
 	  outgoingVertex2 = outgoingVertex1_[inter];
 	}
 	else {
 	  outgoingVertex1 = outgoingVertex1_[inter];
 	  outgoingVertex2 = outgoingVertex2_[inter];
 	}
       }
     }
     else if(inpart.dataPtr()->iColour()==PDT::Colour3bar){
       if(decay[1]->dataPtr()->iColour()==PDT::Colour3bar &&  
 	 decay[0]->dataPtr()->iColour()==PDT::Colour0){
 	if     (outgoingVertex1_[inter]) outgoingVertex2 = outgoingVertex1_[inter];
 	else if(outgoingVertex2_[inter]) outgoingVertex2 = outgoingVertex2_[inter];
       }
       else if (decay[0]->dataPtr()->iColour()==PDT::Colour8 &&
 	       decay[1]->dataPtr()->iColour()==PDT::Colour3bar){
 	if (outgoingVertex1_[inter]->isIncoming(getParticleData(decay[0]->dataPtr()->id()))){
 	  outgoingVertex1 = outgoingVertex1_[inter];
 	  outgoingVertex2 = outgoingVertex2_[inter];
 	}
 	else {
 	  outgoingVertex1 = outgoingVertex2_[inter];
 	  outgoingVertex2 = outgoingVertex1_[inter];
 	}
       }
     }
     
     if (! ((incomingVertex_[inter]  && (outgoingVertex1  || outgoingVertex2)) ||
 	   ( outgoingVertex1 &&  outgoingVertex2)))
       throw Exception()
 	<< "Invalid vertices for QCD radiation in VVV decay in VVVDecayer::identifyVertices"
 	<< Exception::runerror;
   }
   else {
     if(decay[0]->dataPtr()->charged()) {
       if (outgoingVertex1_[inter] &&
 	  outgoingVertex1_[inter]->isIncoming(const_ptr_cast<tPDPtr>(decay[0]->dataPtr())))
 	outgoingVertex1 = outgoingVertex1_[inter];
       else
 	outgoingVertex1 = outgoingVertex2_[inter];
     }
     if(decay[1]->dataPtr()->charged()) {
       if (outgoingVertex1_[inter] &&
 	  outgoingVertex1_[inter]->isIncoming(const_ptr_cast<tPDPtr>(decay[1]->dataPtr())))
 	outgoingVertex2 = outgoingVertex1_[inter];
       else
 	outgoingVertex2 = outgoingVertex2_[inter];
     }
   }
 }
diff --git a/Decay/General/VtoFFVDecayer.cc b/Decay/General/VtoFFVDecayer.cc
--- a/Decay/General/VtoFFVDecayer.cc
+++ b/Decay/General/VtoFFVDecayer.cc
@@ -1,369 +1,371 @@
 // -*- C++ -*-
 //
 // This is the implementation of the non-inlined, non-templated member
 // functions of the VtoFFVDecayer class.
 //
 
 #include "VtoFFVDecayer.h"
 #include "ThePEG/Utilities/DescribeClass.h"
 #include "ThePEG/Interface/ClassDocumentation.h"
 #include "ThePEG/Persistency/PersistentOStream.h"
 #include "ThePEG/Persistency/PersistentIStream.h"
 #include "Herwig/PDT/ThreeBodyAllOnCalculator.h"
 #include "Herwig/Decay/GeneralDecayMatrixElement.h"
 #include <numeric>
 
 using namespace Herwig;
 using namespace ThePEG;
 using namespace ThePEG::Helicity;
 
 IBPtr VtoFFVDecayer::clone() const {
   return new_ptr(*this);
 }
 
 IBPtr VtoFFVDecayer::fullclone() const {
   return new_ptr(*this);
 }
 
 void VtoFFVDecayer::persistentOutput(PersistentOStream & os) const {
   os << sca_ << fer_ << vec_ << ten_;
 }
 
 void VtoFFVDecayer::persistentInput(PersistentIStream & is, int) {
   is >> sca_ >> fer_ >> vec_ >> ten_;
 }
 
 // The following static variable is needed for the type
 // description system in ThePEG.
 DescribeClass<VtoFFVDecayer,GeneralThreeBodyDecayer>
 describeHerwigVtoFFVDecayer("Herwig::VtoFFVDecayer", "Herwig.so");
 
 void VtoFFVDecayer::Init() {
 
   static ClassDocumentation<VtoFFVDecayer> documentation
     ("The VtoFFVDecayer class implements the general three-body "
      "decay of a vector to a two fermions and a vector.");
 
 }
 
 WidthCalculatorBasePtr VtoFFVDecayer::
 threeBodyMEIntegrator(const DecayMode & ) const {
   vector<int> intype;
   vector<Energy> inmass,inwidth;
   vector<double> inpow,inweights;
   constructIntegratorChannels(intype,inmass,inwidth,inpow,inweights);
   return new_ptr(ThreeBodyAllOnCalculator<VtoFFVDecayer>
 		 (inweights,intype,inmass,inwidth,inpow,*this,0,
 		  outgoing()[0]->mass(),outgoing()[1]->mass(),
 		  outgoing()[2]->mass(),relativeError()));
 }
 
 void VtoFFVDecayer::doinit() {
   GeneralThreeBodyDecayer::doinit();
   if(outgoing().empty()) return;
   unsigned int ndiags = getProcessInfo().size();
   sca_.resize(ndiags);
   fer_.resize(ndiags);
   vec_.resize(ndiags);
   ten_.resize(ndiags);
   for(unsigned int ix = 0;ix < ndiags; ++ix) {
     TBDiagram current = getProcessInfo()[ix];
     tcPDPtr offshell = current.intermediate;
     if( offshell->CC() ) offshell = offshell->CC();
     if(offshell->iSpin() == PDT::Spin0) {
       AbstractVVSVertexPtr vert1 = dynamic_ptr_cast<AbstractVVSVertexPtr>
 	(current.vertices.first);
       AbstractFFSVertexPtr vert2 = dynamic_ptr_cast<AbstractFFSVertexPtr>
 	(current.vertices.second);
       if(!vert1||!vert2) throw Exception() 
 	<< "Invalid vertices for a scalar diagram in VtoFFVDecayer::doinit()"
 	<< Exception::runerror;
       sca_[ix] = make_pair(vert1, vert2);
     }
     else if(offshell->iSpin() == PDT::Spin1Half) {
       AbstractFFVVertexPtr vert1 = dynamic_ptr_cast<AbstractFFVVertexPtr>
 	(current.vertices.first);
       AbstractFFVVertexPtr vert2 = dynamic_ptr_cast<AbstractFFVVertexPtr>
 	(current.vertices.second);
       if(!vert1||!vert2) throw Exception() 
 	<< "Invalid vertices for a fermion diagram in VtoFFVDecayer::doinit()"
 	<< Exception::runerror;
       fer_[ix] = make_pair(vert1, vert2);
     }
     else if(offshell->iSpin() == PDT::Spin1) {
       AbstractVVVVertexPtr vert1 = dynamic_ptr_cast<AbstractVVVVertexPtr>
 	(current.vertices.first);
       AbstractFFVVertexPtr vert2 = dynamic_ptr_cast<AbstractFFVVertexPtr>
 	(current.vertices.second);
       if(!vert1||!vert2) throw Exception() 
 	<< "Invalid vertices for a vector diagram in VtoFFVDecayer::doinit()"
 	<< Exception::runerror;
       vec_[ix] = make_pair(vert1, vert2);
     }
     else if(offshell->iSpin() == PDT::Spin2) {
       AbstractVVTVertexPtr vert1 = dynamic_ptr_cast<AbstractVVTVertexPtr>
 	(current.vertices.first);
       AbstractFFTVertexPtr vert2 = dynamic_ptr_cast<AbstractFFTVertexPtr>
 	(current.vertices.second);
       if(!vert1||!vert2) throw Exception() 
 	<< "Invalid vertices for a tensor diagram in VtoFFVDecayer::doinit()"
 	<< Exception::runerror;
       ten_[ix] = make_pair(vert1, vert2);
     }
   }
 }
 
 double VtoFFVDecayer::me2(const int ichan, const Particle & inpart,
 			  const ParticleVector & decay,
 			  MEOption meopt) const {
   // particle or CC of particle
   bool cc = (*getProcessInfo().begin()).incoming != inpart.id();
   // special handling or first/last call
   if(meopt==Initialize) {
     VectorWaveFunction::
       calculateWaveFunctions(inVector_,rho_,const_ptr_cast<tPPtr>(&inpart),
 			     Helicity::incoming,false);
+    // fix rho if no correlations
+    fixRho(rho_);
   }
 
   if(meopt==Terminate) {
     VectorWaveFunction::
       constructSpinInfo(inVector_,const_ptr_cast<tPPtr>(&inpart),
 			Helicity::incoming,true,false);
     for(unsigned int ix=0;ix<decay.size();++ix) {
       if(decay[ix]->dataPtr()->iSpin()==PDT::Spin1) {
 	VectorWaveFunction::constructSpinInfo(outVector_,decay[ix],
 					      Helicity::outgoing,true,false);
       }
       else {
 	SpinorWaveFunction::
 	  constructSpinInfo(outspin_[ix].first,decay[ix],Helicity::outgoing,true);
       }
     }
   }
   unsigned int ivec(0);
   bool massless = false;
   for(unsigned int ix = 0; ix < decay.size();++ix) {
     if(decay[ix]->dataPtr()->iSpin() == PDT::Spin1) {
       massless = decay[ix]->id()==ParticleID::g || decay[ix]->id()==ParticleID::gamma;
       ivec = ix;
       VectorWaveFunction::
 	calculateWaveFunctions(outVector_, decay[ix], Helicity::outgoing, massless );
     }
     else {
       SpinorWaveFunction::
 	calculateWaveFunctions(outspin_[ix].first,decay[ix],Helicity::outgoing);
       outspin_[ix].second.resize(2);
       // Need a ubar and a v spinor
       if(outspin_[ix].first[0].wave().Type() == SpinorType::u) {
 	for(unsigned int iy = 0; iy < 2; ++iy) {
 	  outspin_[ix].second[iy] = outspin_[ix].first[iy].bar();
 	  outspin_[ix].first[iy].conjugate();
 	}
       }
       else {
 	for(unsigned int iy = 0; iy < 2; ++iy) {
 	  outspin_[ix].second[iy] = outspin_[ix].first[iy].bar();
 	  outspin_[ix].second[iy].conjugate();
 	}
       }
     }
   }
   const vector<vector<double> > cfactors(getColourFactors());
   const vector<vector<double> > nfactors(getLargeNcColourFactors());
   Energy2 scale(sqr(inpart.mass()));
   const size_t ncf(numberOfFlows());
   vector<Complex> flows(ncf, Complex(0.)), largeflows(ncf, Complex(0.));
   // setup the DecayMatrixElement
   vector<GeneralDecayMEPtr> 
     mes(ncf,new_ptr(GeneralDecayMatrixElement(PDT::Spin1,
 					      ivec == 0 ? PDT::Spin1 : PDT::Spin1Half,
 					      ivec == 1 ? PDT::Spin1 : PDT::Spin1Half,
 					      ivec == 2 ? PDT::Spin1 : PDT::Spin1Half)));
   vector<GeneralDecayMEPtr> 
     mel(ncf,new_ptr(GeneralDecayMatrixElement(PDT::Spin1,
 					      ivec == 0 ? PDT::Spin1 : PDT::Spin1Half,
 					      ivec == 1 ? PDT::Spin1 : PDT::Spin1Half,
 					      ivec == 2 ? PDT::Spin1 : PDT::Spin1Half)));
   
   //the channel possiblities
   static const unsigned int out2[3] = {1,0,0}, out3[3] = {2,2,1};
   for(unsigned int vi = 0; vi < 3; ++vi) {
     for(unsigned int s1 = 0; s1 < 2; ++s1) {
       for(unsigned int s2 = 0; s2 < 2; ++s2) {
 	for(unsigned int v1 = 0; v1 < 3; ++v1) {
 	  if ( massless && v1 == 1 ) continue; 
 	  flows = vector<Complex>(ncf, Complex(0.));
 	  largeflows = vector<Complex>(ncf, Complex(0.));
 	  unsigned int idiag(0);
 	  for(vector<TBDiagram>::const_iterator dit=getProcessInfo().begin();
 	      dit!=getProcessInfo().end();++dit) {
 	    // channels if selecting
 	    if( ichan >=0 && diagramMap()[ichan] != idiag ) {
 	      ++idiag;
 	      continue;
 	    }
 	    tcPDPtr offshell = dit->intermediate;
 	    if(cc&&offshell->CC()) offshell=offshell->CC();
 	    Complex diag;
 	    unsigned int o2(out2[dit->channelType]), o3(out3[dit->channelType]);
 	    double sign = (o3 < o2) ? 1. : -1.;
 	    // intermediate scalar
 	    if(offshell->iSpin() == PDT::Spin0) {
 	      ScalarWaveFunction inters = sca_[idiag].first->
 		evaluate(scale, widthOption(), offshell, outVector_[v1], 
 			 inVector_[vi]);
 	      unsigned int h1(s1),h2(s2);
 	      if(o2 > o3) swap(h1, h2);
 	      if(decay[o2]->id() < 0 &&  decay[o3]->id() > 0) {
 		diag = -sign*sca_[idiag].second->
 		  evaluate(scale,outspin_[o2].first[h1],
 			   outspin_[o3].second[h2],inters);
 	      }
 	      else {
 		diag = sign*sca_[idiag].second->
 		  evaluate(scale, outspin_[o3].first [h2],
 			   outspin_[o2].second[h1],inters);
 	      }
 	    }
 	    // intermediate fermion
 	    else if(offshell->iSpin() == PDT::Spin1Half) {
 	      int iferm = (decay[o2]->dataPtr()->iSpin() == PDT::Spin1Half) 
 		? o2 : o3;
 	      unsigned int h1(s1),h2(s2);
 	      if(dit->channelType > iferm) swap(h1, h2);
 	      sign = iferm < dit->channelType ? 1. : -1.;
 	      if(decay[dit->channelType]->id() < 0 && decay[iferm]->id() > 0 ) {
 		SpinorWaveFunction inters = fer_[idiag].first->
 		  evaluate(scale,widthOption(),offshell,
 			   outspin_[dit->channelType].first[h1], inVector_[vi]);
 		diag = -sign*fer_[idiag].second->
 		  evaluate(scale,inters,outspin_[iferm].second[h2], outVector_[v1]);
 	      }
 	      else {
 		SpinorBarWaveFunction inters = fer_[idiag].first->
 		  evaluate(scale,widthOption(),offshell,
 			   outspin_[dit->channelType].second[h1],inVector_[vi]);
 		diag =  sign*fer_[idiag].second->
 		  evaluate(scale,outspin_[iferm].first [h2],inters, outVector_[v1]);
 	      }
 	    }
 	    // intermediate vector
 	    else if(offshell->iSpin() == PDT::Spin1) {
 	      VectorWaveFunction interv = vec_[idiag].first->
 		evaluate(scale, widthOption(), offshell, outVector_[v1], 
 			 inVector_[vi]);
 	      unsigned int h1(s1),h2(s2);
 	      if(o2 > o3) swap(h1,h2);
 	      if(decay[o2]->id() < 0 && decay[o3]->id() > 0) {
 		diag =-sign*vec_[idiag].second->
 		  evaluate(scale, outspin_[o2].first[h1],
 			   outspin_[o3].second[h2], interv);
 	      }
 	      else {
 		diag = sign*vec_[idiag].second->
 		  evaluate(scale, outspin_[o3].first[h2],
 			   outspin_[o2].second[h1], interv);
 	      }
 	    }
 	    else if(offshell->iSpin() == PDT::Spin2) {
 	      TensorWaveFunction intert = ten_[idiag].first->
 		evaluate(scale, widthOption(), offshell, inVector_[vi], 
 			 outVector_[v1]);
 	      unsigned int h1(s1),h2(s2);
 	      if(out2[dit->channelType]>out3[dit->channelType]) swap(h1,h2);
 	      if(decay[out2[dit->channelType]]->id()<0&&
 		 decay[out3[dit->channelType]]->id()>0) {
 		diag =-sign*ten_[idiag].second->
 		  evaluate(scale,
 			   outspin_[out2[dit->channelType]].first [h1],
 			   outspin_[out3[dit->channelType]].second[h2],intert);
 	      }
 	      else {
 		diag = sign*ten_[idiag].second->
 		  evaluate(scale,
 			   outspin_[out3[dit->channelType]].first [h2],
 			   outspin_[out2[dit->channelType]].second[h1],intert);
 	      }
 	    }
 	    // unknown
 	    else throw Exception()
 	      << "Unknown intermediate in VtoFFVDecayer::me2()" 
 	      << Exception::runerror;
 	    
 	    // matrix element for the different colour flows
 	    if(ichan < 0) {
 	      for(unsigned iy = 0; iy < dit->colourFlow.size(); ++iy) {
 		flows[dit->colourFlow[iy].first - 1] += 
 		  dit->colourFlow[iy].second * diag;
 	      }
 	      for(unsigned iy = 0; iy < dit->largeNcColourFlow.size(); ++iy) {
 		largeflows[dit->largeNcColourFlow[iy].first - 1] += 
 		  dit->largeNcColourFlow[iy].second * diag;
 	      }
 	    }
 	    else {
 	      for(unsigned iy = 0; iy < dit->colourFlow.size(); ++iy) {
 		if(dit->colourFlow[iy].first - 1 != colourFlow()) continue;
 		flows[dit->colourFlow[iy].first - 1] += 
 		  dit->colourFlow[iy].second * diag;
 	      }
 	      for(unsigned iy = 0; iy < dit->largeNcColourFlow.size(); ++iy) {
 		if(dit->colourFlow[iy].first - 1!=colourFlow()) continue;
 		largeflows[dit->largeNcColourFlow[iy].first - 1] += 
 		  dit->largeNcColourFlow[iy].second * diag;
 	      }
 	    }	    
 	    ++idiag;
 	  } //end of diagrams
 	  // now add the flows to the me2 with appropriate colour factors
 	  for(unsigned int ix = 0; ix < ncf; ++ix) {
 	    if (ivec == 0) {
 	      (*mes[ix])(vi, v1, s1, s2) = flows[ix];
 	      (*mel[ix])(vi, v1, s1, s2) = largeflows[ix];
 	    }
 	    else if(ivec == 1) {
 	      (*mes[ix])(vi, s1, v1, s2) = flows[ix];
 	      (*mel[ix])(vi, s1, v1, s2) = largeflows[ix];
 	      
 	    }
 	    else if(ivec == 2) { 
 	      (*mes[ix])(vi, s1, s2, v1) = flows[ix];
 	      (*mel[ix])(vi, s1, s2, v1) = largeflows[ix];
 	    }
 	  }
 
 	}
       }
     }
   }
   double me2(0.);
   if(ichan < 0) {
     vector<double> pflows(ncf,0.);
     for(unsigned int ix = 0; ix < ncf; ++ix) {
       for(unsigned int iy = 0; iy < ncf; ++ iy) {
 	double con = cfactors[ix][iy]*(mes[ix]->contract(*mes[iy],rho_)).real();
 	me2 += con;
 	if(ix == iy) {
 	  con = nfactors[ix][iy]*(mel[ix]->contract(*mel[iy],rho_)).real();
 	  pflows[ix] += con;
 	}
       }
     }
     double ptotal(std::accumulate(pflows.begin(),pflows.end(),0.));
     ptotal *= UseRandom::rnd();
     for(unsigned int ix = 0;ix < pflows.size(); ++ix) {
       if(ptotal <= pflows[ix]) {
 	colourFlow(ix);
 	ME(mes[ix]);
 	break;
       }
       ptotal -= pflows[ix];
     }
   }
   else {
     unsigned int iflow = colourFlow();
     me2 = nfactors[iflow][iflow]*(mel[iflow]->contract(*mel[iflow],rho_)).real();
   }
   // return the matrix element squared
   return me2;
 }
diff --git a/Decay/HwDecayerBase.cc b/Decay/HwDecayerBase.cc
--- a/Decay/HwDecayerBase.cc
+++ b/Decay/HwDecayerBase.cc
@@ -1,156 +1,163 @@
 // -*- C++ -*-
 //
 // HwDecayerBase.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 HwDecayerBase class.
 //
 
 #include "HwDecayerBase.h"
 #include "ThePEG/Utilities/DescribeClass.h"
 #include "ThePEG/Interface/ClassDocumentation.h"
 #include "ThePEG/PDT/DecayMode.h"
 #include "ThePEG/Interface/Switch.h"
 #include "ThePEG/Persistency/PersistentOStream.h"
 #include "ThePEG/Persistency/PersistentIStream.h"
 #include "ThePEG/Repository/CurrentGenerator.h"
 #include "Herwig/Shower/RealEmissionProcess.h"
+#include "Herwig/Shower/ShowerHandler.h"
 
 using namespace Herwig;
 
 bool HwDecayerBase::accept(const DecayMode & dm) const {
   // get the primary products
   tPDVector products=dm.orderedProducts();
   // add products for which the decay mode is all ready specified
   if(!dm.cascadeProducts().empty()) {
     for(ModeMSet::const_iterator mit=dm.cascadeProducts().begin();
 	mit!=dm.cascadeProducts().end();++mit) {
       products.push_back(const_ptr_cast<PDPtr>((**mit).parent()));
     }
   }
   // can this mode be handled ?
   return accept(dm.parent(),products);
 }
 
 ParticleVector HwDecayerBase::decay(const DecayMode & dm,
 				    const Particle & p) const {
   // handling of the decay including the special features of the
   // DecayMode  
   // get the primary products
   tPDVector products=dm.orderedProducts();
   // add products for which the decay mode is all ready specified
   if(!dm.cascadeProducts().empty()) {
     for(ModeMSet::const_iterator mit=dm.cascadeProducts().begin();
 	mit!=dm.cascadeProducts().end();++mit) {
       products.push_back(const_ptr_cast<PDPtr>((**mit).parent()));
     }
   }
   // perform the primary decay
   ParticleVector output=decay(p,products);
   // perform the secondary decays
   if(!dm.cascadeProducts().empty()) {
     unsigned int iloc=dm.orderedProducts().size();
     for(ModeMSet::const_iterator mit=dm.cascadeProducts().begin();
 	mit!=dm.cascadeProducts().end();++mit) {
       if(!(*mit)->decayer()) 
 	throw Exception() << "Decay mode " << (**mit).tag() 
 			  << "does not have a decayer, can't perform"
 			  << "decay in  HwDecayerBase::decay()"
 			  << Exception::eventerror;
       ParticleVector children=(*mit)->decayer()->decay(**mit,*output[iloc]);
       for(unsigned int ix=0;ix<children.size();++ix) {
 	output[iloc]->addChild(children[ix]);
       }
       ++iloc;
     }
   }
   return output;
 }
 
 void HwDecayerBase::persistentOutput(PersistentOStream & os) const {
   os << _initialize << _dbOutput;
 }
 
 void HwDecayerBase::persistentInput(PersistentIStream & is, int) {
   is >> _initialize >> _dbOutput;
 }
 
 // The following static variable is needed for the type
 // description system in ThePEG.
 DescribeAbstractClass<HwDecayerBase,Decayer>
 describeHerwigHwDecayerBase("Herwig::HwDecayerBase", "Herwig.so");
 
 void HwDecayerBase::Init() {
 
   static ClassDocumentation<HwDecayerBase> documentation
     ("The HwDecayerBase class is the base class for Decayers in Hw++.");
 
   static Switch<HwDecayerBase,bool> interfaceInitialize
     ("Initialize",
      "Initialization of the phase space calculation",
      &HwDecayerBase::_initialize, false, false, false);
   static SwitchOption interfaceInitializeon
     (interfaceInitialize,
      "Yes",
      "At initialisation find max weight and optimise the integration",
      true);
   static SwitchOption interfaceInitializeoff
     (interfaceInitialize,
      "No",
      "Use the maximum weight and channel weights supplied for the integration",
      false);
 
   static Switch<HwDecayerBase,bool> interfaceDatabaseOutput
     ("DatabaseOutput",
      "Whether to print the database information",
      &HwDecayerBase::_dbOutput, false, false, false);
   static SwitchOption interfaceDatabaseOutputYes
     (interfaceDatabaseOutput,
      "Yes",
      "Output information on the decayer initialization",
      true);
   static SwitchOption interfaceDatabaseOutputNo
     (interfaceDatabaseOutput,
      "No",
      "Do not output information about the decayer initialization",
      false);
 }
 
 void HwDecayerBase::dofinish() {
   Decayer::dofinish();
   if(initialize() && databaseOutput()) {
     string fname = CurrentGenerator::current().filename() + 
       string("-") + name() + string(".output");
     ofstream output(fname.c_str());
     dataBaseOutput(output,true);
   }
 }
 
 bool HwDecayerBase::softMatrixElementVeto(PPtr , PPtr,
 					  const bool &,
 					  const Energy & ,
 					  const vector<tcPDPtr> & ,
 					  const double & ,
 					  const Energy & ,
 					  const Energy & ) {
   return false;
 }
 
 RealEmissionProcessPtr HwDecayerBase::generateHardest(RealEmissionProcessPtr) {
   return RealEmissionProcessPtr();
 }
 
 void HwDecayerBase::initializeMECorrection(RealEmissionProcessPtr , double & ,
 			    double & ) {
   assert(false);
 }
 
 RealEmissionProcessPtr HwDecayerBase::applyHardMatrixElementCorrection(RealEmissionProcessPtr) {
   assert(false);
   return RealEmissionProcessPtr();
 }
+
+void HwDecayerBase::fixRho(RhoDMatrix & rho) const {
+  if(ShowerHandler::currentHandlerIsSet() &&
+     !ShowerHandler::currentHandler()->spinCorrelations())
+    rho.reset();
+}
diff --git a/Decay/HwDecayerBase.h b/Decay/HwDecayerBase.h
--- a/Decay/HwDecayerBase.h
+++ b/Decay/HwDecayerBase.h
@@ -1,237 +1,244 @@
 // -*- C++ -*-
 //
 // HwDecayerBase.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_HwDecayerBase_H
 #define HERWIG_HwDecayerBase_H
 //
 // This is the declaration of the HwDecayerBase class.
 //
 
 #include "ThePEG/PDT/Decayer.h"
 #include "Herwig/Shower/RealEmissionProcess.fh"
 #include "HwDecayerBase.fh"
 
 namespace Herwig {
 
 struct Branching;
 
 using namespace ThePEG;
 
 /**
  * The HwDecayerBase class is the base class for Decayers in Herwig. It inherits
  * from the Decayer class of ThePEG and implements additional functionality for the 
  * output of the results to the particle database and initialization of the datbase.
  *
  * It also provide the option of specifying a class based on the DecayRadiationGenerator
  * which should be used to generate QED radiation in the decay
  *
  * @see \ref HwDecayerBaseInterfaces "The interfaces"
  * defined for HwDecayerBase.
 
  */
 class HwDecayerBase: public Decayer {
 
 public:
 
   /**
    * The default constructor.
    */
   HwDecayerBase() : _initialize(false), _dbOutput(false) {}
 
   /** @name Virtual functions required by the Decayer class. */
   //@{
   /**
    * Check if this decayer can perfom the decay specified by the
    * given decay mode.
    * @param dm the DecayMode describing the decay.
    * @return true if this decayer can handle the given mode, otherwise false.
    */
   virtual bool accept(const DecayMode & dm) const;
 
   /**
    * Perform a decay for a given DecayMode and a given Particle instance.
    * @param dm the DecayMode describing the decay.
    * @param p the Particle instance to be decayed.
    * @return a ParticleVector containing the decay products.
    */
   virtual ParticleVector decay(const DecayMode & dm, const Particle & p) const;
   //@}
 
 public:
 
   /**
    *  Virtual members to be overridden by inheriting classes
    *  which implement hard corrections 
    */
   //@{
   
   /**
    * Type of POWHEG correction
    */
   enum POWHEGType {No, ISR, FSR, Both};
 
 
   /**
    *  Has a POWHEG style correction
    */
   virtual POWHEGType hasPOWHEGCorrection() {return No;}
 
 
   /**
    *  Has an old fashioned ME correction
    */
   virtual bool hasMECorrection() {return false;}
 
   /**
    *  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 parent The initial particle in the current branching
    * @param progenitor The progenitor particle of the jet
    * @param fs Whether the emission is initial or final-state
    * @param highestpT The highest pT so far in the shower
    * @param ids ids of the particles produced in the branching
    * @param z The momentum fraction of the branching
    * @param scale the evolution scale of the branching
    * @param pT The transverse momentum of the branching
    * @return If true the emission should be vetoed
    */
   virtual bool softMatrixElementVeto(PPtr parent,
 				     PPtr progenitor,
 				     const bool & fs,
 				     const Energy & highestpT,
 				     const vector<tcPDPtr> & ids,
 				     const double & z,
 				     const Energy & scale,
 				     const Energy & pT);
 
   /**
    *  Apply the POWHEG style correction
    */
   virtual RealEmissionProcessPtr generateHardest(RealEmissionProcessPtr);
   //@}
 
 protected:
 
   /** @name Virtual functions to replaced those from the Decayer class. 
    *  This is so that the decay and accept members of this class can handle all
    *  the more complicated features of the DecayMode class
    */
   //@{
   /**
    * Check if this decayer can perfom the decay for a particular mode
    * @param parent The decaying particle
    * @param children The decay products
    * @return true If this decayer can handle the given mode, otherwise false.
    */
   virtual bool accept(tcPDPtr parent, const tPDVector & children) const = 0;
   
   /**
    *  Perform the decay of the particle to the specified decay products
    * @param parent The decaying particle
    * @param children The decay products
    * @return a ParticleVector containing the decay products.
    */
   virtual ParticleVector decay(const Particle & parent,
 			       const tPDVector & children) const = 0;
   //@}
 
 public:
 
   /** @name Functions used by the persistent I/O system. */
   //@{
   /**
    * Function used to write out object persistently.
    * @param os the persistent output stream written to.
    */
   void persistentOutput(PersistentOStream & os) const;
 
   /**
    * Function used to read in object persistently.
    * @param is the persistent input stream read from.
    * @param version the version number of the object when written.
    */
   void persistentInput(PersistentIStream & is, int version);
   //@}
 
   /**
    * The standard Init function used to initialize the interfaces.
    * Called exactly once for each class by the class description system
    * before the main function starts or
    * when this class is dynamically loaded.
    */
   static void Init();
 
 public:
 
   /**
    *  Functions for the Herwig decayer
    */
   //@{
   /**
    * 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 = 0;
 
   /**
    *  Access to the initialize variable
    */
   bool initialize() const {return _initialize;}
 
   /**
    *  Access the database output variable
    */
   bool databaseOutput() const {return _dbOutput;}
   //@}
 
 protected:
 
+  /**
+   * Set rho to be diagonal if no correlations
+   */
+  void fixRho(RhoDMatrix &) const;
+  
+protected:
+
   /** @name Standard Interfaced functions. */
   //@{
   /**
    * Finalize this object. Called in the run phase just after a
    * run has ended. Used eg. to write out statistics.
    */
   virtual void dofinish();
   //@}
 
 private:
 
   /**
    * The assignment operator is private and must never be called.
    * In fact, it should not even be implemented.
    */
   HwDecayerBase & operator=(const HwDecayerBase &);
 
 private:
 
   /**
    * perform initialisation
    */
   bool _initialize;
 
   /**
    * Print out database  
    */
   bool _dbOutput;
 };
 
 }
 
 #endif /* HERWIG_HwDecayerBase_H */
diff --git a/Decay/Perturbative/SMHiggsFermionsDecayer.cc b/Decay/Perturbative/SMHiggsFermionsDecayer.cc
--- a/Decay/Perturbative/SMHiggsFermionsDecayer.cc
+++ b/Decay/Perturbative/SMHiggsFermionsDecayer.cc
@@ -1,393 +1,395 @@
 // -*- C++ -*-
 //
 // SMHiggsFermionsDecayer.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 SMHiggsFermionsDecayer class.
 //
 
 #include "SMHiggsFermionsDecayer.h"
 #include "ThePEG/Utilities/DescribeClass.h"
 #include "ThePEG/Interface/ClassDocumentation.h"
 #include "ThePEG/Interface/ParVector.h"
 #include "ThePEG/Interface/Reference.h"
 #include "ThePEG/Interface/Switch.h"
 #include "ThePEG/Persistency/PersistentOStream.h"
 #include "ThePEG/Persistency/PersistentIStream.h"
 #include "ThePEG/PDT/DecayMode.h"
 #include "Herwig/Decay/DecayVertex.h"
 #include "ThePEG/Helicity/ScalarSpinInfo.h"
 #include "ThePEG/Helicity/FermionSpinInfo.h"
 #include "ThePEG/Helicity/WaveFunction/ScalarWaveFunction.h"
 #include "Herwig/Models/StandardModel/StandardModel.h"
 #include "Herwig/Decay/GeneralDecayMatrixElement.h"
 #include "Herwig/Utilities/Maths.h"
 #include "Herwig/Shower/RealEmissionProcess.h"
 #include "Herwig/Shower/ShowerAlpha.h"
 
 using namespace Herwig;
 using namespace ThePEG::Helicity;
 
 SMHiggsFermionsDecayer::SMHiggsFermionsDecayer() :
   CF_(4./3.), NLO_(false) {
   _maxwgt.resize(9);
   _maxwgt[0]=0.;
   _maxwgt[1]=0;		
   _maxwgt[2]=0;		
   _maxwgt[3]=0.0194397;	
   _maxwgt[4]=0.463542;	
   _maxwgt[5]=0.;		
   _maxwgt[6]=6.7048e-09; 
   _maxwgt[7]=0.00028665; 
   _maxwgt[8]=0.0809643;  
 }
 
 void SMHiggsFermionsDecayer::doinit() {
   PerturbativeDecayer::doinit();
   // get the vertices from the Standard Model object
   tcHwSMPtr hwsm=dynamic_ptr_cast<tcHwSMPtr>(standardModel());
   if(!hwsm)
     throw InitException() << "SMHiggsFermionsDecayer needs the StandardModel class"
 			  << " to be either the Herwig one or a class inheriting"
 			  << " from it";
   _hvertex = hwsm->vertexFFH();
   // make sure they are initialized
   _hvertex->init();
   // get the width generator for the higgs
   tPDPtr higgs = getParticleData(ParticleID::h0);
   // set up the decay modes
   vector<double> wgt(0);
   unsigned int imode=0;
   tPDVector extpart(3);
   DecayPhaseSpaceModePtr mode;
   int iy;
   extpart[0]=higgs;
   for(unsigned int istep=0;istep<11;istep+=10) {
     for(unsigned ix=1;ix<7;++ix) {
       if(istep<10||ix%2!=0) {
 	iy = ix+istep;
 	extpart[1]=getParticleData( iy);
 	extpart[2]=getParticleData(-iy);
 	mode = new_ptr(DecayPhaseSpaceMode(extpart,this));
 	addMode(mode,_maxwgt[imode],wgt);
 	++imode;
       }
     }
   }
 //   Energy quarkMass = getParticleData(ParticleID::b )->mass();
 //   Energy higgsMass = getParticleData(ParticleID::h0)->mass();
 //   double mu = quarkMass/higgsMass;
 //   double beta = sqrt(1.-4.*sqr(mu));
 //   double beta2 = sqr(beta);
 //   double aS = SM().alphaS(sqr(higgsMass));
 //   double L = log((1.+beta)/(1.-beta));
 //   cerr << "testing " << beta << " " << mu << "\n";
 //   cerr << "testing " << aS << " " << L << "\n";
 //   double fact = 
 //     6.-0.75*(1.+beta2)/beta2+12.*log(mu)-8.*log(beta)
 //     +(5./beta-2.*beta+0.375*sqr(1.-beta2)/beta2/beta)*L
 //     +(1.+beta2)/beta*(4.*L*log(0.5*(1.+beta)/beta)
 // 		      -2.*log(0.5*(1.+beta))*log(0.5*(1.-beta))
 // 		      +8.*Herwig::Math::ReLi2((1.-beta)/(1.+beta))
 // 		      -4.*Herwig::Math::ReLi2(0.5*(1.-beta)));
 //   cerr << "testing correction " 
 //        << 1.+4./3.*aS/Constants::twopi*fact
 //        << "\n"; 
 //   double real = 4./3.*aS/Constants::twopi*
 //     (8.-0.75*(1.+beta2)/beta2+8.*log(mu)-8.*log(beta)
 //      +(3./beta+0.375*sqr(1.-beta2)/pow(beta,3))*L
 //      +(1.+beta2)/beta*(-0.5*sqr(L)+4.*L*log(0.5*(1.+beta))
 // 		       -2.*L*log(beta)-2.*log(0.5*(1.+beta))*log(0.5*(1.-beta))
 // 		       +6.*Herwig::Math::ReLi2((1.-beta)/(1.+beta))
 // 		       -4.*Herwig::Math::ReLi2(0.5*(1.-beta))
 // 		       -2./3.*sqr(Constants::pi)));
 //   double virt = 4./3.*aS/Constants::twopi*
 //     (-2.+4.*log(mu)+(2./beta-2.*beta)*L
 //      +(1.+beta2)/beta*(0.5*sqr(L)-2.*L*log(beta)+2.*sqr(Constants::pi)/3.
 // 		       +2.*Herwig::Math::ReLi2((1.-beta)/(1.+beta))));
 //   cerr << "testing real " << real << "\n";
 //   cerr << "testing virtual " << virt << "\n";
 //   cerr << "testing total no mb corr " << 1.+real+virt << "\n";
 //   cerr << "testing total    mb corr " << 1.+real+virt +(8./3. - 2.*log(sqr(mu)))*aS/Constants::pi << "\n";
 //   InvEnergy2 Gf = 1.166371e-5/GeV2;
 //   Gf = sqrt(2.)*4*Constants::pi*SM().alphaEM(sqr(higgsMass))/8./SM().sin2ThetaW()/
 //     sqr(getParticleData(ParticleID::Wplus)->mass());
 //   cerr << "testing GF " << Gf*GeV2 << "\n";
 //   Energy LO = (3./8./Constants::pi)*sqrt(2)*sqr(quarkMass)*Gf*higgsMass*beta*beta*beta;
 //   cerr << "testing LO " << LO/GeV << "\n";
 //   cerr << "testing quark mass " << quarkMass/GeV << "\n";
 //   cerr << "testing gamma " << (1.+real+virt)*LO/MeV << "\n";
 }
   
 bool SMHiggsFermionsDecayer::accept(tcPDPtr parent, const tPDVector & children) const {
   if(parent->id()!=ParticleID::h0||children.size()!=2) return false;
   tPDVector::const_iterator pit = children.begin();
   int id1=(**pit).id();
   ++pit;
   int id2=(**pit).id();
   if(id1==-id2&&(abs(id1)<=6||(abs(id1)>=11&&abs(id1)<=16)))
     return true;
   else
     return false;
 }
 
 ParticleVector SMHiggsFermionsDecayer::decay(const Particle & parent,
 					     const tPDVector & children) const {
   // id's of the decaying particles
   tPDVector::const_iterator pit(children.begin());
   int id1((**pit).id());
   int imode=-1;
   if(abs(id1)<=6)                     imode = abs(id1)-1;
   else if(abs(id1)>=11&&abs(id1)<=16) imode = (abs(id1)-11)/2+6;
   ParticleVector output(generate(false,false,imode,parent));
   // set up the colour flow
   if(output[0]->hasColour())      output[0]->antiColourNeighbour(output[1]);
   else if(output[1]->hasColour()) output[1]->antiColourNeighbour(output[0]);
   return output;
 }
 
 
 void SMHiggsFermionsDecayer::persistentOutput(PersistentOStream & os) const {
   os << _maxwgt << _hvertex << NLO_;
 }
 
 void SMHiggsFermionsDecayer::persistentInput(PersistentIStream & is, int) {
   is >> _maxwgt >> _hvertex >> NLO_;
 }
 
 // The following static variable is needed for the type
 // description system in ThePEG.
 DescribeClass<SMHiggsFermionsDecayer,PerturbativeDecayer>
 describeHerwigSMHiggsFermionsDecayer("Herwig::SMHiggsFermionsDecayer", "HwPerturbativeHiggsDecay.so");
 
 void SMHiggsFermionsDecayer::Init() {
 
   static ClassDocumentation<SMHiggsFermionsDecayer> documentation
     ("The SMHiggsFermionsDecayer class implements the decat of the Standard Model"
      " Higgs boson to the Standard Model fermions");
 
   static ParVector<SMHiggsFermionsDecayer,double> interfaceMaxWeights
     ("MaxWeights",
      "Maximum weights for the various decays",
      &SMHiggsFermionsDecayer::_maxwgt, 9, 1.0, 0.0, 10.0,
      false, false, Interface::limited);
   
   static Switch<SMHiggsFermionsDecayer,bool> interfaceNLO
     ("NLO",
      "Whether to return the LO or NLO result",
      &SMHiggsFermionsDecayer::NLO_, false, false, false);
   static SwitchOption interfaceNLOLO
     (interfaceNLO,
      "No",
      "Leading-order result",
      false);
   static SwitchOption interfaceNLONLO
     (interfaceNLO,
      "Yes",
      "NLO result",
      true);
 
 }
 
 // return the matrix element squared
 double SMHiggsFermionsDecayer::me2(const int, const Particle & part,
 				   const ParticleVector & decay,
 				   MEOption meopt) const {
   if(!ME())
     ME(new_ptr(GeneralDecayMatrixElement(PDT::Spin0,PDT::Spin1Half,PDT::Spin1Half)));
   int iferm(1),ianti(0);
   if(decay[0]->id()>0) swap(iferm,ianti);
   if(meopt==Initialize) {
     ScalarWaveFunction::
       calculateWaveFunctions(_rho,const_ptr_cast<tPPtr>(&part),incoming);
     _swave = ScalarWaveFunction(part.momentum(),part.dataPtr(),incoming);
+    // fix rho if no correlations
+    fixRho(_rho);
   }
   if(meopt==Terminate) {
     ScalarWaveFunction::constructSpinInfo(const_ptr_cast<tPPtr>(&part),
 					  incoming,true);
     SpinorBarWaveFunction::
       constructSpinInfo(_wavebar,decay[iferm],outgoing,true);
     SpinorWaveFunction::
       constructSpinInfo(_wave   ,decay[ianti],outgoing,true);
     return 0.;
   }
   SpinorBarWaveFunction::
     calculateWaveFunctions(_wavebar,decay[iferm],outgoing);
   SpinorWaveFunction::
     calculateWaveFunctions(_wave   ,decay[ianti],outgoing);
   Energy2 scale(sqr(part.mass()));
   unsigned int ifm,ia;
   for(ifm=0;ifm<2;++ifm) {
     for(ia=0;ia<2;++ia) {
       if(iferm>ianti)
 	(*ME())(0,ia,ifm)=_hvertex->evaluate(scale,_wave[ia],
 					  _wavebar[ifm],_swave);
       else
 	(*ME())(0,ifm,ia)=_hvertex->evaluate(scale,_wave[ia],
 					  _wavebar[ifm],_swave);
     }
   }
   int id = abs(decay[0]->id());
   double output=(ME()->contract(_rho)).real()*UnitRemoval::E2/scale;
   if(id <=6) output*=3.;
   // test of the partial width
 //   Ptr<Herwig::StandardModel>::transient_const_pointer 
 //     hwsm=dynamic_ptr_cast<Ptr<Herwig::StandardModel>::transient_const_pointer>(standardModel());
 //   double g2(hwsm->alphaEM(scale)*4.*Constants::pi/hwsm->sin2ThetaW());
 //   Energy mass(hwsm->mass(scale,decay[0]->dataPtr())),
 //     mw(getParticleData(ParticleID::Wplus)->mass());
 //   double beta(sqrt(1.-4.*decay[0]->mass()*decay[0]->mass()/scale));
 //   cerr << "testing alpha " << hwsm->alphaEM(scale) << "\n";
 //   Energy test(g2*mass*mass*beta*beta*beta*part.mass()/32./Constants::pi/mw/mw);
 //   if(abs(decay[0]->id())<=6){test *=3.;}
 //   cout << "testing the answer " << output << "     " 
 //        << test/GeV
 //        << endl;
   // leading-order result
   if(!NLO_) return output;
   // fermion mass
   Energy particleMass = decay[0]->dataPtr()->mass();
   // check decay products coloured, otherwise return
   if(!decay[0]->dataPtr()->coloured()||
      particleMass==ZERO) return output;
   // inital masses, couplings  etc
   // higgs mass
   mHiggs_ = part.mass();
   // strong coupling
   aS_ = SM().alphaS(sqr(mHiggs_));
   // reduced mass
   mu_  = particleMass/mHiggs_;
   mu2_ = sqr(mu_);
   // generate y
   double yminus = 0.; 
   double yplus  = 1.-2.*mu_*(1.-mu_)/(1.-2*mu2_);
   double y = yminus + UseRandom::rnd()*(yplus-yminus);
   //generate z for D31,2
   double v  = sqrt(sqr(2.*mu2_+(1.-2.*mu2_)*(1.-y))-4.*mu2_)/(1.-2.*mu2_)/(1.-y);
   double zplus  = (1.+v)*(1.-2.*mu2_)*y/2./(mu2_ +(1.-2.*mu2_)*y);
   double zminus = (1.-v)*(1.-2.*mu2_)*y/2./(mu2_ +(1.-2.*mu2_)*y);
   double z = zminus + UseRandom::rnd()*(zplus-zminus);
   // map y,z to x1,x2 for both possible emissions
   double x2 = 1. - y*(1.-2.*mu2_);
   double x1 = 1. - z*(x2-2.*mu2_);
   //get the dipoles
   InvEnergy2 D1 = dipoleSubtractionTerm( x1, x2); 
   InvEnergy2 D2 = dipoleSubtractionTerm( x2, x1); 
   InvEnergy2 dipoleSum = abs(D1) + abs(D2);
   //jacobian
   double jac = (1.-y)*(yplus-yminus)*(zplus-zminus);
   //calculate real
   Energy2 realPrefactor = 0.25*sqr(mHiggs_)*sqr(1.-2.*mu2_)
     /sqrt(calculateLambda(1,mu2_,mu2_))/sqr(Constants::twopi);
   InvEnergy2 realEmission = 4.*Constants::pi*aS_*CF_*calculateRealEmission( x1, x2);
   // calculate the virtual
   double virtualTerm = calculateVirtualTerm();
   // running mass correction
   virtualTerm += (8./3. - 2.*log(mu2_))*aS_/Constants::pi;
   //answer = (born + virtual + real)/born * LO
   output *= 1. + virtualTerm + 2.*jac*realPrefactor*(realEmission*abs(D1)/dipoleSum  - D1);
   // return the answer
   return output;
 }
 
 void SMHiggsFermionsDecayer::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<_maxwgt.size();++ix) {
     os << "newdef " << name() << ":MaxWeights " << ix << " "
 	   << _maxwgt[ix] << "\n";
   }
   PerturbativeDecayer::dataBaseOutput(os,false);
   if(header) os << "\n\" where BINARY ThePEGName=\"" 
 		<< fullName() << "\";" << endl;
 }
 
 void SMHiggsFermionsDecayer::doinitrun() {
   PerturbativeDecayer::doinitrun();
   if(initialize()) {
     for(unsigned int ix=0;ix<numberModes();++ix) {
       _maxwgt[ix] = mode(ix)->maxWeight();
     }
   }
 }
 
 
 //calculate lambda
 double SMHiggsFermionsDecayer::calculateLambda(double x, double y, double z) const{
   return sqr(x)+sqr(y)+sqr(z)-2.*x*y-2.*x*z-2.*y*z;
 }
 
 //calculates the dipole subtraction term for x1, D31,2 (Dij,k),
 // 2 is the spectator anti-fermion and 3 is the gluon
 InvEnergy2 SMHiggsFermionsDecayer::
 dipoleSubtractionTerm(double x1, double x2) const{
   InvEnergy2 commonPrefactor = CF_*8.*Constants::pi*aS_/sqr(mHiggs_);
   return commonPrefactor/(1.-x2)*
     (2.*(1.-2.*mu2_)/(2.-x1-x2)- 
      sqrt((1.-4.*mu2_)/(sqr(x2)-4.*mu2_))*
      (x2-2.*mu2_)*(2.+(x1-1.)/(x2-2.*mu2_)+2.*mu2_/(1.-x2))/(1.-2.*mu2_));
 }
 
 //return ME for real emission
 InvEnergy2 SMHiggsFermionsDecayer::
 calculateRealEmission(double x1, double x2) const {
   InvEnergy2 prefactor = 2./sqr(mHiggs_)/(1.-4.*mu2_);
   return prefactor*(2. + (1.-x1)/(1.-x2) + (1.-x2)/(1.-x1) 
                     + 2.*(1.-2.*mu2_)*(1.-4.*mu2_)/(1.-x1)/(1.-x2)
                     - 2.*(1.-4.*mu2_)*(1./(1.-x2)+1./(1.-x1)) 
                     - 2.*mu2_*(1.-4.*mu2_)*(1./sqr(1.-x2)+1./sqr(1.-x1)));
 }
 
 double SMHiggsFermionsDecayer::
 calculateVirtualTerm() const {
   // logs and prefactors
   double beta = sqrt(1.-4.*mu2_);
   double L = log((1.+beta)/(1.-beta));
   double prefactor = CF_*aS_/Constants::twopi;
   // non-singlet piece
   double nonSingletTerm = calculateNonSingletTerm(beta, L);
   double virtualTerm = 
     -2.+4.*log(mu_)+(2./beta - 2.*beta)*L 
     + (2.-4.*mu2_)/beta*(0.5*sqr(L) - 2.*L*log(beta)
 			 + 2.*Herwig::Math::ReLi2((1.-beta)/(1.+beta)) 
 			 + 2.*sqr(Constants::pi)/3.);
   double iEpsilonTerm = 
     2.*(3.-sqr(Constants::pi)/2. + 0.5*log(mu2_) - 1.5*log(1.-2.*mu2_)
 	-(1.-2.*mu2_)/beta*(0.5*sqr(L)+sqr(Constants::pi)/6.
 			    -2.*L*log(1.-2.*mu2_))
 	+ nonSingletTerm);
   return prefactor*(virtualTerm+iEpsilonTerm);
 }
 
 //non-singlet piece of I(epsilon) insertion operator
 double SMHiggsFermionsDecayer::
 calculateNonSingletTerm(double beta, double L) const {
   return  1.5*log(1.-2.*mu2_)  
     + (1.-2.*mu2_)/beta*(- 2.*L*log(4.*(1.-2.*mu2_)/sqr(1.+beta))+
 			 + 2.*Herwig::Math::ReLi2(sqr((1.-beta)/(1.+beta)))
 			 - 2.*Herwig::Math::ReLi2(2.*beta/(1.+beta)) 
 			 - sqr(Constants::pi)/6.) 
     + log(1.-mu_) 
     - 2.*log(1.-2.*mu_) 
     - 2.*mu2_/(1.-2.*mu2_)*log(mu_/(1.-mu_))
     - mu_/(1.-mu_)
     + 2.*mu_*(2*mu_-1.)/(1.-2.*mu2_)
     + 0.5*sqr(Constants::pi);
 }
 
 double SMHiggsFermionsDecayer::matrixElementRatio(const Particle & inpart, const ParticleVector & decay2,
 						  const ParticleVector & decay3, MEOption,
 						  ShowerInteraction inter) {
   mHiggs_ = inpart.mass();
   mu_ = decay2[0]->mass()/mHiggs_;
   mu2_ = sqr(mu_);
   double x1 = 2.*decay3[0]->momentum().t()/mHiggs_;
   double x2 = 2.*decay3[1]->momentum().t()/mHiggs_;
   double pre = inter==ShowerInteraction::QCD ? CF_ : sqr(double(decay2[0]->dataPtr()->iCharge())/3.);
   return pre*calculateRealEmission(x1,x2)*4.*Constants::pi*sqr(mHiggs_);
 }
diff --git a/Decay/Perturbative/SMHiggsGGHiggsPPDecayer.cc b/Decay/Perturbative/SMHiggsGGHiggsPPDecayer.cc
--- a/Decay/Perturbative/SMHiggsGGHiggsPPDecayer.cc
+++ b/Decay/Perturbative/SMHiggsGGHiggsPPDecayer.cc
@@ -1,424 +1,426 @@
 // -*- C++ -*-
 //
 // SMHiggsGGHiggsPPDecayer.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 SMHiggsGGHiggsPPDecayer class.
 //
 
 #include "SMHiggsGGHiggsPPDecayer.h"
 #include "ThePEG/Interface/ClassDocumentation.h"
 #include "ThePEG/Interface/Reference.h"
 #include "ThePEG/Utilities/DescribeClass.h"
 #include "ThePEG/Persistency/PersistentOStream.h"
 #include "ThePEG/Persistency/PersistentIStream.h"
 #include "ThePEG/Helicity/WaveFunction/ScalarWaveFunction.h"
 #include "ThePEG/Helicity/WaveFunction/VectorWaveFunction.h"
 #include "ThePEG/PDT/DecayMode.h"
 #include "Herwig/Decay/GeneralDecayMatrixElement.h"
 #include "Herwig/Utilities/HiggsLoopFunctions.h"
 
 using namespace Herwig;
 using namespace Herwig::HiggsLoopFunctions;
 using namespace ThePEG::Helicity;
 
 // The following static variable is needed for the type
 // description system in ThePEG. 
 DescribeClass<SMHiggsGGHiggsPPDecayer,PerturbativeDecayer>
 describeHerwigSMHiggsGGHiggsPPDecayer("Herwig::SMHiggsGGHiggsPPDecayer",
 				      "HwPerturbativeHiggsDecay.so");
 
 bool SMHiggsGGHiggsPPDecayer::accept(tcPDPtr parent,
 				       const tPDVector & children) const {
   int idp = parent->id();
   int id0 = children[0]->id();
   int id1 = children[1]->id();
   if((idp == ParticleID::h0 && 
       id0 == ParticleID::g     && id1 == ParticleID::g) ||
      (idp == ParticleID::h0 && 
       id0 == ParticleID::gamma && id1 == ParticleID::gamma)||
      (idp == ParticleID::h0 && 
       id0 == ParticleID::Z0 && id1 == ParticleID::gamma)||
      (idp == ParticleID::h0 && 
       id0 == ParticleID::gamma && id1 == ParticleID::Z0)) 
     return true;
   else
     return false;
 }
 
 ParticleVector SMHiggsGGHiggsPPDecayer::decay(const Particle & parent,
 					      const tPDVector & children) const {
   int imode(2);
   if(children[0]->id() == ParticleID::gamma && 
      children[1]->id() == ParticleID::gamma)
     imode = 1;
   else if(children[0]->id() ==ParticleID::g)
     imode = 0;
   ParticleVector out(generate(true,false,imode,parent));
   //colour flow
   if(children[0]->id() == ParticleID::g &&
      children[1]->id() == ParticleID::g) {
     out[0]->colourNeighbour(out[1]);
     out[0]->antiColourNeighbour(out[1]);
   }
   return out;
 }
 
 void SMHiggsGGHiggsPPDecayer::persistentOutput(PersistentOStream & os) const {
   os << _hggvertex << _hppvertex << _hzpvertex  << _h0wgt
      << _minloop << _maxloop << _massopt;
 }
 
 void SMHiggsGGHiggsPPDecayer::persistentInput(PersistentIStream & is, int) {
   is >> _hggvertex >> _hppvertex >> _hzpvertex >> _h0wgt
      >> _minloop >> _maxloop >> _massopt;
 }
 
 void SMHiggsGGHiggsPPDecayer::Init() {
 
   static ClassDocumentation<SMHiggsGGHiggsPPDecayer> documentation
     ("This is an implentation of h0->gg or h0->gamma,gamma "
      "decayer using the SMHGGVertex.");
   
   static Reference<SMHiggsGGHiggsPPDecayer,AbstractVVSVertex> 
     interfaceSMHGGVertex
     ("SMHGGVertex",
      "Pointer to SMHGGVertex",
      &SMHiggsGGHiggsPPDecayer::_hggvertex, false, false, true, 
      false, false);
   
   static Reference<SMHiggsGGHiggsPPDecayer,AbstractVVSVertex> 
     interfaceSMHPPVertex
     ("SMHPPVertex",
      "Pointer to SMHPPVertex",
      &SMHiggsGGHiggsPPDecayer::_hppvertex, false, false, true, 
      false, false);
   
   static Reference<SMHiggsGGHiggsPPDecayer,AbstractVVSVertex> 
     interfaceSMHZPVertex
     ("SMHZPVertex",
      "Pointer to SMHZPVertex",
      &SMHiggsGGHiggsPPDecayer::_hzpvertex, false, false, true, 
      false, false);
   
   static ParVector<SMHiggsGGHiggsPPDecayer,double> interfaceMaxWeights
     ("MaxWeights",
      "Maximum weights for the various decays",
      &SMHiggsGGHiggsPPDecayer::_h0wgt, 3, 1.0, 0.0, 10.0,
      false, false, Interface::limited);
   static Parameter<SMHiggsGGHiggsPPDecayer,int> interfaceMinimumInLoop
     ("MinimumInLoop",
      "The minimum flavour of the quarks to include in the loops",
      &SMHiggsGGHiggsPPDecayer::_minloop, 6, 4, 6,
      false, false, Interface::limited);
 
   static Parameter<SMHiggsGGHiggsPPDecayer,int> interfaceMaximumInLoop
     ("MaximumInLoop",
      "The maximum flavour of the quarks to include in the loops",
      &SMHiggsGGHiggsPPDecayer::_maxloop, 6, 4, 6,
      false, false, Interface::limited);
 
   static Switch<SMHiggsGGHiggsPPDecayer,unsigned int> interfaceMassOption
     ("MassOption",
      "Option for the treatment of the masses in the loop diagrams",
      &SMHiggsGGHiggsPPDecayer::_massopt, 0, false, false);
   static SwitchOption interfaceMassOptionFull
     (interfaceMassOption,
      "Full",
      "Include the full mass dependence",
      0);
   static SwitchOption interfaceMassOptionLarge
     (interfaceMassOption,
      "Large",
      "Use the heavy mass limit",
      1);
 
 }
 
 double SMHiggsGGHiggsPPDecayer::me2(const int, 
 				    const Particle & part,
 				    const ParticleVector & decay,
 				    MEOption meopt) const {
   if(!ME())
     ME(new_ptr(GeneralDecayMatrixElement(PDT::Spin0,PDT::Spin1,PDT::Spin1)));
   if(meopt==Initialize) {
     ScalarWaveFunction::
       calculateWaveFunctions(_rho,const_ptr_cast<tPPtr>(&part),incoming);
     _swave = ScalarWaveFunction(part.momentum(),part.dataPtr(),incoming);
+    // fix rho if no correlations
+    fixRho(_rho);
   }
   if(meopt==Terminate) {
     ScalarWaveFunction::constructSpinInfo(const_ptr_cast<tPPtr>(&part),
 					  incoming,true);
     for(unsigned int ix=0;ix<2;++ix)
       VectorWaveFunction::constructSpinInfo(_vwave[ix],decay[ix],
 					    outgoing,true,
 					    decay[ix]->id()!=ParticleID::Z0);
     return 0.;
   }
   for(unsigned int ix=0;ix<2;++ix)
     VectorWaveFunction::
       calculateWaveFunctions(_vwave[ix],decay[ix],outgoing,decay[ix]->id()!=ParticleID::Z0);
   //Set up decay matrix
   Energy2 scale(sqr(part.mass()));
   unsigned int v1hel,v2hel;
   AbstractVVSVertexPtr vertex;
   unsigned int vstep1(2),vstep2(2);
   double sym(1.);
   if(decay[0]->id() == ParticleID::g &&
      decay[1]->id() == ParticleID::g) {
     vertex = _hggvertex;
     sym = 2.;
   }
   else if(decay[0]->id() == ParticleID::gamma &&
 	  decay[1]->id() == ParticleID::gamma) {
     vertex = _hppvertex;
     sym = 2.;
   }
   else if(decay[0]->id() == ParticleID::Z0 &&
 	  decay[1]->id() == ParticleID::gamma) {
     vertex = _hzpvertex;
     vstep1 = 1;
   }
   else if(decay[1]->id() == ParticleID::Z0 &&
 	  decay[0]->id() == ParticleID::gamma) {
     vertex = _hzpvertex;
     vstep2 = 1;
   }
   else
     assert(false);
   // loop over the helicities of the outgoing bosons
   for(v1hel = 0;v1hel < 3;v1hel+=vstep1) {
     for(v2hel = 0;v2hel < 3;v2hel+=vstep2) {
       (*ME())(0,v1hel,v2hel) = vertex->evaluate(scale,_vwave[0][v1hel],
 						_vwave[1][v2hel],_swave);
     }
   }
   //store matrix element
   double output = ME()->contract(_rho).real()*UnitRemoval::E2/scale;
   //colour factor (N^2 - 1)/4
   if(decay[0]->id() == ParticleID::g) output *= 8.;
   //symmetric final states
   output /= sym;
   // return the answer
   return output;
 }
 
 void SMHiggsGGHiggsPPDecayer::doinit() {
   PerturbativeDecayer::doinit();
   // get the width generator for the higgs
   tPDPtr higgs = getParticleData(ParticleID::h0);
   if(_hggvertex) {
     _hggvertex->init();
   }
   else {
     throw InitException() << "SMHiggsGGHiggsPPDecayer::doinit() - " 
 			  << "_hggvertex is null";
   }
   if(_hppvertex) {
     _hppvertex->init();
   }
   else {
     throw InitException() << "SMHiggsGGHiggsPPDecayer::doinit() - " 
 			  << "_hppvertex is null";
   }
   if(_hzpvertex) {
     _hzpvertex->init();
   }
   else {
     throw InitException() << "SMHiggsGGHiggsZPDecayer::doinit() - " 
 			  << "_hzpvertex is null";
   }
   //set up decay modes
   DecayPhaseSpaceModePtr mode;
   tPDVector extpart(3);
   vector<double> wgt(0);
   // glu,glu mode
   extpart[0] = getParticleData(ParticleID::h0);
   extpart[1] = getParticleData(ParticleID::g);
   extpart[2] = getParticleData(ParticleID::g);
   mode = new_ptr(DecayPhaseSpaceMode(extpart,this));
   addMode(mode,_h0wgt[0],wgt);
   // gamma,gamma mode
   extpart[1] = getParticleData(ParticleID::gamma);
   extpart[2] = getParticleData(ParticleID::gamma);
   mode = new_ptr(DecayPhaseSpaceMode(extpart,this));
   addMode(mode,_h0wgt[1],wgt);
   // Z0,gamma mode
   extpart[1] = getParticleData(ParticleID::Z0);
   extpart[2] = getParticleData(ParticleID::gamma);
   mode = new_ptr(DecayPhaseSpaceMode(extpart,this));
   addMode(mode,_h0wgt[2],wgt);
 }
 
 void SMHiggsGGHiggsPPDecayer::doinitrun() {
   _hggvertex->initrun();
   _hppvertex->initrun();
   _hzpvertex->initrun();
   PerturbativeDecayer::doinitrun();
   if(initialize()) {
     for(unsigned int ix=0;ix<numberModes();++ix) {
       _h0wgt[ix] = mode(ix)->maxWeight();
     }
   }
 }
 
 void SMHiggsGGHiggsPPDecayer::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<_h0wgt.size();++ix) {
     os << "newdef " << name() << ":MaxWeights " << ix << " "
 	   << _h0wgt[ix] << "\n";
   }
   os << "newdef " << name() << ":SMHGGVertex " << _hggvertex->fullName() << "\n";
   os << "newdef " << name() << ":SMHPPVertex " << _hppvertex->fullName() << "\n";
   os << "newdef " << name() << ":SMHZPVertex " << _hzpvertex->fullName() << "\n";
   PerturbativeDecayer::dataBaseOutput(os,false);
   if(header) os << "\n\" where BINARY ThePEGName=\"" 
 		<< fullName() << "\";" << endl;
 }
 
 double SMHiggsGGHiggsPPDecayer::matrixElementRatio(const Particle & inpart, const ParticleVector & decay2,
 						   const ParticleVector & decay3, MEOption,
 						   ShowerInteraction inter) {
   assert(inter==ShowerInteraction::QCD);
   // extract partons and LO momentas
   vector<cPDPtr> partons(1,inpart.dataPtr());
   vector<Lorentz5Momentum> lomom(1,inpart.momentum());
   for(unsigned int ix=0;ix<2;++ix) {
     partons.push_back(decay2[ix]->dataPtr());
     lomom.push_back(decay2[ix]->momentum());
   }
   vector<Lorentz5Momentum> realmom(1,inpart.momentum());
   for(unsigned int ix=0;ix<3;++ix) {
     if(ix==2) partons.push_back(decay3[ix]->dataPtr());
     realmom.push_back(decay3[ix]->momentum());
   }
   Energy2 scale = sqr(inpart.mass());
   Energy2 lome = loME(inpart.mass());
   double reme = realME(partons,realmom);
   double ratio = reme/lome*scale;
   // // analytic value for mt -> infinity
   // double x1 = 2.*decay3[0]->momentum().t()/inpart.mass();
   // double x2 = 2.*decay3[1]->momentum().t()/inpart.mass();
   // double x3 = 2.*decay3[2]->momentum().t()/inpart.mass();
   // double test = 8.*Constants::pi*3.*(1.+pow(1-x1,4)+pow(1-x2,4)+pow(1-x3,4))
   //   /(1.-x1)/(1.-x2)/(1.-x3);
   // generator()->log() << "TESTING RATIO " << test << " " << ratio << " " << ratio/test << "\n";
   // remember the symmetry factor
   return ratio/3.;
 }
 
 double SMHiggsGGHiggsPPDecayer::realME(//const vector<cPDPtr> & partons, 
 				       const vector<cPDPtr> &, 
 				       const vector<Lorentz5Momentum> & momenta) const {
   // using std::norm;
   // ScalarWaveFunction  hout(momenta[0],partons[0],outgoing);
   // LorentzPolarizationVector g[3][2];
   // // calculate the polarization vectors for the gluons
   // for(unsigned int iw=0;iw<3;++iw) {
   //   VectorWaveFunction gwave(momenta[iw+1],partons[iw+1],outgoing);
   //   for(unsigned int ix=0;ix<2;++ix) {
   //     //if(iw==2) gwave.reset(10);
   //     //else
   //     gwave.reset(2*ix);
   //     g[iw][ix] = gwave.wave();
   //   }
   // }
   Energy2 mh2 = momenta[0].mass2();
   Energy2 s = (momenta[1]+momenta[2]).m2();
   Energy2 t = (momenta[1]+momenta[3]).m2();
   Energy2 u = (momenta[2]+momenta[3]).m2();
   // calculate the loop functions
   Complex A4stu(0.),A2stu(0.),A2tsu(0.),A2ust(0.);
   for(int ix=_minloop;ix<=_maxloop;++ix) {
     // loop functions
     if(_massopt==0) {
       Energy2 mf2=sqr(getParticleData(ix)->mass());
       A4stu+=A4(s,t,u,mf2);
       A2stu+=A2(s,t,u,mf2);
       A2tsu+=A2(t,s,u,mf2);
       A2ust+=A2(u,s,t,mf2);
     }
     else {
       A4stu=-1./3.;
       A2stu=-sqr(s/mh2)/3.;
       A2tsu=-sqr(t/mh2)/3.;
       A2ust=-sqr(u/mh2)/3.;
     }
   }
   // Complex A3stu=0.5*(A2stu+A2ust+A2tsu-A4stu);
   // // compute the dot products for the matrix element
   // // and polarization vector * momenta
   // Energy2 pdot[3][3];
   // complex<InvEnergy> eps[3][3][2]; 
   // for(unsigned int ig=0;ig<3;++ig) {
   //   for(unsigned int ip=0;ip<3;++ip) {
   //     pdot[ig][ip]=momenta[ig+1]*momenta[ip+1];
   //     for(unsigned int ih=0;ih<2;++ih) {
   // 	if(ig!=ip)
   // 	  eps[ig][ip][ih]=g[ig][ih].dot(momenta[ip+1])/pdot[ig][ip];
   // 	else
   // 	  eps[ig][ip][ih]=ZERO;
   //     }
   //   }
   // }
   // prefactors
   Energy mw(getParticleData(ParticleID::Wplus)->mass());
   // Energy3 pre=sqr(mh2)/mw;
   // // compute the matrix element
   // double output(0.);
   // complex<InvEnergy2> wdot[3][3];
   //  for(unsigned int ghel1=0;ghel1<2;++ghel1) {
   //    for(unsigned int ghel2=0;ghel2<2;++ghel2) {
   //      for(unsigned int ghel3=0;ghel3<2;++ghel3) {
   // 	 wdot[0][1]=g[0][ghel1].dot(g[1][ghel2])/pdot[0][1];
   // 	 wdot[0][2]=g[0][ghel1].dot(g[2][ghel3])/pdot[0][2];
   // 	 wdot[1][0]=wdot[0][1];
   // 	 wdot[1][2]=g[1][ghel2].dot(g[2][ghel3])/pdot[1][2];
   // 	 wdot[2][0]=wdot[0][2];
   // 	 wdot[2][1]=wdot[1][2];
   // 	 // last piece
   // 	 Complex diag=pre*A3stu*(eps[0][2][ghel1]*eps[1][0][ghel2]*eps[2][1][ghel3]-
   // 				 eps[0][1][ghel1]*eps[1][2][ghel2]*eps[2][0][ghel3]+
   // 				 (eps[2][0][ghel3]-eps[2][1][ghel3])*wdot[0][1]+
   // 				 (eps[1][2][ghel2]-eps[1][0][ghel2])*wdot[0][2]+
   // 				 (eps[0][1][ghel1]-eps[0][2][ghel1])*wdot[1][2]);
   // 	 // first piece
   // 	 diag+=pre*(+A2stu*(eps[0][1][ghel1]*eps[1][0][ghel2]-wdot[0][1])*
   // 		    (eps[2][0][ghel3]-eps[2][1][ghel3])
   // 		    +A2tsu*(eps[0][2][ghel1]*eps[2][0][ghel3]-wdot[0][2])*
   // 		    (eps[1][2][ghel2]-eps[1][0][ghel2])
   // 		    +A2ust*(eps[1][2][ghel2]*eps[2][1][ghel3]-wdot[1][2])*
   // 		    (eps[0][1][ghel1]-eps[0][2][ghel1]));
   // 	 output+=norm(diag);
   //      }
   //    }
   //  }
   //  // colour factor and what's left of the prefactor
   //  output *= 6.;
    double me=4.*24./s/t/u*pow<4,1>(mh2)/sqr(mw)*
      (norm(A2stu)+norm(A2ust)+norm(A2tsu)+norm(A4stu));
    return me;
 }
 
 Energy2 SMHiggsGGHiggsPPDecayer::loME(Energy mh) const {
   Complex loop(0.);
   Energy2 mh2(sqr(mh));
   Energy mw(getParticleData(ParticleID::Wplus)->mass());
   for(int ix=_minloop;ix<=_maxloop;++ix) {
     // loop functions
     if(_massopt==0) {
       Energy2 mf2=sqr(getParticleData(ix)->mass());
       loop += A1(mh2,mf2);
     }
     else {
       loop += 2./3.;
     }
   }
   return 1./Constants::pi*sqr(mh2)/sqr(mw)*norm(loop);
 }
diff --git a/Decay/Perturbative/SMHiggsWWDecayer.cc b/Decay/Perturbative/SMHiggsWWDecayer.cc
--- a/Decay/Perturbative/SMHiggsWWDecayer.cc
+++ b/Decay/Perturbative/SMHiggsWWDecayer.cc
@@ -1,325 +1,327 @@
 // -*- C++ -*-
 //
 // SMHiggsWWDecayer.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 SMHiggsWWDecayer class.
 //
 
 #include "SMHiggsWWDecayer.h"
 #include "ThePEG/Utilities/DescribeClass.h"
 #include "ThePEG/Interface/ClassDocumentation.h"
 #include "ThePEG/Interface/Parameter.h"
 #include "ThePEG/Interface/Switch.h"
 #include "ThePEG/Persistency/PersistentOStream.h"
 #include "ThePEG/Persistency/PersistentIStream.h"
 #include "Herwig/Models/StandardModel/StandardModel.h"
 #include "ThePEG/PDT/EnumParticles.h"
 #include "ThePEG/PDT/DecayMode.h"
 #include "ThePEG/PDT/ParticleData.h"
 #include "Herwig/Decay/GeneralDecayMatrixElement.h"
 
 using namespace Herwig;
 typedef Selector<tDMPtr> DecaySelector;
 
 // The following static variable is needed for the type
 // description system in ThePEG.
 DescribeClass<SMHiggsWWDecayer,PerturbativeDecayer>
 describeHerwigSMHiggsWWDecayer("Herwig::SMHiggsWWDecayer", "HwPerturbativeHiggsDecay.so");
 
 void SMHiggsWWDecayer::Init() {
 
   static ClassDocumentation<SMHiggsWWDecayer> documentation
     ("The SMHiggsWWDecayer class performs the decay of the Standard Model Higgs"
      " boson to W+W- and Z0Z0");
 
   static ParVector<SMHiggsWWDecayer,double> interfaceWMaximum
     ("WMaximum",
      "The maximum weight for H-> W+W- decays",
      &SMHiggsWWDecayer::_wmax, 2, 1.0, 0.0, 10000.0,
      false, false, Interface::limited);
 
   static ParVector<SMHiggsWWDecayer,double> interfaceZMaximum
     ("ZMaximum",
      "The maximum weight for H-> Z0Z0 decays",
      &SMHiggsWWDecayer::_zmax, 2, 1.0, 0.0, 10000.0,
      false, false, Interface::limited);
 }
 
 SMHiggsWWDecayer::SMHiggsWWDecayer() : _wmax(2,1.00), _zmax(2,1.00)
 {}
 
 void SMHiggsWWDecayer::doinit() {
   PerturbativeDecayer::doinit();
   // get the vertices from the Standard Model object
   tcHwSMPtr hwsm=dynamic_ptr_cast<tcHwSMPtr>(standardModel());
   if(!hwsm) 
     throw InitException() << "SMHiggsWWDecayer needs the StandardModel class"
 			  << " to be either the Herwig one or a class inheriting"
 			  << " from it";
   _theFFWVertex = hwsm->vertexFFW();
   _theFFZVertex = hwsm->vertexFFZ();
   _theHVVVertex = hwsm->vertexWWH();
   // get the width generator for the higgs
   tPDPtr higgs = getParticleData(ParticleID::h0);
   // the W+W- decays
   for(unsigned int ix=0;ix<2;++ix) {
     tPDPtr h0     = getParticleData(ParticleID::h0);
     tPDPtr wplus  = getParticleData(ParticleID::Wplus);
     tPDPtr wminus = getParticleData(ParticleID::Wminus);
     DecaySelector wpDecay =  wplus->decaySelector();
     DecaySelector wmDecay = wminus->decaySelector();
     tPDVector extpart(5);
     extpart[0]=h0;
     DecayPhaseSpaceModePtr mode;
     DecayPhaseSpaceChannelPtr newchannel;
     vector<double> wgt(1,1.);
     unsigned int imode=0;
     for(DecaySelector::const_iterator wp=wpDecay.begin();wp!=wpDecay.end();++wp) {
       // extract the decay products of W+
       tPDVector prod=(*wp).second->orderedProducts();
       if(prod[0]->id()<prod[1]->id()) swap(prod[0],prod[1]);
       extpart[1]=prod[0];
       extpart[2]=prod[1];
       for(DecaySelector::const_iterator wm=wmDecay.begin();wm!=wmDecay.end();++wm) {
 	// extract the decay products of W-
 	tPDVector prod=(*wm).second->orderedProducts();
 	if(prod[0]->id()<prod[1]->id()) swap(prod[0],prod[1]);
 	extpart[3]=prod[0];
 	extpart[4]=prod[1];
 	// create the new mode
 	mode = new_ptr(DecayPhaseSpaceMode(extpart,this));
 	// create the phase space channel
 	newchannel=new_ptr(DecayPhaseSpaceChannel(mode));
 	newchannel->addIntermediate(extpart[0],0,0.0,-1,-2);
 	if(ix==0) {
 	  newchannel->addIntermediate(wplus     ,1,0., 1, 2);
 	  newchannel->addIntermediate(wminus    ,1,0., 3, 4);
 	}
 	else {
 	  newchannel->addIntermediate(wplus     ,0,0., 1, 2);
 	  newchannel->addIntermediate(wminus    ,0,0., 3, 4);
 	}
 	mode->addChannel(newchannel);
 	addMode(mode,_wmax[ix],wgt);
 	// insert mode into selector
 	_ratio.push_back(wp->second->brat()*wm->second->brat());
 	if(ix==0) _wdecays.insert (_ratio.back(),imode);
 	++imode;
       }
     }
     // the Z0Z0 decays
     tPDPtr Z0=getParticleData(ParticleID::Z0);
     DecaySelector Z0Decay = Z0->decaySelector();
     for(DecaySelector::const_iterator z1=Z0Decay.begin();z1!=Z0Decay.end();++z1) {
       // extract the decay products of Z0
       tPDVector prod=(*z1).second->orderedProducts();
       if(prod[0]->id()<prod[1]->id()) swap(prod[0],prod[1]);
       extpart[1]=prod[0];
       extpart[2]=prod[1];
       for(DecaySelector::const_iterator z2=Z0Decay.begin();z2!=Z0Decay.end();++z2) {
 	// extract the decay products of Z0
 	tPDVector prod=(*z2).second->orderedProducts();
 	if(prod[0]->id()<prod[1]->id()) swap(prod[0],prod[1]);
 	extpart[3]=prod[0];
 	extpart[4]=prod[1];
 	// create the new mode
 	mode = new_ptr(DecayPhaseSpaceMode(extpart,this));
 	// create the phase space channel
 	newchannel=new_ptr(DecayPhaseSpaceChannel(mode));
 	newchannel->addIntermediate(extpart[0],0,0.0,-1,-2);
 	if(ix==0) {
 	  newchannel->addIntermediate(Z0    ,1,0., 1, 2);
 	  newchannel->addIntermediate(Z0    ,1,0., 3, 4);
 	}
 	else {
 	  newchannel->addIntermediate(Z0    ,0,0., 1, 2);
 	  newchannel->addIntermediate(Z0    ,0,0., 3, 4);
 	}
 	mode->addChannel(newchannel);
 	addMode(mode,_zmax[ix],wgt);
 	// insert mode into selector
 	_ratio.push_back(z1->second->brat()*z2->second->brat());
 	if(ix==0) _zdecays.insert (_ratio.back(),imode);
 	++imode;
       }
     }
   }
 }
 
 bool SMHiggsWWDecayer::accept(tcPDPtr parent, const tPDVector & children) const {
   // if not two decay products return false
   if(children.size()!=2) return false;
   // if not decaying higgs return false
   if(parent->id()!=ParticleID::h0) return false;
   tPDVector::const_iterator pit = children.begin();
   int id1=(**pit).id();
   ++pit;
   int id2=(**pit).id();
   if((id1==-id2&&abs(id1)==ParticleID::Wplus)||
      (id1== id2&&    id1 ==ParticleID::Z0))
     return true;
   else
     return false;
 }
 
 void SMHiggsWWDecayer::persistentOutput(PersistentOStream & os) const {
   os << _theFFWVertex << _theFFZVertex << _theHVVVertex 
      << _wdecays << _zdecays << _ratio << _wmax << _zmax;
 }
 
 void SMHiggsWWDecayer::persistentInput(PersistentIStream & is, int) {
   is >> _theFFWVertex >> _theFFZVertex >> _theHVVVertex 
      >> _wdecays >> _zdecays >> _ratio >> _wmax >> _zmax;
 }
 
 ParticleVector SMHiggsWWDecayer::decay(const Particle & parent,
 				       const tPDVector & children) const {
   // select the decay modes of the gauge bosons
   unsigned int imode;
   if(abs(children[0]->id())==ParticleID::Wplus)
     imode=_wdecays.select(UseRandom::rnd());
   else
     imode=_zdecays.select(UseRandom::rnd());
   // use different phase space for low/high mass higgs
   if(parent.mass()>1.8*children[0]->mass()) 
     imode+=_wdecays.size()+_zdecays.size();
   // generate the kinematics
   return generate(true,false,imode,parent);
 }
 
 double SMHiggsWWDecayer::me2(const int, const Particle & inpart,
 			     const ParticleVector & decay,
 			     MEOption meopt) const {
   if(!ME())
     ME(new_ptr(GeneralDecayMatrixElement(PDT::Spin0,PDT::Spin1Half,PDT::Spin1Half,
 					 PDT::Spin1Half,PDT::Spin1Half)));
   // check if Z or W decay
   bool Z0=decay[0]->id()==-decay[1]->id();
   if(meopt==Initialize) {
     ScalarWaveFunction::
       calculateWaveFunctions(_rho,const_ptr_cast<tPPtr>(&inpart),incoming);
     _swave = ScalarWaveFunction(inpart.momentum(),inpart.dataPtr(),incoming);
+    // fix rho if no correlations
+    fixRho(_rho);
   }
   if(meopt==Terminate) {
     ScalarWaveFunction::constructSpinInfo(const_ptr_cast<tPPtr>(&inpart),
 					  incoming,true);
     SpinorBarWaveFunction::
       constructSpinInfo(_fwave1,decay[0],outgoing,true);
     SpinorWaveFunction   ::
       constructSpinInfo(_awave1,decay[1],outgoing,true);
     SpinorBarWaveFunction::
       constructSpinInfo(_fwave2,decay[2],outgoing,true);
     SpinorWaveFunction   ::
       constructSpinInfo(_awave2,decay[3],outgoing,true);
     return 0.;
   }
   SpinorBarWaveFunction::
     calculateWaveFunctions(_fwave1,decay[0],outgoing);
   SpinorWaveFunction   ::
     calculateWaveFunctions(_awave1,decay[1],outgoing);
   SpinorBarWaveFunction::
     calculateWaveFunctions(_fwave2,decay[2],outgoing);
   SpinorWaveFunction   ::
     calculateWaveFunctions(_awave2,decay[3],outgoing);
   // get the intermediates and vertex
   tcPDPtr inter[2];
   AbstractFFVVertexPtr vert;
   if(Z0) {
     inter[0]=getParticleData(ParticleID::Z0);
     inter[1]=inter[0];
     vert=_theFFZVertex;
   }
   else {
     inter[0]=getParticleData(ParticleID::Wplus);
     inter[1]=getParticleData(ParticleID::Wminus);
     vert=_theFFWVertex;
   }
 
 
   // construct the spinors for the outgoing particles
   Energy2 scale0(sqr(inpart.mass()));
   Energy2 scale1((decay[0]->momentum()+decay[1]->momentum()).m2());
   Energy2 scale2((decay[2]->momentum()+decay[3]->momentum()).m2());
   // for decays to quarks ensure boson is massive enough to
   // put quarks on constituent mass-shell
   if(scale1<sqr(decay[0]->dataPtr()->constituentMass()+
 		decay[1]->dataPtr()->constituentMass())) return 0.;
   if(scale2<sqr(decay[2]->dataPtr()->constituentMass()+
 		decay[3]->dataPtr()->constituentMass())) return 0.;
   // compute the boson currents
   VectorWaveFunction curr1[2][2],curr2[2][2];
   unsigned int ohel1,ohel2,ohel3,ohel4;
   for(ohel1=0;ohel1<2;++ohel1) {
     for(ohel2=0;ohel2<2;++ohel2) {
       curr1[ohel1][ohel2]=vert->evaluate(scale1,1,inter[0],
 					 _awave1[ohel2],_fwave1[ohel1]);
       curr2[ohel1][ohel2]=vert->evaluate(scale2,1,inter[1],
 					 _awave2[ohel2],_fwave2[ohel1]);
     }
   }
   // compute the matrix element
   for(ohel1=0;ohel1<2;++ohel1) {
     for(ohel2=0;ohel2<2;++ohel2) {
       for(ohel3=0;ohel3<2;++ohel3) {
 	for(ohel4=0;ohel4<2;++ohel4) {
 	  (*ME())(0,ohel1,ohel2,ohel3,ohel4)=
 	    _theHVVVertex->evaluate(scale0,curr1[ohel1][ohel2],
 				    curr2[ohel3][ohel4],_swave);
 	}
       }
     }
   }
   double output=(ME()->contract(_rho)).real()*scale0*UnitRemoval::InvE2;
   // set up the colour flows
   if(decay[0]->coloured()) {
     output*=3.;
     decay[0]->antiColourNeighbour(decay[1]);
   }
   if(decay[2]->coloured()) {
     output*=3.;
     decay[2]->antiColourNeighbour(decay[3]);
   }
   // divide out the gauge boson branching ratios
   output/=_ratio[imode()];
   // if Z0 decays identical particle factor
   if(Z0) output*=0.5;
   // return the answer
   return output;
 }
 
 void SMHiggsWWDecayer::dataBaseOutput(ofstream & os,bool header) const {
   if(header) os << "update decayers set parameters=\"";
   for(unsigned int ix=0;ix<2;++ix) {
     os << "newdef " << name() << ":WMaximum "    << ix << " " << _wmax[ix]  << "\n";
     os << "newdef " << name() << ":ZMaximum "    << ix << " " << _zmax[ix]  << "\n";
   }
   PerturbativeDecayer::dataBaseOutput(os,false);
   if(header) os << "\n\" where BINARY ThePEGName=\"" << fullName() << "\";" << endl;
 }
 
 void SMHiggsWWDecayer::doinitrun() {
   PerturbativeDecayer::doinitrun();
   for(unsigned int ix=0;ix<2;++ix) {
     _zmax[ix]=0.;
     _wmax[ix]=0.;
   }
   unsigned int ntest=_wdecays.size()+_zdecays.size();
   if(initialize()) {
     for(unsigned int ix=0;ix<numberModes();++ix) {
       unsigned int iloc = ix<ntest ? 0 : 1;
       if(mode(ix)->externalParticles(1)->iCharge()==
 	 -mode(ix)->externalParticles(2)->iCharge()) {
 	_zmax[iloc]=max(mode(ix)->maxWeight(),_zmax[iloc]);
       }
       else {
 	_wmax[iloc]=max(mode(ix)->maxWeight(),_wmax[iloc]);
       }
     }
   }
 }
diff --git a/Decay/Perturbative/SMTopDecayer.cc b/Decay/Perturbative/SMTopDecayer.cc
--- a/Decay/Perturbative/SMTopDecayer.cc
+++ b/Decay/Perturbative/SMTopDecayer.cc
@@ -1,764 +1,766 @@
 // -*- 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/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) {
   _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;
 }
   
 void SMTopDecayer::persistentInput(PersistentIStream & is, int) {
   is >> FFWVertex_ >> FFGVertex_ >> FFPVertex_ >> WWWVertex_
      >> _wquarkwgt >> _wleptonwgt >> _wplus
      >> _initialenhance >> _finalenhance >> _xg_sampling;
 }
   
 // 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);
 }
 
 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);
+    // fix rho if no correlations
+    fixRho(_rho);
   }
   // 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();
 }
 
 
 bool SMTopDecayer::softMatrixElementVeto(PPtr parent,
 					 PPtr progenitor,
 					 const bool & ,
 					 const Energy & highestpT,
 					 const vector<tcPDPtr> &,
 					 const double & z,
 					 const Energy & scale,
 					 const Energy & pt) {
   // check if we need to apply the full correction
   // the initial-state correction
   if(abs(progenitor->id())==ParticleID::t&&abs(parent->id())==ParticleID::t) {
     // check if hardest so far
     // if not just need to remove effect of enhancement
     bool veto(false);
     // if not hardest so far
     if(pt<highestpT)
       veto=!UseRandom::rndbool(1./_initialenhance);
     // if hardest so far do calculation
     else {
       // values of kappa and z
       double kappa(sqr(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);
       }
     }
     // return the veto
     return veto;
   }
   // final-state correction
   else if(abs(progenitor->id())==ParticleID::b&&abs(parent->id())==ParticleID::b) {
     // check if hardest so far
     // if not just need to remove effect of enhancement
     // if not hardest so far
     if(pt<highestpT) return !UseRandom::rndbool(1./_finalenhance);
     // if hardest so far do calculation
     // values of kappa and z
     double kappa(sqr(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;
       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 and return
     return !UseRandom::rndbool(wgt);
   }
   // 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);
 }
 
 // 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::loME(const Particle & inpart, const ParticleVector & decay) {
   // spinors
   vector<SpinorWaveFunction   > swave;
   vector<SpinorBarWaveFunction> awave;
   vector<VectorWaveFunction> vwave;
   tPPtr Wboson = abs(decay[0]->id())==ParticleID::Wplus ? decay[0] : decay[1];
   tPPtr bquark = abs(decay[0]->id())==ParticleID::Wplus ? decay[1] : decay[0];
   // spinors 
   if(inpart.id()>0) {
     SpinorWaveFunction   ::calculateWaveFunctions(swave,const_ptr_cast<tPPtr>(&inpart),
 						  incoming);
     SpinorBarWaveFunction::calculateWaveFunctions(awave,bquark,outgoing);
   }
   else {
     SpinorBarWaveFunction::calculateWaveFunctions(awave,const_ptr_cast<tPPtr>(&inpart),
 						  incoming);
     SpinorWaveFunction   ::calculateWaveFunctions(swave,bquark,outgoing);
   }
   // polarization vectors
   VectorWaveFunction::calculateWaveFunctions(vwave,Wboson,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;
   tPPtr Wboson = abs(decay[0]->id())==ParticleID::Wplus ? decay[0] : decay[1];
   tPPtr bquark = abs(decay[0]->id())==ParticleID::Wplus ? decay[1] : decay[0];
   // spinors 
   if(inpart.id()>0) {
     SpinorWaveFunction   ::calculateWaveFunctions(swave,const_ptr_cast<tPPtr>(&inpart),
 						  incoming);
     SpinorBarWaveFunction::calculateWaveFunctions(awave,bquark,outgoing);
   }
   else {
     SpinorBarWaveFunction::calculateWaveFunctions(awave,const_ptr_cast<tPPtr>(&inpart),
 						  incoming);
     SpinorWaveFunction   ::calculateWaveFunctions(swave,bquark,outgoing);
   }
   // polarization vectors
   VectorWaveFunction::calculateWaveFunctions(vwave,Wboson,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,bquark->dataPtr()->CC(),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,Wboson->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,bquark->dataPtr()->CC(),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,Wboson->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/SMWDecayer.cc b/Decay/Perturbative/SMWDecayer.cc
--- a/Decay/Perturbative/SMWDecayer.cc
+++ b/Decay/Perturbative/SMWDecayer.cc
@@ -1,740 +1,742 @@
 // -*- C++ -*-
 //
 // SMWDecayer.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 SMWDecayer class.
 //
 
 #include "SMWDecayer.h"
 #include "ThePEG/Utilities/DescribeClass.h"
 #include "ThePEG/Interface/ClassDocumentation.h"
 #include "ThePEG/Interface/ParVector.h"
 #include "ThePEG/Interface/Reference.h"
 #include "ThePEG/Interface/Switch.h"
 #include "ThePEG/Persistency/PersistentOStream.h"
 #include "ThePEG/Persistency/PersistentIStream.h"
 #include "ThePEG/PDT/DecayMode.h"
 #include "Herwig/Decay/DecayVertex.h"
 #include "ThePEG/Helicity/VectorSpinInfo.h"
 #include "ThePEG/Helicity/FermionSpinInfo.h"
 #include "ThePEG/Helicity/WaveFunction/VectorWaveFunction.h"
 #include "Herwig/Models/StandardModel/StandardModel.h"
 #include "Herwig/Shower/RealEmissionProcess.h"
 #include "Herwig/Decay/GeneralDecayMatrixElement.h"
 #include <numeric>
 
 using namespace Herwig;
 using namespace ThePEG::Helicity;
 
 const double SMWDecayer::EPS_=0.00000001;
 
 SMWDecayer::SMWDecayer()
   : quarkWeight_(6,0.), leptonWeight_(3,0.), CF_(4./3.),
     NLO_(false) {
   quarkWeight_[0]  = 1.01596;
   quarkWeight_[1]  = 0.0537308;
   quarkWeight_[2]  = 0.0538085;
   quarkWeight_[3]  = 1.01377;
   quarkWeight_[4]  = 1.45763e-05;
   quarkWeight_[5]  = 0.0018143;
   leptonWeight_[0] = 0.356594;
   leptonWeight_[1] = 0.356593;
   leptonWeight_[2] = 0.356333;
   // intermediates
   generateIntermediates(false);
 }
 
 void SMWDecayer::doinit() {
   PerturbativeDecayer::doinit();
   // get the vertices from the Standard Model object
   tcHwSMPtr hwsm=dynamic_ptr_cast<tcHwSMPtr>(standardModel());
   if(!hwsm) throw InitException() << "Must have Herwig StandardModel object in"
 				  << "SMWDecayer::doinit()"
 				  << Exception::runerror;
   FFWVertex_ = hwsm->vertexFFW();
   FFGVertex_ = hwsm->vertexFFG();
   WWWVertex_ = hwsm->vertexWWW();
   FFPVertex_ = hwsm->vertexFFP();
   // make sure they are initialized
   FFGVertex_->init();
   FFWVertex_->init();
   WWWVertex_->init();
   FFPVertex_->init();
   // now set up the decay modes
   DecayPhaseSpaceModePtr mode;
   tPDVector extpart(3);
   vector<double> wgt(0);
   // W modes
   extpart[0]=getParticleData(ParticleID::Wplus);
   // loop for the quarks
   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))
 	throw InitException() << "SMWDecayer::doinit() the W vertex" 
 			      << "cannot handle all the quark modes" 
 			      << Exception::abortnow;
       extpart[1] = getParticleData(-ix);
       extpart[2] = getParticleData( iy);
       mode = new_ptr(DecayPhaseSpaceMode(extpart,this));
       addMode(mode,quarkWeight_[iz],wgt);
       ++iz;
     }
   }
   // loop for the leptons
   for(int ix=11;ix<17;ix+=2) {
     // check that the combination of particles is allowed
     // if(!FFWVertex_->allowed(-ix,ix+1,ParticleID::Wminus))
     //   throw InitException() << "SMWDecayer::doinit() the W vertex" 
     // 			    << "cannot handle all the lepton modes" 
     // 			    << Exception::abortnow;
     extpart[1] = getParticleData(-ix);
     extpart[2] = getParticleData(ix+1);
     mode = new_ptr(DecayPhaseSpaceMode(extpart,this));
     addMode(mode,leptonWeight_[(ix-11)/2],wgt);
   }
   gluon_ = getParticleData(ParticleID::g);
 }
 
 int SMWDecayer::modeNumber(bool & cc,tcPDPtr parent, 
 			    const tPDVector & children) const {
   int imode(-1);
   if(children.size()!=2) return imode;
   int id0=parent->id();
   tPDVector::const_iterator pit = children.begin();
   int id1=(**pit).id();
   ++pit;
   int id2=(**pit).id();
   if(abs(id0)!=ParticleID::Wplus) return imode;
   int idd(0),idu(0);
   if(abs(id1)%2==1&&abs(id2)%2==0) {
     idd=abs(id1);
     idu=abs(id2);
   }
   else if(abs(id1)%2==0&&abs(id2)%2==1) {
     idd=abs(id2);
     idu=abs(id1);
   }
   if(idd==0&&idu==0) {
     return imode;
   }
   else if(idd<=5) {
     imode=idd+idu/2-2;
   }
   else {
     imode=(idd-1)/2+1;
   }
   cc= (id0==ParticleID::Wminus);
   return imode;
 }
 
 void SMWDecayer::persistentOutput(PersistentOStream & os) const {
   os << FFWVertex_ << quarkWeight_ << leptonWeight_
      << FFGVertex_ << gluon_ << NLO_
      << WWWVertex_ << FFPVertex_;  
 }
 
 void SMWDecayer::persistentInput(PersistentIStream & is, int) {
   is >> FFWVertex_ >> quarkWeight_ >> leptonWeight_
      >> FFGVertex_ >> gluon_ >> NLO_
      >> WWWVertex_ >> FFPVertex_;
 }
 
 // The following static variable is needed for the type
 // description system in ThePEG.
 DescribeClass<SMWDecayer,PerturbativeDecayer>
 describeHerwigSMWDecayer("Herwig::SMWDecayer", "HwPerturbativeDecay.so");
 
 void SMWDecayer::Init() {
 
   static ClassDocumentation<SMWDecayer> documentation
     ("The SMWDecayer class is the implementation of the decay"
      " of the W boson to the Standard Model fermions.");
 
   static ParVector<SMWDecayer,double> interfaceWquarkMax
     ("QuarkMax",
      "The maximum weight for the decay of the W to quarks",
      &SMWDecayer::quarkWeight_,
      0, 0, 0, -10000, 10000, false, false, true);
 
   static ParVector<SMWDecayer,double> interfaceWleptonMax
     ("LeptonMax",
      "The maximum weight for the decay of the W to leptons",
      &SMWDecayer::leptonWeight_,
      0, 0, 0, -10000, 10000, false, false, true);
 
   static Switch<SMWDecayer,bool> interfaceNLO
     ("NLO",
      "Whether to return the LO or NLO result",
      &SMWDecayer::NLO_, false, false, false);
   static SwitchOption interfaceNLOLO
     (interfaceNLO,
      "No",
      "Leading-order result",
      false);
   static SwitchOption interfaceNLONLO
     (interfaceNLO,
      "Yes",
      "NLO result",
      true);
 
 }
 
 
 // return the matrix element squared
 double SMWDecayer::me2(const int, const Particle & part,
 			const ParticleVector & decay,
 			MEOption meopt) const {
   if(!ME()) 
     ME(new_ptr(GeneralDecayMatrixElement(PDT::Spin1,PDT::Spin1Half,PDT::Spin1Half)));
   int iferm(1),ianti(0);
   if(decay[0]->id()>0) swap(iferm,ianti);
   if(meopt==Initialize) {
     VectorWaveFunction::calculateWaveFunctions(vectors_,rho_,
 					       const_ptr_cast<tPPtr>(&part),
 					       incoming,false);
+    // fix rho if no correlations
+    fixRho(rho_);
   }
   if(meopt==Terminate) {
     VectorWaveFunction::constructSpinInfo(vectors_,const_ptr_cast<tPPtr>(&part),
 					  incoming,true,false);
     SpinorBarWaveFunction::
       constructSpinInfo(wavebar_,decay[iferm],outgoing,true);
     SpinorWaveFunction::
       constructSpinInfo(wave_   ,decay[ianti],outgoing,true);
     return 0.;
   }
   SpinorBarWaveFunction::
     calculateWaveFunctions(wavebar_,decay[iferm],outgoing);
   SpinorWaveFunction::
     calculateWaveFunctions(wave_   ,decay[ianti],outgoing);
   // compute the matrix element
   Energy2 scale(sqr(part.mass()));
   for(unsigned int ifm=0;ifm<2;++ifm) {
     for(unsigned int ia=0;ia<2;++ia) {
       for(unsigned int vhel=0;vhel<3;++vhel) {
 	if(iferm>ianti) (*ME())(vhel,ia,ifm)=
 	  FFWVertex_->evaluate(scale,wave_[ia],wavebar_[ifm],vectors_[vhel]);
 	else            (*ME())(vhel,ifm,ia)=
 	  FFWVertex_->evaluate(scale,wave_[ia],wavebar_[ifm],vectors_[vhel]);
       }
     }
   }
   double output=(ME()->contract(rho_)).real()*UnitRemoval::E2/scale;
   if(abs(decay[0]->id())<=6) output*=3.;
   if(decay[0]->hasColour())      decay[0]->antiColourNeighbour(decay[1]);
   else if(decay[1]->hasColour()) decay[1]->antiColourNeighbour(decay[0]);
   // leading-order result
   if(!NLO_) return output;
   // check decay products coloured, otherwise return
   if(!decay[0]->dataPtr()->coloured()) return output;
   // inital masses, couplings  etc
   // W mass
   mW_ = part.mass();
   // strong coupling
   aS_ = SM().alphaS(sqr(mW_));
   // reduced mass
   double mu1  = (decay[0]->dataPtr()->mass())/mW_;
   double mu2  = (decay[1]->dataPtr()->mass())/mW_;
   // scale
   scale_ = sqr(mW_);
   // now for the nlo loop correction
   double virt = CF_*aS_/Constants::pi;
   // now for the real correction
   double realFact=0.;
   for(int iemit=0;iemit<2;++iemit) {
     double phi  = UseRandom::rnd()*Constants::twopi;
     // set the emitter and the spectator
     double muj  = iemit==0 ? mu1 : mu2;
     double muk  = iemit==0 ? mu2 : mu1;
     double muj2 = sqr(muj);
     double muk2 = sqr(muk);
     // calculate y
     double yminus = 0.; 
     double yplus  = 1.-2.*muk*(1.-muk)/(1.-muj2-muk2);
     double y = yminus + UseRandom::rnd()*(yplus-yminus);
     double v = sqrt(sqr(2.*muk2 + (1.-muj2-muk2)*(1.-y))-4.*muk2)
       /(1.-muj2-muk2)/(1.-y);
     double zplus  = (1.+v)*(1.-muj2-muk2)*y/2./(muj2+(1.-muj2-muk2)*y);
     double zminus = (1.-v)*(1.-muj2-muk2)*y/2./(muj2+(1.-muj2-muk2)*y);
     double z = zminus + UseRandom::rnd()*(zplus-zminus);
     double jac = (1.-y)*(yplus-yminus)*(zplus-zminus);
     // calculate x1,x2,x3,xT
     double x2 = 1.-y*(1.-muj2-muk2)-muj2+muk2;
     double x1 = 1.+muj2-muk2-z*(x2-2.*muk2);
     // copy the particle objects over for calculateRealEmission
     vector<PPtr> hardProcess(3);
     hardProcess[0] = const_ptr_cast<PPtr>(&part);
     hardProcess[1] = decay[0];
     hardProcess[2] = decay[1];
     realFact += 0.25*jac*sqr(1.-muj2-muk2)/
       sqrt((1.-sqr(muj-muk))*(1.-sqr(muj+muk)))/Constants::twopi
       *2.*CF_*aS_*calculateRealEmission(x1, x2, hardProcess, phi, 
 					muj, muk, iemit, true);
   }
   // the born + virtual + real
   output *= (1. + virt + realFact);
   return output;
 }
 
 void SMWDecayer::doinitrun() {
   PerturbativeDecayer::doinitrun();
   if(initialize()) {
     for(unsigned int ix=0;ix<numberModes();++ix) {
       if(ix<6) quarkWeight_ [ix]=mode(ix)->maxWeight();
       else     leptonWeight_[ix-6]=mode(ix)->maxWeight();
     }
   }
 }
 
 void SMWDecayer::dataBaseOutput(ofstream & output,
 				 bool header) const {
   if(header) output << "update decayers set parameters=\"";
   for(unsigned int ix=0;ix<quarkWeight_.size();++ix) {
     output << "newdef " << name() << ":QuarkMax " << ix << " "
 	   << quarkWeight_[ix] << "\n";
   }
   for(unsigned int ix=0;ix<leptonWeight_.size();++ix) {
     output << "newdef " << name() << ":LeptonMax " << ix << " "
 	   << leptonWeight_[ix] << "\n";
   }
   // parameters for the PerturbativeDecayer base class
   PerturbativeDecayer::dataBaseOutput(output,false);
   if(header) output << "\n\" where BINARY ThePEGName=\"" 
 		    << fullName() << "\";" << endl;
 }
 
 
 void SMWDecayer::
 initializeMECorrection(RealEmissionProcessPtr born, double & initial,
 		       double & final) {
   // get the quark and antiquark
   ParticleVector qq; 
   for(unsigned int ix=0;ix<born->bornOutgoing().size();++ix)
     qq.push_back(born->bornOutgoing()[ix]);
   // ensure quark first
   if(qq[0]->id()<0) swap(qq[0],qq[1]);
   // centre of mass energy
   d_Q_ = (qq[0]->momentum() + qq[1]->momentum()).m();
   // quark mass
   d_m_ = 0.5*(qq[0]->momentum().m()+qq[1]->momentum().m());
   // set the other parameters
   setRho(sqr(d_m_/d_Q_));
   setKtildeSymm();
   // otherwise can do it
   initial=1.;
   final  =1.;
 }
 
 bool SMWDecayer::softMatrixElementVeto(PPtr parent,
 				       PPtr progenitor,
 				       const bool & ,
 				       const Energy & highestpT,
 				       const vector<tcPDPtr> & ids,
 				       const double & d_z,
 				       const Energy & d_qt,
 				       const Energy & ) {
   // check we should be applying the veto
   if(parent->id()!=progenitor->id()||
      ids[0]!=ids[1]||
      ids[2]->id()!=ParticleID::g) return false;
   // calculate pt
   Energy2 d_m2 = parent->momentum().m2();
   Energy2 pPerp2 = sqr(d_z*d_qt) - d_m2;
   if(pPerp2<ZERO) return true;
   Energy pPerp = (1.-d_z)*sqrt(pPerp2);
   // if not hardest so far don't apply veto
   if(pPerp<highestpT) return false;
   // calculate the weight
   double weight = 0.;
   if(parent->id()>0) weight = qWeightX(d_qt, d_z);
   else weight = qbarWeightX(d_qt, d_z);
   // compute veto from weight and return
   return !UseRandom::rndbool(weight);
 }
 
 
 void SMWDecayer::setRho(double r) 
 { 
   d_rho_ = r;
   d_v_ = sqrt(1.-4.*d_rho_);
 }
 
 void SMWDecayer::setKtildeSymm() { 
   d_kt1_ = (1. + sqrt(1. - 4.*d_rho_))/2.;
   setKtilde2();
 }
 
 void SMWDecayer::setKtilde2() { 
    double num = d_rho_ * d_kt1_ + 0.25 * d_v_ *(1.+d_v_)*(1.+d_v_);
    double den = d_kt1_ - d_rho_;
    d_kt2_ = num/den;
 }
 
 double SMWDecayer::getZfromX(double x1, double x2) {
   double uval = u(x2);
   double num = x1 - (2. - x2)*uval;
   double den = sqrt(x2*x2 - 4.*d_rho_);
   return uval + num/den;
 }
 
 double SMWDecayer::getKfromX(double x1, double x2) {
    double zval = getZfromX(x1, x2);
    return (1.-x2)/(zval*(1.-zval));
 }
 
 double SMWDecayer::MEV(double x1, double x2) {
   // Vector part
   double num = (x1+2.*d_rho_)*(x1+2.*d_rho_) + (x2+2.*d_rho_)*(x2+2.*d_rho_) 
     - 8.*d_rho_*(1.+2.*d_rho_);
   double den = (1.+2.*d_rho_)*(1.-x1)*(1.-x2);
   return (num/den - 2.*d_rho_/((1.-x1)*(1.-x1)) 
 	  - 2*d_rho_/((1.-x2)*(1.-x2)))/d_v_;
 }
 
 double SMWDecayer::MEA(double x1, double x2) {
   // Axial part
   double num = (x1+2.*d_rho_)*(x1+2.*d_rho_) + (x2+2.*d_rho_)*(x2+2.*d_rho_) 
     + 2.*d_rho_*((5.-x1-x2)*(5.-x1-x2) - 19.0 + 4*d_rho_);
   double den = d_v_*d_v_*(1.-x1)*(1.-x2);
   return (num/den - 2.*d_rho_/((1.-x1)*(1.-x1)) 
 	  - 2*d_rho_/((1.-x2)*(1.-x2)))/d_v_;
 }
 
 double SMWDecayer::u(double x2) {
   return 0.5*(1. + d_rho_/(1.-x2+d_rho_));
 }
 
 void SMWDecayer::
 getXXbar(double kti, double z, double &x, double &xbar) {
   double w = sqr(d_v_) + kti*(-1. + z)*z*(2. + kti*(-1. + z)*z);
   if (w < 0) {
     x = -1.; 
     xbar = -1;
   } else {
     x = (1. + sqr(d_v_)*(-1. + z) + sqr(kti*(-1. + z))*z*z*z 
 	 + z*sqrt(w)
 	 - kti*(-1. + z)*z*(2. + z*(-2 + sqrt(w))))/
       (1. - kti*(-1. + z)*z + sqrt(w));
     xbar = 1. + kti*(-1. + z)*z;
   }
 }
 
 double SMWDecayer::qWeight(double x, double xbar) {
   double rval; 
   double xg = 2. - xbar - x;
   // always return one in the soft gluon region
   if(xg < EPS_) return 1.0;
   // check it is in the phase space
   if((1.-x)*(1.-xbar)*(1.-xg) < d_rho_*xg*xg) return 0.0;
   double k1 = getKfromX(x, xbar);
   double k2 = getKfromX(xbar, x);
   // Is it in the quark emission zone?
   if(k1 < d_kt1_) {
     rval = MEV(x, xbar)/PS(x, xbar);
     // is it also in the anti-quark emission zone?
     if(k2 < d_kt2_) rval *= 0.5;
     return rval;
   }
   return 1.0;
 }
 
 double SMWDecayer::qbarWeight(double x, double xbar) {
   double rval; 
   double xg = 2. - xbar - x;
   // always return one in the soft gluon region
   if(xg < EPS_) return 1.0;
   // check it is in the phase space
   if((1.-x)*(1.-xbar)*(1.-xg) < d_rho_*xg*xg) return 0.0;
   double k1 = getKfromX(x, xbar);
   double k2 = getKfromX(xbar, x);
   // Is it in the antiquark emission zone?
   if(k2 < d_kt2_) {
     rval = MEV(x, xbar)/PS(xbar, x);
     // is it also in the quark emission zone?
     if(k1 < d_kt1_) rval *= 0.5;
     return rval;
   }
   return 1.0;
 }
 
 double SMWDecayer::qWeightX(Energy qtilde, double z) {
   double x, xb;
   getXXbar(sqr(qtilde/d_Q_), z, x, xb);
   // if exceptionally out of phase space, leave this emission, as there 
   // is no good interpretation for the soft ME correction. 
   if (x < 0 || xb < 0) return 1.0; 
   return qWeight(x, xb); 
 }
 
 double SMWDecayer::qbarWeightX(Energy qtilde, double z) {
   double x, xb;
   getXXbar(sqr(qtilde/d_Q_), z, xb, x);
   // see above in qWeightX. 
   if (x < 0 || xb < 0) return 1.0; 
   return qbarWeight(x, xb); 
 }
 
 double SMWDecayer::PS(double x, double xbar) {
   double u = 0.5*(1. + d_rho_ / (1.-xbar+d_rho_));
   double z = u + (x - (2.-xbar)*u)/sqrt(xbar*xbar - 4.*d_rho_);
   double brack = (1.+z*z)/(1.-z)- 2.*d_rho_/(1-xbar);
   // interesting: the splitting function without the subtraction
   // term. Actually gives a much worse approximation in the collinear
   // limit.  double brack = (1.+z*z)/(1.-z);
   double den = (1.-xbar)*sqrt(xbar*xbar - 4.*d_rho_);
   return brack/den;
 }
 
 double SMWDecayer::matrixElementRatio(const Particle & inpart, const ParticleVector & decay2,
 				      const ParticleVector & decay3, MEOption,
 				      ShowerInteraction inter) {
   // extract partons and LO momentas
   vector<cPDPtr> partons(1,inpart.dataPtr());
   vector<Lorentz5Momentum> lomom(1,inpart.momentum());
   for(unsigned int ix=0;ix<2;++ix) {
     partons.push_back(decay2[ix]->dataPtr());
     lomom.push_back(decay2[ix]->momentum());
   }
   vector<Lorentz5Momentum> realmom(1,inpart.momentum());
   for(unsigned int ix=0;ix<3;++ix) {
     if(ix==2) partons.push_back(decay3[ix]->dataPtr());
     realmom.push_back(decay3[ix]->momentum());
   }
   if(partons[0]->id()<0) {
     swap(partons[1],partons[2]);
     swap(lomom[1],lomom[2]);
     swap(realmom[1],realmom[2]);
   }
   scale_ = sqr(inpart.mass());
   double     lome = loME(partons,lomom);
   InvEnergy2 reme = realME(partons,realmom,inter);
   double ratio = reme/lome*sqr(inpart.mass())*4.*Constants::pi;
   if(inter==ShowerInteraction::QCD) ratio *= CF_;
   return ratio;
 }
 
 double SMWDecayer::meRatio(vector<cPDPtr> partons, 
 			   vector<Lorentz5Momentum> momenta,
 			   unsigned int iemitter, bool subtract) const {
   Lorentz5Momentum q = momenta[1]+momenta[2]+momenta[3];
   Energy2 Q2=q.m2();
   Energy2 lambda = sqrt((Q2-sqr(momenta[1].mass()+momenta[2].mass()))*
 			(Q2-sqr(momenta[1].mass()-momenta[2].mass())));
   InvEnergy2 D[2];
   double lome(0.);
   for(unsigned int iemit=0;iemit<2;++iemit) {
     unsigned int ispect = iemit==0 ? 1 : 0;    
     Energy2 pipj = momenta[3      ] * momenta[1+iemit ];
     Energy2 pipk = momenta[3      ] * momenta[1+ispect];
     Energy2 pjpk = momenta[1+iemit] * momenta[1+ispect];
     double y = pipj/(pipj+pipk+pjpk); 
     double z = pipk/(     pipk+pjpk);
     Energy mij = sqrt(2.*pipj+sqr(momenta[1+iemit].mass()));
     Energy2 lamB = sqrt((Q2-sqr(mij+momenta[1+ispect].mass()))*
 			(Q2-sqr(mij-momenta[1+ispect].mass())));
     Energy2 Qpk = q*momenta[1+ispect];
     Lorentz5Momentum pkt = 
       lambda/lamB*(momenta[1+ispect]-Qpk/Q2*q)
       +0.5/Q2*(Q2+sqr(momenta[1+ispect].mass())-sqr(momenta[1+ispect].mass()))*q;
     Lorentz5Momentum pijt = 
       q-pkt;
     double muj = momenta[1+iemit ].mass()/sqrt(Q2);
     double muk = momenta[1+ispect].mass()/sqrt(Q2);
     double vt = sqrt((1.-sqr(muj+muk))*(1.-sqr(muj-muk)))/(1.-sqr(muj)-sqr(muk));
     double v  = sqrt(sqr(2.*sqr(muk)+(1.-sqr(muj)-sqr(muk))*(1.-y))-4.*sqr(muk))
       /(1.-y)/(1.-sqr(muj)-sqr(muk));
     // dipole term
     D[iemit] = 0.5/pipj*(2./(1.-(1.-z)*(1.-y))
 			 -vt/v*(2.-z+sqr(momenta[1+iemit].mass())/pipj));
     // matrix element
     vector<Lorentz5Momentum> lomom(3);
     lomom[0] = momenta[0];
     if(iemit==0) {
       lomom[1] = pijt;
       lomom[2] = pkt ;
     }
     else {
       lomom[2] = pijt;
       lomom[1] = pkt ;
     }
     if(iemit==0) lome  = loME(partons,lomom);
   }
   InvEnergy2 ratio = realME(partons,momenta,ShowerInteraction::QCD)/lome*abs(D[iemitter])
     /(abs(D[0])+abs(D[1]));
   if(subtract)
     return Q2*(ratio-2.*D[iemitter]);
   else
     return Q2*ratio;
 }
 
 double SMWDecayer::loME(const vector<cPDPtr> & partons, 
 			const vector<Lorentz5Momentum> & momenta) const {
   // compute the spinors
   vector<VectorWaveFunction>    vin;
   vector<SpinorWaveFunction>    aout;
   vector<SpinorBarWaveFunction> fout;
   VectorWaveFunction    win  (momenta[0],partons[0],incoming);
   SpinorBarWaveFunction qkout(momenta[1],partons[1],outgoing);
   SpinorWaveFunction    qbout(momenta[2],partons[2],outgoing);
   for(unsigned int ix=0;ix<2;++ix){
     qkout.reset(ix);
     fout.push_back(qkout);
     qbout.reset(ix);
     aout.push_back(qbout);
   }
   for(unsigned int ix=0;ix<3;++ix){
     win.reset(ix);
     vin.push_back(win);
   }
   // temporary storage of the different diagrams
   // sum over helicities to get the matrix element
   double total(0.);
   for(unsigned int inhel=0;inhel<3;++inhel) {
     for(unsigned int outhel1=0;outhel1<2;++outhel1) {
       for(unsigned int outhel2=0;outhel2<2;++outhel2) {
 	Complex diag1 = FFWVertex_->evaluate(scale_,aout[outhel2],fout[outhel1],vin[inhel]);
 	total += norm(diag1);
       }
     }
   }
   // return the answer
   return total;
 }
  
 InvEnergy2 SMWDecayer::realME(const vector<cPDPtr> & partons, 
 			      const vector<Lorentz5Momentum> & momenta,
 			      ShowerInteraction inter) const {
   // compute the spinors
   vector<VectorWaveFunction>     vin;
   vector<SpinorWaveFunction>     aout;
   vector<SpinorBarWaveFunction>  fout;
   vector<VectorWaveFunction>     gout;
   VectorWaveFunction    win  (momenta[0],partons[0],incoming);
   SpinorBarWaveFunction qkout(momenta[1],partons[1],outgoing);
   SpinorWaveFunction    qbout(momenta[2],partons[2],outgoing);
   VectorWaveFunction    gluon(momenta[3],partons[3],outgoing);
   for(unsigned int ix=0;ix<2;++ix){
     qkout.reset(ix);
     fout.push_back(qkout);
     qbout.reset(ix);
     aout.push_back(qbout);
     gluon.reset(2*ix);
     gout.push_back(gluon);
   }
   for(unsigned int ix=0;ix<3;++ix){
     win.reset(ix);
     vin.push_back(win);
   }
   vector<Complex> diag(3,0.);
 
   double total(0.);
 
   AbstractFFVVertexPtr vertex = inter==ShowerInteraction::QCD ? FFGVertex_ : FFPVertex_;
   
   for(unsigned int inhel1=0;inhel1<3;++inhel1) {
     for(unsigned int outhel1=0;outhel1<2;++outhel1) {
       for(unsigned int outhel2=0;outhel2<2;++outhel2) {
 	for(unsigned int outhel3=0;outhel3<2;++outhel3) {
 	  SpinorBarWaveFunction off1 =
 	    vertex->evaluate(scale_,3,partons[1]->CC(),fout[outhel1],gout[outhel3]);
 	  diag[0] = FFWVertex_->evaluate(scale_,aout[outhel2],off1,vin[inhel1]);
 	  
 	  SpinorWaveFunction off2 = 
 	    vertex->evaluate(scale_,3,partons[2]->CC(),aout[outhel2],gout[outhel3]);
 	  diag[1] = FFWVertex_->evaluate(scale_,off2,fout[outhel1],vin[inhel1]);
 
 	  if(inter==ShowerInteraction::QED) {
 	    VectorWaveFunction off3 =
 	      WWWVertex_->evaluate(scale_,3,partons[0],vin[inhel1],gout[outhel3]);
 	    diag[2] = FFWVertex_->evaluate(scale_,aout[outhel2],fout[outhel1],off3);
 	  }
 	  
 	  // sum of diagrams
 	  Complex sum = std::accumulate(diag.begin(),diag.end(),Complex(0.));
 	  // me2
 	  total += norm(sum);
 	}
       }
     }
   }
   // divide out the coupling
   total /= norm(vertex->norm());
   // double g = sqrt(2.)*abs(FFWVertex_->norm());
   // double xg = 2.*momenta[3].t()/momenta[0].mass();
   // double xe,mue2;
   // if(abs(partons[1]->id())==ParticleID::eminus) {
   //   xe = 2.*momenta[1].t()/momenta[0].mass();
   //   mue2 = sqr(momenta[1].mass()/momenta[0].mass());
   // }
   // else {
   //   xe = 2.*momenta[2].t()/momenta[0].mass();
   //   mue2 = sqr(momenta[2].mass()/momenta[0].mass());
   // }
   // double cg = -4. * g * g * (-pow(mue2, 3.) / 2. + (xg * xg / 4. + (xe / 2. + 1.) * xg + 5. / 2. * xe - 2.) * mue2 * mue2
   // 			     + (pow(xg, 3.) / 4. + (xe / 4. - 5. / 4.) * xg * xg + (-7. / 2. * xe + 3.) * xg - 3. * xe * xe
   // 				+ 11. / 2. * xe - 7. / 2.) * mue2 + (xg * xg / 2. + (xe - 2.) * xg + xe * xe - 2. * xe + 2.) * (-1. + xg + xe)) * (xe - mue2 - 1.) *
   //   pow(xg, -2.) * pow(-1. + xg + xe - mue2, -2.);
   
   // cerr << "real " << cg/total << "\n";
   // return the total
   return total*UnitRemoval::InvE2;
 }
 
 double SMWDecayer::calculateRealEmission(double x1, double x2, 
 					 vector<PPtr> hardProcess,
 					 double phi, double muj,
 					 double muk, int iemit, 
 					 bool subtract) const {
   // make partons data object for meRatio
   vector<cPDPtr> partons (3);
   for(int ix=0; ix<3; ++ix)
     partons[ix] = hardProcess[ix]->dataPtr();
   partons.push_back(gluon_);
   // calculate x3
   double x3 = 2.-x1-x2;
   double xT = sqrt(max(0.,sqr(x3)-0.25*sqr(sqr(x2)+sqr(x3)-sqr(x1)-4.*sqr(muk)+4.*sqr(muj))
 		       /(sqr(x2)-4.*sqr(muk))));
   // calculate the momenta
   Energy M = mW_;
   Lorentz5Momentum pspect(ZERO,ZERO,-0.5*M*sqrt(max(sqr(x2)-4.*sqr(muk),0.)),
 			  0.5*M*x2,M*muk); 
   Lorentz5Momentum pemit (-0.5*M*xT*cos(phi),-0.5*M*xT*sin(phi),
 			  0.5*M*sqrt(max(sqr(x1)-sqr(xT)-4.*sqr(muj),0.)),
 			  0.5*M*x1,M*muj);
   Lorentz5Momentum pgluon(0.5*M*xT*cos(phi), 0.5*M*xT*sin(phi),
 			  0.5*M*sqrt(max(sqr(x3)-sqr(xT),0.)),0.5*M*x3,ZERO);
   if(abs(pspect.z()+pemit.z()-pgluon.z())/M<1e-6) 
     pgluon.setZ(-pgluon.z());
   else if(abs(pspect.z()-pemit.z()+pgluon.z())/M<1e-6) 
     pemit .setZ(- pemit.z());
   // boost and rotate momenta
   LorentzRotation eventFrame( ( hardProcess[1]->momentum() +
 				hardProcess[2]->momentum() ).findBoostToCM() );
   Lorentz5Momentum spectator = eventFrame*hardProcess[iemit+1]->momentum();
   eventFrame.rotateZ( -spectator.phi()    );
   eventFrame.rotateY( -spectator.theta()  );
   eventFrame.invert();
   vector<Lorentz5Momentum> momenta(3);
   momenta[0]   = hardProcess[0]->momentum();
   if(iemit==0) {
     momenta[2] = eventFrame*pspect;
     momenta[1] = eventFrame*pemit ;
   }
   else {
     momenta[1] = eventFrame*pspect;
     momenta[2] = eventFrame*pemit ;
   }
   momenta.push_back(eventFrame*pgluon);
   // calculate the weight
   double realwgt(0.);
   if(1.-x1>1e-5 && 1.-x2>1e-5) 
     realwgt = meRatio(partons,momenta,iemit,subtract);
   return realwgt;
 }
diff --git a/Decay/Perturbative/SMZDecayer.cc b/Decay/Perturbative/SMZDecayer.cc
--- a/Decay/Perturbative/SMZDecayer.cc
+++ b/Decay/Perturbative/SMZDecayer.cc
@@ -1,1119 +1,1121 @@
 // -*- C++ -*-
 //
 // SMZDecayer.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 SMZDecayer class.
 //
 
 #include "SMZDecayer.h"
 #include "Herwig/Utilities/Maths.h"
 #include "ThePEG/Utilities/DescribeClass.h"
 #include "ThePEG/Interface/ClassDocumentation.h"
 #include "ThePEG/Interface/ParVector.h"
 #include "ThePEG/Interface/Reference.h"
 #include "ThePEG/Interface/Switch.h"
 #include "ThePEG/Persistency/PersistentOStream.h"
 #include "ThePEG/Persistency/PersistentIStream.h"
 #include "ThePEG/PDT/DecayMode.h"
 #include "Herwig/Decay/DecayVertex.h"
 #include "ThePEG/Helicity/VectorSpinInfo.h"
 #include "ThePEG/Helicity/FermionSpinInfo.h"
 #include "ThePEG/Helicity/WaveFunction/VectorWaveFunction.h"
 #include "Herwig/Models/StandardModel/StandardModel.h"
 #include "Herwig/Shower/RealEmissionProcess.h"
 #include "Herwig/Decay/GeneralDecayMatrixElement.h"
 #include <numeric>
 
 using namespace Herwig;
 using namespace ThePEG::Helicity;
 
 const double SMZDecayer::EPS_=0.00000001;
 
 SMZDecayer::SMZDecayer() 
   : quarkWeight_(5,0.), leptonWeight_(6,0.), CF_(4./3.),
     NLO_(false) {
    quarkWeight_[0]  = 0.488029;
    quarkWeight_[1]  = 0.378461;
    quarkWeight_[2]  = 0.488019;
    quarkWeight_[3]  = 0.378027;
    quarkWeight_[4]  = 0.483207;
    leptonWeight_[0] = 0.110709;
    leptonWeight_[1] = 0.220276;
    leptonWeight_[2] = 0.110708;
    leptonWeight_[3] = 0.220276;
    leptonWeight_[4] = 0.110458;
    leptonWeight_[5] = 0.220276;
    // intermediates
    generateIntermediates(false);
    // QED corrections
   hasRealEmissionME(true);
   hasOneLoopME(true);
 }
 
 void SMZDecayer::doinit() {
   PerturbativeDecayer::doinit();
   // get the vertices from the Standard Model object
   tcHwSMPtr hwsm=dynamic_ptr_cast<tcHwSMPtr>(standardModel());
   if(!hwsm) throw InitException() << "Must have Herwig StandardModel object in"
 				  << "SMZDecayer::doinit()"
 				  << Exception::runerror;
   // cast the vertices
   FFZVertex_ = dynamic_ptr_cast<FFVVertexPtr>(hwsm->vertexFFZ());
   FFZVertex_->init();
   FFGVertex_ = hwsm->vertexFFG();
   FFGVertex_->init();
   FFPVertex_ = hwsm->vertexFFP();
   FFPVertex_->init();
   gluon_ = getParticleData(ParticleID::g);
   // now set up the decay modes
   DecayPhaseSpaceModePtr mode;
   tPDVector extpart(3);
   vector<double> wgt(0);
   // the Z decay modes
   extpart[0]=getParticleData(ParticleID::Z0);
   // loop over the  quarks and the leptons
   for(int istep=0;istep<11;istep+=10) {
     for(int ix=1;ix<7;++ix) {
       int iy=istep+ix;
       if(iy==6) continue;
       extpart[1] = getParticleData(-iy);
       extpart[2] = getParticleData( iy);
       mode = new_ptr(DecayPhaseSpaceMode(extpart,this));
       if(iy<=6) addMode(mode,  quarkWeight_.at(ix-1),wgt);
       else      addMode(mode,leptonWeight_.at(iy-11),wgt);
     }
   }
 }
 
 int SMZDecayer::modeNumber(bool & cc,tcPDPtr parent, 
 			    const tPDVector & children) const {
   int imode(-1);
   if(children.size()!=2) return imode;
   int id0=parent->id();
   tPDVector::const_iterator pit = children.begin();
   int id1=(**pit).id();
   ++pit;
   int id2=(**pit).id();
   // Z to quarks or leptons
   cc =false;
   if(id0!=ParticleID::Z0) return imode;
   if(abs(id1)<6&&id1==-id2) {
     imode=abs(id1)-1;
   }
   else if(abs(id1)>=11&&abs(id1)<=16&&id1==-id2) {
     imode=abs(id1)-6;
   }
   cc = false;
   return imode;
 }
 
 void SMZDecayer::persistentOutput(PersistentOStream & os) const {
   os << FFZVertex_ << FFPVertex_ << FFGVertex_
      << quarkWeight_ << leptonWeight_ << NLO_
      << gluon_;
 }
 
 void SMZDecayer::persistentInput(PersistentIStream & is, int) {
   is >> FFZVertex_ >> FFPVertex_ >> FFGVertex_
      >> quarkWeight_ >> leptonWeight_ >> NLO_
      >> gluon_;
 }
 
 // The following static variable is needed for the type
 // description system in ThePEG.
 DescribeClass<SMZDecayer,PerturbativeDecayer>
 describeHerwigSMZDecayer("Herwig::SMZDecayer", "HwPerturbativeDecay.so");
 
 void SMZDecayer::Init() {
 
   static ClassDocumentation<SMZDecayer> documentation
     ("The SMZDecayer class is the implementation of the decay"
      " Z boson to the Standard Model fermions.");
 
   static ParVector<SMZDecayer,double> interfaceZquarkMax
     ("QuarkMax",
      "The maximum weight for the decay of the Z to quarks",
      &SMZDecayer::quarkWeight_,
      0, 0, 0, -10000, 10000, false, false, true);
 
   static ParVector<SMZDecayer,double> interfaceZleptonMax
     ("LeptonMax",
      "The maximum weight for the decay of the Z to leptons",
      &SMZDecayer::leptonWeight_,
      0, 0, 0, -10000, 10000, false, false, true);
 
   static Switch<SMZDecayer,bool> interfaceNLO
     ("NLO",
      "Whether to return the LO or NLO result",
      &SMZDecayer::NLO_, false, false, false);
   static SwitchOption interfaceNLOLO
     (interfaceNLO,
      "No",
      "Leading-order result",
      false);
   static SwitchOption interfaceNLONLO
     (interfaceNLO,
      "Yes",
      "NLO result",
      true);
 
 }
 
 // return the matrix element squared
 double SMZDecayer::me2(const int, const Particle & part,
 			const ParticleVector & decay,
 			MEOption meopt) const {
   if(!ME())
     ME(new_ptr(GeneralDecayMatrixElement(PDT::Spin1,PDT::Spin1Half,PDT::Spin1Half)));
   int iferm(1),ianti(0);
   if(decay[0]->id()>0) swap(iferm,ianti);
   if(meopt==Initialize) {
     VectorWaveFunction::calculateWaveFunctions(_vectors,_rho,
 					       const_ptr_cast<tPPtr>(&part),
 					       incoming,false);
+    // fix rho if no correlations
+    fixRho(_rho);
   }
   if(meopt==Terminate) {
     VectorWaveFunction::constructSpinInfo(_vectors,const_ptr_cast<tPPtr>(&part),
 					  incoming,true,false);
     SpinorBarWaveFunction::
       constructSpinInfo(_wavebar,decay[iferm],outgoing,true);
     SpinorWaveFunction::
       constructSpinInfo(_wave   ,decay[ianti],outgoing,true);
     return 0.;
   }
   SpinorBarWaveFunction::
     calculateWaveFunctions(_wavebar,decay[iferm],outgoing);
   SpinorWaveFunction::
     calculateWaveFunctions(_wave   ,decay[ianti],outgoing);
   // compute the matrix element
   Energy2 scale(sqr(part.mass()));
   unsigned int ifm,ia,vhel;
   for(ifm=0;ifm<2;++ifm) {
     for(ia=0;ia<2;++ia) {
       for(vhel=0;vhel<3;++vhel) {
 	if(iferm>ianti) (*ME())(vhel,ia,ifm)=
 	  FFZVertex_->evaluate(scale,_wave[ia],_wavebar[ifm],_vectors[vhel]);
 	else            (*ME())(vhel,ifm,ia)=
 	  FFZVertex_->evaluate(scale,_wave[ia],_wavebar[ifm],_vectors[vhel]);
       }
     }
   }
   double output=(ME()->contract(_rho)).real()*UnitRemoval::E2/scale;
   if(abs(decay[0]->id())<=6) output*=3.;
   if(decay[0]->hasColour())      decay[0]->antiColourNeighbour(decay[1]);
   else if(decay[1]->hasColour()) decay[1]->antiColourNeighbour(decay[0]);
   // if LO return
   if(!NLO_) return output;  // check decay products coloured, otherwise return
   if(!decay[0]->dataPtr()->coloured()) return output;
   // inital masses, couplings  etc
   // fermion mass
   Energy particleMass = decay[0]->dataPtr()->mass();
   // Z mass
   mZ_ = part.mass();
   // strong coupling
   aS_ = SM().alphaS(sqr(mZ_));
   // reduced mass
   mu_  = particleMass/mZ_;
   mu2_ = sqr(mu_);
   // scale
   scale_ = sqr(mZ_);
   // compute the spinors
   vector<SpinorWaveFunction>    aout;
   vector<SpinorBarWaveFunction> fout;
   vector<VectorWaveFunction>    vin;
   SpinorBarWaveFunction qkout(decay[0]->momentum(),decay[0]->dataPtr(),outgoing);
   SpinorWaveFunction    qbout(decay[1]->momentum(),decay[1]->dataPtr(),outgoing);
   VectorWaveFunction    zin  (part.momentum()     ,part.dataPtr()     ,incoming);
   for(unsigned int ix=0;ix<2;++ix){
     qkout.reset(ix);
     fout.push_back(qkout);
     qbout.reset(ix);
     aout.push_back(qbout);
   }
   for(unsigned int ix=0;ix<3;++ix){
     zin.reset(ix);
     vin.push_back(zin);
   }
   // temporary storage of the different diagrams
   // sum over helicities to get the matrix element
   double total=0.;
   if(mu_!=0.) {
     LorentzPolarizationVector momDiff = 
       (decay[0]->momentum()-decay[1]->momentum())/2./
       (decay[0]->momentum().mass()+decay[1]->momentum().mass());
     // scalars
     Complex scalar1 = zin.wave().dot(momDiff);
     for(unsigned int outhel1=0;outhel1<2;++outhel1) {
       for(unsigned int outhel2=0;outhel2<2;++outhel2) {		
 	for(unsigned int inhel=0;inhel<3;++inhel) {
 	  // first the LO bit
 	  Complex diag1 = FFZVertex_->evaluate(scale_,aout[outhel2],
 					       fout[outhel1],vin[inhel]);
 	  // extra stuff for NLO 
 	  LorentzPolarizationVector left  = 
 	    aout[outhel2].wave().leftCurrent(fout[outhel1].wave());
 	  LorentzPolarizationVector right = 
 	    aout[outhel2].wave().rightCurrent(fout[outhel1].wave());
 	  Complex scalar = 
 	    aout[outhel2].wave().scalar(fout[outhel1].wave());
 	  // nlo specific pieces
 	  Complex diag3 =
 	    Complex(0.,1.)*FFZVertex_->norm()*
 	    (FFZVertex_->right()*( left.dot(zin.wave())) +
 	     FFZVertex_-> left()*(right.dot(zin.wave())) -
 	     ( FFZVertex_-> left()+FFZVertex_->right())*scalar1*scalar);
 	  // nlo piece
 	  total += real(diag1*conj(diag3) + diag3*conj(diag1));
 	}
       }
     }
     // rescale
     total *= UnitRemoval::E2/scale_;
   }
   else {
     total = ZERO;
   }
   // now for the NLO bit
   double mu4 = sqr(mu2_);
   double lmu = mu_!=0. ? log(mu_) : 0.;
   double v = sqrt(1.-4.*mu2_),v2(sqr(v));
   double omv = 4.*mu2_/(1.+v);
   double f1,f2,fNS,VNS;
   double r = omv/(1.+v);
   double lr = mu_!=0. ? log(r) : 0.;
   // normal form
   if(mu_>1e-4) {
     f1 = CF_*aS_/Constants::pi*
       ( +1. + 3.*log(0.5*(1.+v)) - 1.5*log(0.5*(1.+v2)) + sqr(Constants::pi)/6.
 	- 0.5*sqr(lr) - (1.+v2)/v*(lr*log(1.+v2) + sqr(Constants::pi)/12. 
 				       -0.5*log(4.*mu2_)*lr + 0.25*sqr(lr)));
     fNS = -0.5*(1.+2.*v2)*lr/v + 1.5*lr - 2./3.*sqr(Constants::pi) + 0.5*sqr(lr)
       + (1.+v2)/v*(Herwig::Math::ReLi2(r) + sqr(Constants::pi)/3. - 0.25*sqr(lr) 
 		   + lr*log((2.*v/ (1.+v))));
     VNS = 1.5*log(0.5*(1.+v2)) 
       + 0.5*(1.+v2)/v*( 2.*lr*log(2.*(1.+v2)/sqr(1.+v))  
 			+ 2.*Herwig::Math::ReLi2(sqr(r)) 
 			- 2.*Herwig::Math::ReLi2(2.*v/(1.+v)) - sqr(Constants::pi)/6.)
       + log(1.-mu_) - 2.*log(1.-2.*mu_) - 4.*mu2_/(1.+v2)*log(mu_/(1.-mu_)) 
       - mu_/(1.-mu_)
       + 4.*(2.*mu2_-mu_)/(1.+v2) + 0.5*sqr(Constants::pi); 
     f2 = CF_*aS_/Constants::pi*mu2_*lr/v;
   }
   // small mass limit
   else {
     f1 = -CF_*aS_/Constants::pi/6.*
       ( - 6. - 24.*lmu*mu2_ - 15.*mu4 - 12.*mu4*lmu - 24.*mu4*sqr(lmu) 
 	+ 2.*mu4*sqr(Constants::pi) - 12.*mu2_*mu4 - 96.*mu2_*mu4*sqr(lmu) 
 	+ 8.*mu2_*mu4*sqr(Constants::pi) - 80.*mu2_*mu4*lmu);
     fNS = - mu2_/18.*( + 36.*lmu - 36. - 45.*mu2_ + 216.*lmu*mu2_ - 24.*mu2_*sqr(Constants::pi) 
 		      + 72.*mu2_*sqr(lmu) - 22.*mu4 + 1032.*mu4 * lmu
 		      - 96.*mu4*sqr(Constants::pi) + 288.*mu4*sqr(lmu));
     VNS = - mu2_/1260.*(-6930. + 7560.*lmu + 2520.*mu_ - 16695.*mu2_ 
 		       + 1260.*mu2_*sqr(Constants::pi) 
 		       + 12600.*lmu*mu2_ + 1344.*mu_*mu2_ - 52780.*mu4 + 36960.*mu4*lmu 
 		       + 5040.*mu4*sqr(Constants::pi) - 12216.*mu_*mu4);
     f2 = CF_*aS_*mu2_/Constants::pi*( 2.*lmu + 4.*mu2_*lmu + 2.*mu2_ + 12.*mu4*lmu + 7.*mu4);
   }
   // add up bits for f1
   f1 += CF_*aS_/Constants::pi*(fNS+VNS);
   double realFact(0.); 
   for(int iemit=0;iemit<2;++iemit) {
     // now for the real correction
     double phi  = UseRandom::rnd()*Constants::twopi;
     // calculate y
     double yminus = 0.; 
     double yplus  = 1.-2.*mu_*(1.-mu_)/(1.-2*mu2_);
     double y = yminus + UseRandom::rnd()*(yplus-yminus);
     // calculate z
     double v1  = sqrt(sqr(2.*mu2_+(1.-2.*mu2_)*(1.-y))-4.*mu2_)/(1.-2.*mu2_)/(1.-y);
     double zplus  = (1.+v1)*(1.-2.*mu2_)*y/2./(mu2_ +(1.-2.*mu2_)*y);
     double zminus = (1.-v1)*(1.-2.*mu2_)*y/2./(mu2_ +(1.-2.*mu2_)*y);
     double z = zminus + UseRandom::rnd()*(zplus-zminus);
     double jac = (1.-y)*(yplus-yminus)*(zplus-zminus);
     // calculate x1,x2
     double x2 = 1. - y*(1.-2.*mu2_);
     double x1 = 1. - z*(x2-2.*mu2_);
     // copy the particle objects over for calculateRealEmission
     vector<PPtr> hardProcess(3);
     hardProcess[0] = const_ptr_cast<PPtr>(&part);
     hardProcess[1] = decay[0];
     hardProcess[2] = decay[1];
     // total real emission contribution
     realFact += 0.25*jac*sqr(1.-2.*mu2_)/
     sqrt(1.-4.*mu2_)/Constants::twopi
       *2.*CF_*aS_*calculateRealEmission(x1, x2, hardProcess, phi,
 					iemit, true);
   }
   // the born + virtual + real
   output = output*(1. + f1 + realFact) + f2*total;
   return output;
 }
 
 void SMZDecayer::doinitrun() {
   PerturbativeDecayer::doinitrun();
   if(initialize()) {
     for(unsigned int ix=0;ix<numberModes();++ix) {
       if(ix<5)       quarkWeight_ [ix   ]=mode(ix)->maxWeight();
       else if(ix<11) leptonWeight_[ix-5 ]=mode(ix)->maxWeight();
     }
   }
 }
 
 void SMZDecayer::dataBaseOutput(ofstream & output,
 				 bool header) const {
   if(header) output << "update decayers set parameters=\"";
   for(unsigned int ix=0;ix<quarkWeight_.size();++ix) {
     output << "newdef " << name() << ":QuarkMax " << ix << " "
 	   << quarkWeight_[ix] << "\n";
   }
   for(unsigned int ix=0;ix<leptonWeight_.size();++ix) {
     output << "newdef " << name() << ":LeptonMax " << ix << " "
 	   << leptonWeight_[ix] << "\n";
   }
   // parameters for the PerturbativeDecayer base class
   PerturbativeDecayer::dataBaseOutput(output,false);
   if(header) output << "\n\" where BINARY ThePEGName=\"" 
 		    << fullName() << "\";" << endl;
 }
 
 InvEnergy2 SMZDecayer::
 realEmissionME(unsigned int,const Particle &parent, 
 	       ParticleVector &children,
 	       unsigned int iemitter,
 	       double ctheta, double stheta,
 	       const LorentzRotation & rot1,
 	       const LorentzRotation & rot2) {
   // check the number of products and parent
   assert(children.size()==3 && parent.id()==ParticleID::Z0);
   // the electric charge
   double e = sqrt(SM().alphaEM()*4.*Constants::pi);
   // azimuth of the photon
   double phi = children[2]->momentum().phi();
   // wavefunctions for the decaying particle in the rotated dipole frame
   vector<VectorWaveFunction> vec1 = _vectors;
   for(unsigned int ix=0;ix<vec1.size();++ix) {
     vec1[ix].transform(rot1);
     vec1[ix].transform(rot2);
   }
   // wavefunctions for the decaying particle in the rotated rest frame
   vector<VectorWaveFunction> vec2 = _vectors;
   for(unsigned int ix=0;ix<vec1.size();++ix) {
     vec2[ix].transform(rot2);
   }
   // find the outgoing particle and antiparticle
   unsigned int iferm(0),ianti(1);
   if(children[iferm]->id()<0) swap(iferm,ianti);
   // wavefunctions for the particles before the radiation
   // wavefunctions for the outgoing fermion
   SpinorBarWaveFunction wavebartemp;
   Lorentz5Momentum ptemp =  - _wavebar[0].momentum();
   ptemp *= rot2;
   if(ptemp.perp()/ptemp.e()<1e-10) {
     ptemp.setX(ZERO);
     ptemp.setY(ZERO);
   }
   wavebartemp = SpinorBarWaveFunction(ptemp,_wavebar[0].particle(),outgoing);
   // wavefunctions for the outgoing antifermion
   SpinorWaveFunction wavetemp;
   ptemp =  - _wave[0].momentum();
   ptemp *= rot2;
   if(ptemp.perp()/ptemp.e()<1e-10) {
     ptemp.setX(ZERO);
     ptemp.setY(ZERO);
   }
   wavetemp = SpinorWaveFunction(ptemp,_wave[0].particle(),outgoing);
   // loop over helicities
   vector<SpinorWaveFunction> wf_old;
   vector<SpinorBarWaveFunction> wfb_old;
   for(unsigned int ihel=0;ihel<2;++ihel) {
     wavetemp.reset(ihel);
     wf_old.push_back(wavetemp);
     wavebartemp.reset(ihel);
     wfb_old.push_back(wavebartemp);
   }
   // calculate the wave functions for the new fermions
   // ensure the momenta have pT=0
   for(unsigned int ix=0;ix<2;++ix) {
     Lorentz5Momentum ptemp = children[ix]->momentum();
     if(ptemp.perp()/ptemp.e()<1e-10) {
       ptemp.setX(ZERO);
       ptemp.setY(ZERO);
       children[ix]->set5Momentum(ptemp);
     }
   }
   // calculate the wavefunctions
   vector<SpinorBarWaveFunction> wfb;
   SpinorBarWaveFunction::calculateWaveFunctions(wfb,children[iferm],outgoing);
   vector<SpinorWaveFunction> wf;
   SpinorWaveFunction::calculateWaveFunctions   (wf ,children[ianti],outgoing);
   // wave functions for the photons
   vector<VectorWaveFunction> photon;
   VectorWaveFunction::calculateWaveFunctions(photon,children[2],outgoing,true);
   // loop to calculate the matrix elements
   Complex lome[3][2][2],diffme[3][2][2][2],summe[3][2][2][2];
   Energy2 scale(sqr(parent.mass()));
   Complex diff[2]={0.,0.};
   Complex sum [2]={0.,0.};
   for(unsigned int ifm=0;ifm<2;++ifm) {
     for(unsigned int ia=0;ia<2;++ia) {
       for(unsigned int vhel=0;vhel<3;++vhel) {
 	// calculation of the leading-order matrix element
 	Complex loamp  = FFZVertex_->evaluate(scale,wf_old[ia],
 					      wfb_old[ifm],vec2[vhel]);
 	Complex lotemp = FFZVertex_->evaluate(scale,wf[ia],
 					      wfb[ifm],vec1[vhel]);
 	if(iferm>ianti) lome[vhel][ia][ifm] = loamp;
 	else            lome[vhel][ifm][ia] = loamp;
 	// photon loop for the real emmision terms
 	for(unsigned int phel=0;phel<2;++phel) {
 	  // radiation from the antifermion
 	  // normal case with small angle treatment
 	  if(children[2    ]->momentum().z()/
 	     children[iferm]->momentum().z()>=ZERO && iemitter == iferm ) {
 	    Complex dipole = e*double(children[iferm]->dataPtr()->iCharge())/3.*
 	      UnitRemoval::E*loamp*
 	      (children[iferm]->momentum()*photon[2*phel].wave())/
 	      (children[iferm]->momentum()*children[2]->momentum());
 	    // sum and difference
 	    SpinorBarWaveFunction foff =
 	      FFPVertex_->evaluateSmall(ZERO,3,children[iferm]->dataPtr()->CC(),
 					wfb[ifm],photon[2*phel],
 					ifm,2*phel,ctheta,phi,stheta,false);
 	    diff[0] = FFZVertex_->evaluate(scale,wf[ia],foff,vec1[vhel]) +
 	      e*double(children[iferm]->dataPtr()->iCharge())/3.*
 	      UnitRemoval::E*(lotemp-loamp)*
 	      (children[iferm]->momentum()*photon[2*phel].wave())/
 	      (children[iferm]->momentum()*children[2]->momentum());
 	    sum [0] = diff[0]+2.*dipole;
 	  }
 	  // special if fermion backwards
 	  else {
 	    SpinorBarWaveFunction foff = 
 	      FFPVertex_->evaluate(ZERO,3,children[iferm]->dataPtr()->CC(),
 				   wfb[ifm],photon[2*phel]);
 	    Complex diag = 
 	      FFZVertex_->evaluate(scale,wf[ia],foff,vec1[vhel]);
 	    Complex dipole = e*double(children[iferm]->dataPtr()->iCharge())/3.*
 	      UnitRemoval::E*loamp*
 	      (children[iferm]->momentum()*photon[2*phel].wave())/
 	      (children[iferm]->momentum()*children[2]->momentum());
 	    diff[0] = diag-dipole;
 	    sum [0] = diag+dipole;
 	  }
 	  // radiation from the anti fermion 
 	  // small angle case in general
 	  if(children[2    ]->momentum().z()/
 	     children[ianti]->momentum().z()>=ZERO && iemitter == ianti ) {
 	    Complex dipole = e*double(children[ianti]->dataPtr()->iCharge())/3.*
 	      UnitRemoval::E*loamp*
 	      (children[ianti]->momentum()*photon[2*phel].wave())/
 	      (children[ianti]->momentum()*children[2]->momentum());
 	    // sum and difference
 	    SpinorWaveFunction foff =
 	      FFPVertex_->evaluateSmall(ZERO,3,children[ianti]->dataPtr()->CC(),
 					wf[ia],photon[2*phel],
 					ia,2*phel,ctheta,phi,stheta,false);
 	    diff[1] = FFZVertex_->evaluate(scale,foff ,wfb[ifm],vec1[vhel]) +
 	      e*double(children[ianti]->dataPtr()->iCharge())/3.*
 	      UnitRemoval::E*(lotemp-loamp)*
 	      (children[ianti]->momentum()*photon[2*phel].wave())/
 	      (children[ianti]->momentum()*children[2]->momentum());
 	    sum [1] = diff[1]+2.*dipole;
 	  }	    
 	  // special if fermion backwards after radiation
 	  else {
 	    SpinorWaveFunction foff = 
 	      FFPVertex_->evaluate(ZERO,3,children[ianti]->dataPtr()->CC(),
 				   wf[ia],photon[2*phel]);
 	    Complex diag = 
 	      FFZVertex_->evaluate(scale,foff ,wfb[ifm],vec1[vhel]);
 	    Complex dipole = e*double(children[ianti]->dataPtr()->iCharge())/3.*
 	      UnitRemoval::E*loamp*
 	      (children[ianti]->momentum()*photon[2*phel].wave())/
 	      (children[ianti]->momentum()*children[2]->momentum());
 	    // sum and difference
 	    diff[1] = diag - dipole;
 	    sum [1] = diag + dipole;
 	  }
 	  // add to me
 	  if(iferm>ianti) {
 	    diffme[vhel][ia][ifm][phel] = diff[0] + diff[1];
 	    summe [vhel][ia][ifm][phel] = sum[0]  + sum[1] ;
 	  }
 	  else {
 	    diffme  [vhel][ifm][ia][phel] = diff[0] + diff[1];
 	    summe   [vhel][ifm][ia][phel] = sum[0]  + sum[1] ;
 	  }
 	}
       }
     }
   }
 //   cerr << parent << "\n";
 //   for(unsigned int ix=0;ix<children.size();++ix) {
 //     cerr << *children[ix] << "\n";
 //   }
 //   _rho = RhoDMatrix(PDT::Spin1);
   Complex lo(0.),difference(0.);
   for(unsigned int vhel1=0;vhel1<3;++vhel1) {
     for(unsigned int vhel2=0;vhel2<3;++vhel2) {
       for(unsigned int ifm=0;ifm<2;++ifm) {
 	for(unsigned int ia=0;ia<2;++ia) {
 	  lo += _rho(vhel1,vhel2)*lome[vhel1][ifm][ia]*conj(lome[vhel2][ifm][ia]);
 	  for(unsigned int phel=0;phel<2;++phel) {
 	    difference += 
 	      _rho(vhel1,vhel2)*diffme[vhel1][ifm][ia][phel]*conj(summe[vhel2][ifm][ia][phel]);
 	  }
 	}
       }
     }
   }
 //   // analytic result
 //   double iCharge = children[0]->dataPtr()->iCharge()*
 //     children[1]->dataPtr()->iCharge()/9.;
 //   Energy2 ubar = 2.*children[0]->momentum()*children[2]->momentum();
 //   Energy2 tbar = 2.*children[1]->momentum()*children[2]->momentum();
 //   double mu2 = sqr(children[1]->mass()/parent.mass());
 //   double gL = (FFZVertex_->left() *FFZVertex_->norm()).real();
 //   double gR = (FFZVertex_->right()*FFZVertex_->norm()).real();
 //   Energy2 den = sqr(parent.mass())*(((sqr(gL)+sqr(gR))*(1-mu2)+6.*mu2*gL*gR));
 
 //   InvEnergy2 anal =  -iCharge*( 2.*(ubar/tbar+tbar/ubar)/sqr(parent.mass())+
 // 				4.*mu2/den*((sqr(gL)+sqr(gR))*(1+ubar/tbar+tbar/ubar)
 // 					    -2.*gL*gR*(1.+2.*(ubar/tbar+tbar/ubar))));
 //   cerr << "testing ratio " << parent.PDGName() 
 //        << " " << difference.real()/sqr(e)/lo.real()*UnitRemoval::InvE2/(anal) << "\n"
 //        << stheta << " " << ctheta << "\n";
   return difference.real()/sqr(e)/lo.real()*UnitRemoval::InvE2;
 }
 
 double SMZDecayer::oneLoopVirtualME(unsigned int,
 				    const Particle & parent, 
 				    const ParticleVector & children) {
   assert(children.size()==2);
   // velocities of the particles
   double beta = sqrt(1.-4.*sqr(children[0]->mass()/parent.mass()));
   double opb = 1.+beta;
   double omb = 4.*sqr(children[0]->mass()/parent.mass())/opb;
   // couplings
   double gL = (FFZVertex_->left() *FFZVertex_->norm()).real();
   double gR = (FFZVertex_->right()*FFZVertex_->norm()).real();
   double gA = 0.5*(gL-gR);
   double gV = 0.5*(gL+gR);
   // correction terms
   double ln = log(omb/opb);
   double f1 = 1. + ln*beta;
   double fA = 1. + ln/beta;
   InvEnergy f2 = 0.5*sqrt(omb*opb)/parent.mass()/beta*ln;
   // momentum difference for the loop
   Lorentz5Momentum q = children[0]->momentum()-children[1]->momentum();
   if(children[0]->id()<0) q *= -1.;
   // spinors
   vector<LorentzSpinor   <SqrtEnergy> > sp;
   vector<LorentzSpinorBar<SqrtEnergy> > sbar;
   for(unsigned int ix=0;ix<2;++ix) {
     sp  .push_back(   _wave[ix].dimensionedWave());
     sbar.push_back(_wavebar[ix].dimensionedWave());
   }
   // polarization vectors
   vector<LorentzPolarizationVector> pol;
   for(unsigned int ix=0;ix<3;++ix)
     pol.push_back(_vectors[ix].wave());
   // matrix elements
   complex<Energy> lome[3][2][2],loopme[3][2][2];
   for(unsigned int vhel=0;vhel<3;++vhel) {
     for(unsigned int ihel1=0;ihel1<2;++ihel1) {
       for(unsigned int ihel2=0;ihel2<2;++ihel2) {
 	complex<Energy> vector = 
 	  sp[ihel1].generalCurrent(sbar[ihel2], 1.,1.).dot(pol[vhel]);
 	complex<Energy>  axial = 
 	  sp[ihel1].generalCurrent(sbar[ihel2],-1.,1.).dot(pol[vhel]);
 	complex<Energy2> scalar =
 	  sp[ihel1].scalar(sbar[ihel2])*(q*pol[vhel]);
 	lome  [vhel][ihel1][ihel2] = gV*   vector-gA*   axial;
 	loopme[vhel][ihel1][ihel2] = gV*f1*vector-gA*fA*axial+scalar*f2*gV;
       }
     }
   }
   // sum sums
   complex<Energy2> den(ZERO),num(ZERO);
   for(unsigned int vhel1=0;vhel1<3;++vhel1) {
     for(unsigned int vhel2=0;vhel2<3;++vhel2) {
       for(unsigned int ihel1=0;ihel1<2;++ihel1) {
 	for(unsigned int ihel2=0;ihel2<2;++ihel2) {
 	  num += _rho(vhel1,vhel2)*
 	    (  lome[vhel1][ihel1][ihel2]*conj(loopme[vhel2][ihel1][ihel2])+
 	     loopme[vhel1][ihel1][ihel2]*conj(  lome[vhel2][ihel1][ihel2]));
 	  den += _rho(vhel1,vhel2)*
 	    lome[vhel1][ihel1][ihel2]*conj(lome[vhel2][ihel1][ihel2]);
 	}
       }
     }
   }
   // prefactor
   double iCharge = children[0]->dataPtr()->iCharge()*
                    children[1]->dataPtr()->iCharge()/9.;
   double pre = 0.5*SM().alphaEM()*iCharge/Constants::pi;
   // output
   return pre*num.real()/den.real();
 }
 
 
 void SMZDecayer::
 initializeMECorrection(RealEmissionProcessPtr born, double & initial,
 		       double & final) {
   // get the quark and antiquark
   ParticleVector qq; 
   for(unsigned int ix=0;ix<born->bornOutgoing().size();++ix)
     qq.push_back(born->bornOutgoing()[ix]);
   // ensure quark first
   if(qq[0]->id()<0) swap(qq[0],qq[1]);
   // centre of mass energy
   d_Q_ = (qq[0]->momentum() + qq[1]->momentum()).m();
   // quark mass
   d_m_ = 0.5*(qq[0]->momentum().m()+qq[1]->momentum().m());
   // set the other parameters
   setRho(sqr(d_m_/d_Q_));
   setKtildeSymm();
   // otherwise can do it
   initial=1.;
   final  =1.;
 }
 
 bool SMZDecayer::softMatrixElementVeto(PPtr parent,
 				       PPtr progenitor,
 				       const bool & ,
 				       const Energy & highestpT,
 				       const vector<tcPDPtr> & ids,
 				       const double & d_z,
 				       const Energy & d_qt,
 				       const Energy &) {
   // check we should be applying the veto
   if(parent->id()!=progenitor->id()||
      ids[0]->id()!=ids[1]->id()||
      ids[2]->id()!=ParticleID::g) return false;
   // calculate pt
   Energy2 d_m2 = parent->momentum().m2();
   Energy pPerp = (1.-d_z)*sqrt( sqr(d_z*d_qt) - d_m2);
   // if not hardest so far don't apply veto
   if(pPerp<highestpT) return false;
   // calculate the weight
   double weight = 0.;
   if(parent->id()>0) weight = qWeightX(d_qt, d_z);
   else weight = qbarWeightX(d_qt, d_z);
   // compute veto from weight and return 
   return !UseRandom::rndbool(weight);
 }
 
 
 void SMZDecayer::setRho(double r) 
 { 
   d_rho_ = r;
   d_v_ = sqrt(1.-4.*d_rho_);
 }
 
 void SMZDecayer::setKtildeSymm() { 
   d_kt1_ = (1. + sqrt(1. - 4.*d_rho_))/2.;
   setKtilde2();
 }
 
 void SMZDecayer::setKtilde2() { 
    double num = d_rho_ * d_kt1_ + 0.25 * d_v_ *(1.+d_v_)*(1.+d_v_);
    double den = d_kt1_ - d_rho_;
    d_kt2_ = num/den;
 }
 
 double SMZDecayer::getZfromX(double x1, double x2) {
   double uval = u(x2);
   double num = x1 - (2. - x2)*uval;
   double den = sqrt(x2*x2 - 4.*d_rho_);
   return uval + num/den;
 }
 
 double SMZDecayer::getKfromX(double x1, double x2) {
    double zval = getZfromX(x1, x2);
    return (1.-x2)/(zval*(1.-zval));
 }
 
 double SMZDecayer::MEV(double x1, double x2) {
   // Vector part
   double num = (x1+2.*d_rho_)*(x1+2.*d_rho_) + (x2+2.*d_rho_)*(x2+2.*d_rho_) 
     - 8.*d_rho_*(1.+2.*d_rho_);
   double den = (1.+2.*d_rho_)*(1.-x1)*(1.-x2);
   return (num/den - 2.*d_rho_/((1.-x1)*(1.-x1)) 
 	  - 2*d_rho_/((1.-x2)*(1.-x2)))/d_v_;
 }
 
 double SMZDecayer::MEA(double x1, double x2) {
   // Axial part
   double num = (x1+2.*d_rho_)*(x1+2.*d_rho_) + (x2+2.*d_rho_)*(x2+2.*d_rho_) 
     + 2.*d_rho_*((5.-x1-x2)*(5.-x1-x2) - 19.0 + 4*d_rho_);
   double den = d_v_*d_v_*(1.-x1)*(1.-x2);
   return (num/den - 2.*d_rho_/((1.-x1)*(1.-x1)) 
 	  - 2*d_rho_/((1.-x2)*(1.-x2)))/d_v_;
 }
 
 double SMZDecayer::u(double x2) {
   return 0.5*(1. + d_rho_/(1.-x2+d_rho_));
 }
 
 void SMZDecayer::
 getXXbar(double kti, double z, double &x, double &xbar) {
   double w = sqr(d_v_) + kti*(-1. + z)*z*(2. + kti*(-1. + z)*z);
   if (w < 0) {
     x = -1.; 
     xbar = -1;
   } else {
     x = (1. + sqr(d_v_)*(-1. + z) + sqr(kti*(-1. + z))*z*z*z 
 	 + z*sqrt(w)
 	 - kti*(-1. + z)*z*(2. + z*(-2 + sqrt(w))))/
       (1. - kti*(-1. + z)*z + sqrt(w));
     xbar = 1. + kti*(-1. + z)*z;
   }
 }
 
 double SMZDecayer::qWeight(double x, double xbar) {
   double rval; 
   double xg = 2. - xbar - x;
   // always return one in the soft gluon region
   if(xg < EPS_) return 1.0;
   // check it is in the phase space
   if((1.-x)*(1.-xbar)*(1.-xg) < d_rho_*xg*xg) return 0.0;
   double k1 = getKfromX(x, xbar);
   double k2 = getKfromX(xbar, x);
   // Is it in the quark emission zone?
   if(k1 < d_kt1_) {
     rval = MEV(x, xbar)/PS(x, xbar);
     // is it also in the anti-quark emission zone?
     if(k2 < d_kt2_) rval *= 0.5;
     return rval;
   }
   return 1.0;
 }
 
 double SMZDecayer::qbarWeight(double x, double xbar) {
   double rval; 
   double xg = 2. - xbar - x;
   // always return one in the soft gluon region
   if(xg < EPS_) return 1.0;
   // check it is in the phase space
   if((1.-x)*(1.-xbar)*(1.-xg) < d_rho_*xg*xg) return 0.0;
   double k1 = getKfromX(x, xbar);
   double k2 = getKfromX(xbar, x);
   // Is it in the antiquark emission zone?
   if(k2 < d_kt2_) {
     rval = MEV(x, xbar)/PS(xbar, x);
     // is it also in the quark emission zone?
     if(k1 < d_kt1_) rval *= 0.5;
     return rval;
   }
   return 1.0;
 }
 
 double SMZDecayer::qWeightX(Energy qtilde, double z) {
   double x, xb;
   getXXbar(sqr(qtilde/d_Q_), z, x, xb);
   // if exceptionally out of phase space, leave this emission, as there 
   // is no good interpretation for the soft ME correction. 
   if (x < 0 || xb < 0) return 1.0; 
   return qWeight(x, xb); 
 }
 
 double SMZDecayer::qbarWeightX(Energy qtilde, double z) {
   double x, xb;
   getXXbar(sqr(qtilde/d_Q_), z, xb, x);
   // see above in qWeightX. 
   if (x < 0 || xb < 0) return 1.0; 
   return qbarWeight(x, xb); 
 }
 
 double SMZDecayer::PS(double x, double xbar) {
   double u = 0.5*(1. + d_rho_ / (1.-xbar+d_rho_));
   double z = u + (x - (2.-xbar)*u)/sqrt(xbar*xbar - 4.*d_rho_);
   double brack = (1.+z*z)/(1.-z)- 2.*d_rho_/(1-xbar);
   // interesting: the splitting function without the subtraction
   // term. Actually gives a much worse approximation in the collinear
   // limit.  double brack = (1.+z*z)/(1.-z);
   double den = (1.-xbar)*sqrt(xbar*xbar - 4.*d_rho_);
   return brack/den;
 }
 
 double SMZDecayer::matrixElementRatio(const Particle & inpart, const ParticleVector & decay2,
 				      const ParticleVector & decay3, MEOption,
 				      ShowerInteraction inter) {
   // extract partons and LO momentas
   vector<cPDPtr> partons(1,inpart.dataPtr());
   vector<Lorentz5Momentum> lomom(1,inpart.momentum());
   for(unsigned int ix=0;ix<2;++ix) {
     partons.push_back(decay2[ix]->dataPtr());
     lomom.push_back(decay2[ix]->momentum());
   }
   vector<Lorentz5Momentum> realmom(1,inpart.momentum());
   for(unsigned int ix=0;ix<3;++ix) {
     if(ix==2) partons.push_back(decay3[ix]->dataPtr());
     realmom.push_back(decay3[ix]->momentum());
   }
   if(partons[0]->id()<0) {
     swap(partons[1],partons[2]);
     swap(lomom[1],lomom[2]);
     swap(realmom[1],realmom[2]);
   }
   scale_ = sqr(inpart.mass());
   double     lome = loME(partons,lomom);
   InvEnergy2 reme = realME(partons,realmom,inter);
   double ratio = reme/lome*sqr(inpart.mass())*4.*Constants::pi;
   if(inter==ShowerInteraction::QCD) ratio *= CF_;
   return ratio;
 }
 
 double SMZDecayer::meRatio(vector<cPDPtr> partons, 
 					 vector<Lorentz5Momentum> momenta,
 					 unsigned int iemitter, bool subtract) const {
   Lorentz5Momentum q = momenta[1]+momenta[2]+momenta[3];
   Energy2 Q2=q.m2();
   Energy2 lambda = sqrt((Q2-sqr(momenta[1].mass()+momenta[2].mass()))*
 			(Q2-sqr(momenta[1].mass()-momenta[2].mass())));
   InvEnergy2 D[2];
   double lome[2];
   for(unsigned int iemit=0;iemit<2;++iemit) {
     unsigned int ispect = iemit==0 ? 1 : 0;    
     Energy2 pipj = momenta[3      ] * momenta[1+iemit ];
     Energy2 pipk = momenta[3      ] * momenta[1+ispect];
     Energy2 pjpk = momenta[1+iemit] * momenta[1+ispect];
     double y = pipj/(pipj+pipk+pjpk); 
     double z = pipk/(     pipk+pjpk);
     Energy mij = sqrt(2.*pipj+sqr(momenta[1+iemit].mass()));
     Energy2 lamB = sqrt((Q2-sqr(mij+momenta[1+ispect].mass()))*
 			(Q2-sqr(mij-momenta[1+ispect].mass())));
     Energy2 Qpk = q*momenta[1+ispect];
     Lorentz5Momentum pkt = 
       lambda/lamB*(momenta[1+ispect]-Qpk/Q2*q)
       +0.5/Q2*(Q2+sqr(momenta[1+ispect].mass())-sqr(momenta[1+ispect].mass()))*q;
     Lorentz5Momentum pijt = 
       q-pkt;
     double muj = momenta[1+iemit ].mass()/sqrt(Q2);
     double muk = momenta[1+ispect].mass()/sqrt(Q2);
     double vt = sqrt((1.-sqr(muj+muk))*(1.-sqr(muj-muk)))/(1.-sqr(muj)-sqr(muk));
     double v  = sqrt(sqr(2.*sqr(muk)+(1.-sqr(muj)-sqr(muk))*(1.-y))-4.*sqr(muk))
       /(1.-y)/(1.-sqr(muj)-sqr(muk));
     // dipole term
     D[iemit] = 0.5/pipj*(2./(1.-(1.-z)*(1.-y))
 			 -vt/v*(2.-z+sqr(momenta[1+iemit].mass())/pipj));
     // matrix element
     vector<Lorentz5Momentum> lomom(3);
     lomom[0] = momenta[0];
     if(iemit==0) {
       lomom[1] = pijt;
       lomom[2] = pkt ;
     }
     else {
       lomom[2] = pijt;
       lomom[1] = pkt ;
     }
     lome[iemit]  = loME(partons,lomom);
   }
   InvEnergy2 ratio = realME(partons,momenta,ShowerInteraction::QCD)*abs(D[iemitter])
     /(abs(D[0]*lome[0])+abs(D[1]*lome[1]));
   if(subtract)
     return Q2*(ratio-2.*D[iemitter]);
   else
     return Q2*ratio;
 }
 
 double SMZDecayer::loME(const vector<cPDPtr> & partons, 
 			const vector<Lorentz5Momentum> & momenta) const {
   // compute the spinors
   vector<VectorWaveFunction>    vin;
   vector<SpinorWaveFunction>    aout;
   vector<SpinorBarWaveFunction> fout;
   VectorWaveFunction    zin  (momenta[0],partons[0],incoming);
   SpinorBarWaveFunction qkout(momenta[1],partons[1],outgoing);
   SpinorWaveFunction    qbout(momenta[2],partons[2],outgoing);
   for(unsigned int ix=0;ix<2;++ix){
     qkout.reset(ix);
     fout.push_back(qkout);
     qbout.reset(ix);
     aout.push_back(qbout);
   }
   for(unsigned int ix=0;ix<3;++ix){
     zin.reset(ix);
     vin.push_back(zin);
   }
   // temporary storage of the different diagrams
   // sum over helicities to get the matrix element
   double total(0.);
   for(unsigned int inhel=0;inhel<3;++inhel) {
     for(unsigned int outhel1=0;outhel1<2;++outhel1) {
       for(unsigned int outhel2=0;outhel2<2;++outhel2) {
 	Complex diag1 = FFZVertex_->evaluate(scale_,aout[outhel2],fout[outhel1],vin[inhel]);
 	total += norm(diag1);
       }
     }
   }
   // return the answer
   return total;
 }
  
 InvEnergy2 SMZDecayer::realME(const vector<cPDPtr> & partons, 
 			      const vector<Lorentz5Momentum> & momenta,
 			      ShowerInteraction inter) const {
   AbstractFFVVertexPtr vertex = inter==ShowerInteraction::QCD ?
     FFGVertex_ : FFPVertex_;
   // compute the spinors
   vector<VectorWaveFunction>     vin;
   vector<SpinorWaveFunction>     aout;
   vector<SpinorBarWaveFunction>  fout;
   vector<VectorWaveFunction>     gout;
   VectorWaveFunction    zin  (momenta[0],partons[0],incoming);
   SpinorBarWaveFunction qkout(momenta[1],partons[1],outgoing);
   SpinorWaveFunction    qbout(momenta[2],partons[2],outgoing);
   VectorWaveFunction    gluon(momenta[3],partons[3],outgoing);
   for(unsigned int ix=0;ix<2;++ix){
     qkout.reset(ix);
     fout.push_back(qkout);
     qbout.reset(ix);
     aout.push_back(qbout);
     gluon.reset(2*ix);
     gout.push_back(gluon);
   }
   for(unsigned int ix=0;ix<3;++ix){
     zin.reset(ix);
     vin.push_back(zin);
   }
   vector<Complex> diag(2,0.);
 
   double total(0.);
   for(unsigned int inhel1=0;inhel1<3;++inhel1) {
     for(unsigned int outhel1=0;outhel1<2;++outhel1) {
       for(unsigned int outhel2=0;outhel2<2;++outhel2) {
 	for(unsigned int outhel3=0;outhel3<2;++outhel3) {
 	  SpinorBarWaveFunction off1 =
 	    vertex->evaluate(scale_,3,partons[1]->CC(),fout[outhel1],gout[outhel3]);
 	  diag[0] = FFZVertex_->evaluate(scale_,aout[outhel2],off1,vin[inhel1]);
 
 	  SpinorWaveFunction off2 = 
 	    vertex->evaluate(scale_,3,partons[2]->CC(),aout[outhel2],gout[outhel3]);
 	  diag[1] = FFZVertex_->evaluate(scale_,off2,fout[outhel1],vin[inhel1]);
 
 	  // sum of diagrams
 	  Complex sum = std::accumulate(diag.begin(),diag.end(),Complex(0.));
 	  // me2
 	  total += norm(sum);
 	}
       }
     }
   }
 
   // divide out the coupling
   total /= norm(vertex->norm());
   // return the total
   return total*UnitRemoval::InvE2;
 }
 
 double SMZDecayer::calculateRealEmission(double x1, double x2, 
 					 vector<PPtr> hardProcess,
 					 double phi,
 					 bool subtract) const {
   // make partons data object for meRatio
   vector<cPDPtr> partons (3);
   for(int ix=0; ix<3; ++ix)
     partons[ix] = hardProcess[ix]->dataPtr();
   partons.push_back(gluon_);
   // calculate x3
   double x3 = 2.-x1-x2;
   double xT = sqrt(max(0.,sqr(x3) -0.25*sqr(sqr(x2)+sqr(x3)-sqr(x1))/(sqr(x2)-4.*mu2_)));
   // calculate the momenta
   Energy M = mZ_;
   Lorentz5Momentum pspect(ZERO,ZERO,-0.5*M*sqrt(max(sqr(x2)-4.*mu2_,0.)),0.5*M*x2,M*mu_); 
   Lorentz5Momentum pemit (-0.5*M*xT*cos(phi),-0.5*M*xT*sin(phi),
   			  0.5*M*sqrt(max(sqr(x1)-sqr(xT)-4.*mu2_,0.)),0.5*M*x1,M*mu_);
   Lorentz5Momentum pgluon(0.5*M*xT*cos(phi), 0.5*M*xT*sin(phi),
 			  0.5*M*sqrt(max(sqr(x3)-sqr(xT),0.)),0.5*M*x3,ZERO);
   if(abs(pspect.z()+pemit.z()-pgluon.z())/M<1e-6) 
     pgluon.setZ(-pgluon.z());
   else if(abs(pspect.z()-pemit.z()+pgluon.z())/M<1e-6) 
     pemit .setZ(- pemit.z());
   // loop over the possible emitting partons
   double realwgt(0.);
   for(unsigned int iemit=0;iemit<2;++iemit) {
     // boost and rotate momenta
     LorentzRotation eventFrame( ( hardProcess[1]->momentum() +
 				  hardProcess[2]->momentum() ).findBoostToCM() );
     Lorentz5Momentum spectator = eventFrame*hardProcess[iemit+1]->momentum();
     eventFrame.rotateZ( -spectator.phi()    );
     eventFrame.rotateY( -spectator.theta()  );
     eventFrame.invert();
     vector<Lorentz5Momentum> momenta(3);
     momenta[0]   = hardProcess[0]->momentum();
     if(iemit==0) {
       momenta[2] = eventFrame*pspect;
       momenta[1] = eventFrame*pemit ;
     }
     else {
       momenta[1] = eventFrame*pspect;
       momenta[2] = eventFrame*pemit ;
     }
     momenta.push_back(eventFrame*pgluon);
     // calculate the weight
     if(1.-x1>1e-5 && 1.-x2>1e-5) 
       realwgt += meRatio(partons,momenta,iemit,subtract);
   }
   
   // total real emission contribution
   return realwgt;
 }
 
 double SMZDecayer::calculateRealEmission(double x1, double x2, 
 					 vector<PPtr> hardProcess,
 					 double phi,
 					 bool subtract,
 					 int emitter) const {
   // make partons data object for meRatio
   vector<cPDPtr> partons (3);
   for(int ix=0; ix<3; ++ix)
     partons[ix] = hardProcess[ix]->dataPtr();
   partons.push_back(gluon_);
   // calculate x3
   double x3 = 2.-x1-x2;
   double xT = sqrt(max(0.,sqr(x3) -0.25*sqr(sqr(x2)+sqr(x3)-sqr(x1))/(sqr(x2)-4.*mu2_)));
   // calculate the momenta
   Energy M = mZ_;
   Lorentz5Momentum pspect(ZERO,ZERO,-0.5*M*sqrt(max(sqr(x2)-4.*mu2_,0.)),0.5*M*x2,M*mu_); 
   Lorentz5Momentum pemit (-0.5*M*xT*cos(phi),-0.5*M*xT*sin(phi),
   			  0.5*M*sqrt(max(sqr(x1)-sqr(xT)-4.*mu2_,0.)),0.5*M*x1,M*mu_);
   Lorentz5Momentum pgluon( 0.5*M*xT*cos(phi), 0.5*M*xT*sin(phi),
   			   0.5*M*sqrt(max(sqr(x3)-sqr(xT),0.)),0.5*M*x3,ZERO);
   if(abs(pspect.z()+pemit.z()-pgluon.z())/M<1e-6) 
     pgluon.setZ(-pgluon.z());
   else if(abs(pspect.z()-pemit.z()+pgluon.z())/M<1e-6) 
     pemit .setZ(- pemit.z());
   // boost and rotate momenta
   LorentzRotation eventFrame( ( hardProcess[1]->momentum() +
 				hardProcess[2]->momentum() ).findBoostToCM() );
   Lorentz5Momentum spectator = eventFrame*hardProcess[emitter+1]->momentum();
   eventFrame.rotateZ( -spectator.phi()    );
   eventFrame.rotateY( -spectator.theta()  );
   eventFrame.invert();
   vector<Lorentz5Momentum> momenta(3);
   momenta[0]   = hardProcess[0]->momentum();
   if(emitter==0) {
     momenta[2] = eventFrame*pspect;
     momenta[1] = eventFrame*pemit ;
   }
   else {
     momenta[1] = eventFrame*pspect;
     momenta[2] = eventFrame*pemit ;
   }
   momenta.push_back(eventFrame*pgluon);
   // calculate the weight
   double realwgt(0.);
   if(1.-x1>1e-5 && 1.-x2>1e-5) 
     realwgt = meRatio(partons,momenta,emitter,subtract);  
   // total real emission contribution
   return realwgt;
 }
diff --git a/Decay/Tau/TauDecayer.cc b/Decay/Tau/TauDecayer.cc
--- a/Decay/Tau/TauDecayer.cc
+++ b/Decay/Tau/TauDecayer.cc
@@ -1,359 +1,361 @@
 // -*- C++ -*-
 //
 // TauDecayer.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 TauDecayer class.
 //
 //  Author: Peter Richardson
 //
 
 #include "TauDecayer.h"
 #include "ThePEG/Utilities/DescribeClass.h"
 #include "ThePEG/PDT/DecayMode.h"
 #include "ThePEG/Interface/ClassDocumentation.h"
 #include "ThePEG/Interface/Switch.h"
 #include "ThePEG/Interface/ParVector.h"
 #include "ThePEG/Interface/Reference.h"
 #include "ThePEG/Persistency/PersistentOStream.h"
 #include "ThePEG/Persistency/PersistentIStream.h"
 #include "ThePEG/Interface/Parameter.h"
 #include "ThePEG/Helicity/VectorSpinInfo.h"
 #include "ThePEG/Helicity/WaveFunction/SpinorWaveFunction.h"
 #include "ThePEG/Helicity/WaveFunction/SpinorBarWaveFunction.h"
 #include "Herwig/Decay/DecayVertex.h"
 #include "Herwig/Decay/GeneralDecayMatrixElement.h"
 #include "ThePEG/Helicity/FermionSpinInfo.h"
 #include "ThePEG/StandardModel/StandardModelBase.h"
 
 using namespace Herwig;
 using namespace ThePEG::Helicity;
 
 void TauDecayer::doinit() {
   DecayIntegrator::doinit();
   // make sure the current got initialised
   _current->init();
   // set up the phase-space channels
   DecayPhaseSpaceModePtr mode;
   DecayPhaseSpaceChannelPtr channel;
   tPDVector extpart,ptemp;
   extpart.push_back(getParticleData(ParticleID::tauminus));
   extpart.push_back(getParticleData(ParticleID::nu_tau));
   Energy mtau(extpart[0]->mass());
   double maxweight;
   vector<double> channelwgts;
   int iq(0),ia(0);
   _modemap.clear();
   unsigned int ix,iy;
   bool done;
   vector<double>::iterator start,end;
   for(ix=0;ix<_current->numberOfModes();++ix) {
     // get the external particles for this mode
     extpart.resize(2);
     ptemp=_current->particles(-3,ix,iq,ia);
     for(iy=0;iy<ptemp.size();++iy) extpart.push_back(ptemp[iy]);
     // create the mode
     mode=new_ptr(DecayPhaseSpaceMode(extpart,this));
     // create the first piece of the channel
     channel = new_ptr(DecayPhaseSpaceChannel(mode));
     channel->addIntermediate(extpart[0],0,0.0,-1,1);
     done=_current->createMode(-3,ix,mode,2,1,channel,mtau);
     if(done) {
       // the maximum weight and the channel weights
       // the maximum
       maxweight = _wgtmax.size()>numberModes() ? _wgtmax[numberModes()] : 0;
       // the weights for the channel
       if(_wgtloc.size()>numberModes()&&
 	 _wgtloc[numberModes()]+mode->numberChannels()<=_weights.size()) {
 	start=_weights.begin()+_wgtloc[numberModes()];
 	end  = start+mode->numberChannels();
 	channelwgts=vector<double>(start,end);
       }
       else {
 	channelwgts.resize(mode->numberChannels(),1./(mode->numberChannels()));
       }
       _modemap.push_back(ix);
       // special for the two body modes
       if(extpart.size()==3) {
 	channelwgts.clear();
 	mode=new_ptr(DecayPhaseSpaceMode(extpart,this));
       }
       addMode(mode,maxweight,channelwgts);
     }
   }
   _current->reset();
   _current->touch();
   _current->update();
 }
 
 void TauDecayer::doinitrun() {
   _current->initrun();
   DecayIntegrator::doinitrun();
   if(initialize()) {
     _weights.clear();_wgtloc.clear();_wgtmax.clear();
     unsigned int ix,iy;
     for(ix=0;ix<numberModes();++ix) {
       _wgtmax.push_back(mode(ix)->maxWeight());
       _wgtloc.push_back(_weights.size());
       for(iy=0;iy<mode(ix)->numberChannels();++iy) {
 	_weights.push_back(mode(ix)->channelWeight(iy));
       }
     }
   }
 }
 
 bool TauDecayer::accept(tcPDPtr parent, const tPDVector & children) const {
   bool allowed(false);
   // find the neutrino 
   int idnu(0),idtemp,idin(parent->id());
   vector<int> idother;
   tPDVector::const_iterator pit  = children.begin();
   tPDVector::const_iterator pend = children.end();
   for( ; pit!=pend;++pit) {
     idtemp=(**pit).id();
     if(abs(idtemp)==16) idnu=idtemp; 
     else                idother.push_back(idtemp);
   }
   if((idnu==ParticleID::nu_tau    && idin==ParticleID::tauminus)||
      (idnu==ParticleID::nu_taubar && idin==ParticleID::tauplus )) {
     allowed=_current->accept(idother);
   }
   return allowed;
 }
 
 
 int TauDecayer::modeNumber(bool & cc,tcPDPtr parent, const tPDVector & children) const {
   int imode(-1);
   tPDVector::const_iterator pit  = children.begin();
   tPDVector::const_iterator pend = children.end();
   int idtemp;vector<int> idother;
   for( ; pit!=pend;++pit) {
     idtemp=(**pit).id();
     if(abs(idtemp)!=16) idother.push_back(idtemp);
   }
   unsigned int itemp=_current->decayMode(idother);
   for(unsigned int ix=0;ix<_modemap.size();++ix) {
     if(_modemap[ix]==itemp) imode=ix;
   }
   // perform the decay
   cc=parent->id()==ParticleID::tauplus;
   return imode;
 }
 
 
 void TauDecayer::persistentOutput(PersistentOStream & os) const {
   os << _modemap << _current << _wgtloc 
      << _wgtmax << _weights << _polOpt << _tauMpol << _tauPpol;
 }
 
 void TauDecayer::persistentInput(PersistentIStream & is, int) {
   is >> _modemap >> _current >> _wgtloc 
      >> _wgtmax >> _weights >> _polOpt >> _tauMpol >> _tauPpol;
 }
 
 // The following static variable is needed for the type
 // description system in ThePEG.
 DescribeClass<TauDecayer,DecayIntegrator>
 describeHerwigTauDecayer("Herwig::TauDecayer", "HwTauDecay.so");
 
 void TauDecayer::Init() {
 
   static ClassDocumentation<TauDecayer> documentation
     ("The TauDecayer class is designed to use a weak current"
      " to perform the decay of the tau.");
 
   static Reference<TauDecayer,WeakDecayCurrent> interfaceWeakCurrent
     ("WeakCurrent",
      "The reference for the decay current to be used.",
      &TauDecayer::_current, false, false, true, false, false);
 
   static ParVector<TauDecayer,int> interfaceWeightLocation
     ("WeightLocation",
      "The locations of the weights for a given channel in the vector",
      &TauDecayer::_wgtloc,
      0, 0, 0, 0, 10000, false, false, true);
 
   static ParVector<TauDecayer,double> interfaceWeightMax
     ("MaximumWeight",
      "The maximum weight for a given channel.",
      &TauDecayer::_wgtmax,
      0, 0, 0, 0., 100., false, false, true);
 
   static ParVector<TauDecayer,double> interfaceWeights
     ("Weights",
      "The weights for the integration.",
      &TauDecayer::_weights,
      0, 0, 0, 0., 1., false, false, true);
 
   static Switch<TauDecayer,bool> interfacePolarizationOption
     ("PolarizationOption",
      "Option of forcing the polarization of the tau leptons, N.B. you"
      " should only use this option for making distributions for"
      " comparision if you really know what you are doing.",
      &TauDecayer::_polOpt, false, false, false);
   static SwitchOption interfacePolarizationOptionDefault
     (interfacePolarizationOption,
      "Default",
      "Don't force the polarization use the full spin density matrices"
      " to get the right answer",
      false);
   static SwitchOption interfacePolarizationOptionForce
     (interfacePolarizationOption,
      "Force",
      "Force the polarizations",
      true);
 
   static Parameter<TauDecayer,double> interfaceTauMinusPolarization
     ("TauMinusPolarization",
      "The polarization of the tau-, left=-1, right=+1 if this is forced.",
      &TauDecayer::_tauMpol, 0.0, -1.0, 1.0,
      false, false, Interface::limited);
 
 
   static Parameter<TauDecayer,double> interfaceTauPlusPolarization
     ("TauPlusPolarization",
      "The polarization of the tau+, left=-1, right=+1 if this is forced.",
      &TauDecayer::_tauPpol, 0.0, -1.0, 1.0,
      false, false, Interface::limited);
 
 }
 
 // combine the currents to give the matrix element
 double TauDecayer::me2(const int ichan,const Particle & inpart,
 		       const ParticleVector & decay,
 		       MEOption meopt) const {
   // map the mode to those in the current
   int mode(_modemap[imode()]);
   // get the particles for the hadronic current
   ParticleVector hadpart(decay.begin()+1,decay.end());
   Energy q;
   // extract info on the decaying particle
   if(meopt==Initialize) {
     // spin density matrix for the decaying particle
     _rho = RhoDMatrix(PDT::Spin1Half);
     if(inpart.id()==ParticleID::tauminus)
       SpinorWaveFunction   ::calculateWaveFunctions(_inspin,_rho,
 						    const_ptr_cast<tPPtr>(&inpart),
 						    incoming);
     else
       SpinorBarWaveFunction::calculateWaveFunctions(_inbar ,_rho,
 						    const_ptr_cast<tPPtr>(&inpart),
 						    incoming);
+    // fix rho if no correlations
+    fixRho(_rho);
     if(_polOpt) {
       _rho(0,1) = _rho(1,0) = 0.;
       if(inpart.id()==ParticleID::tauminus) {
 	_rho(0,0) = 0.5*(1.-_tauMpol);
 	_rho(1,1) = 0.5*(1.+_tauMpol);
       }
       else {
 	_rho(0,0) = 0.5*(1.+_tauPpol);
 	_rho(1,1) = 0.5*(1.-_tauPpol);
       }
     }
     // work out the mapping for the hadron vector
     _constants = vector<unsigned int>(decay.size()+1);
     _ispin     = vector<PDT::Spin   >(decay.size());
     int itemp(1);
     unsigned int ix(decay.size());
     do {
       --ix;
       _ispin[ix]     = decay[ix]->data().iSpin();
       itemp         *= _ispin[ix];
       _constants[ix] = itemp;
     }
     while(ix>0);
     _constants[decay.size()] = 1;
     _constants[0           ] = _constants[1];
   }
   if(!ME())
     ME(new_ptr(GeneralDecayMatrixElement(PDT::Spin1Half,_ispin)));  
   // connect the spininfo up if needed
   if(meopt==Terminate) {
     if(inpart.id()==ParticleID::tauminus) {
       SpinorWaveFunction   ::
 	constructSpinInfo(_inspin,const_ptr_cast<tPPtr>(&inpart),incoming,true);
       SpinorBarWaveFunction::
 	constructSpinInfo(_inbar,decay[0],outgoing,true);
     }
     else {
       SpinorBarWaveFunction::
 	constructSpinInfo(_inbar ,const_ptr_cast<tPPtr>(&inpart),incoming,true);
       SpinorWaveFunction::
 	constructSpinInfo(_inspin,decay[0],outgoing,true);
     }
     _current->current(mode,ichan,q,hadpart,meopt);
     return 0.;
   }
   // calculate the spinors for the decay products
   if(inpart.id()==ParticleID::tauminus)
     SpinorBarWaveFunction::calculateWaveFunctions(_inbar ,decay[0],outgoing);
   else   
     SpinorWaveFunction   ::calculateWaveFunctions(_inspin,decay[0],outgoing);
   // calculate the hadron current
   vector<LorentzPolarizationVectorE> 
     hadron(_current->current(mode,ichan,q,hadpart,meopt));
   // prefactor
   double pre = sqr(pow(inpart.mass()/q,int(hadpart.size()-2)));
   // calculate the lepton current
   LorentzPolarizationVectorE lepton[2][2];
   for(unsigned ix=0;ix<2;++ix) {
     for(unsigned iy=0;iy<2;++iy) {
       if(inpart.id()==15) 
 	lepton[ix][iy]=2.*_inspin[ix].leftCurrent(_inbar[iy]); 
       else                
 	lepton[iy][ix]=2.*_inspin[ix].leftCurrent(_inbar[iy]); 
     }
   }
   // compute the matrix element
   vector<unsigned int> ihel(decay.size()+1);
   for(unsigned int hhel=0;hhel<hadron.size();++hhel) {
     // map the index for the hadrons to a helicity state
     for(unsigned int ix=decay.size();ix>1;--ix) {
       ihel[ix]=(hhel%_constants[ix-1])/_constants[ix];
     }
     // loop over the helicities of the tau and neutrino and set up the matrix 
     // element
     for(ihel[1]=0;ihel[1]<2;++ihel[1]){
       for(ihel[0]=0;ihel[0]<2;++ihel[0]) {
 	(*ME())(ihel)= lepton[ihel[0]][ihel[1]].dot(hadron[hhel])*
 	  SM().fermiConstant();
       }
     }
   }
   // multiply by the CKM element
   int iq,ia;
   _current->decayModeInfo(mode,iq,ia);
   double ckm(1.);
   if(iq<=6) {
     if(iq%2==0) ckm = SM().CKM(iq/2-1,(abs(ia)-1)/2);
     else        ckm = SM().CKM(abs(ia)/2-1,(iq-1)/2);
   }
   return 0.5*pre*ckm*(ME()->contract(_rho)).real();
 }
   
 // output the setup information for the particle database
 void TauDecayer::dataBaseOutput(ofstream & output,bool header) const {
   unsigned int ix;
   if(header) output << "update decayers set parameters=\"";
   DecayIntegrator::dataBaseOutput(output,false);
   for(ix=0;ix<_wgtloc.size();++ix) {
     output << "insert " << name() << ":WeightLocation " << ix << " " 
 	   << _wgtloc[ix] << "\n";
   }
   for(ix=0;ix<_wgtmax.size();++ix) {
     output << "insert " << name() << ":MaximumWeight "  << ix << " " 
 	   << _wgtmax[ix] << "\n";
   }
   for(ix=0;ix<_weights.size();++ix) {
     output << "insert " << name() << ":Weights "        << ix << " " 
 	   << _weights[ix] << "\n";
   }
   _current->dataBaseOutput(output,false,true);
   output << "newdef " << name() << ":WeakCurrent " << _current->name() << " \n";
   output << "\n\" where BINARY ThePEGName=\"" << fullName() << "\";\n";
 }
diff --git a/Shower/ShowerHandler.h b/Shower/ShowerHandler.h
--- a/Shower/ShowerHandler.h
+++ b/Shower/ShowerHandler.h
@@ -1,873 +1,880 @@
 // -*- C++ -*-
 //
 // ShowerHandler.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_ShowerHandler_H
 #define HERWIG_ShowerHandler_H
 //
 // This is the declaration of the ShowerHandler class.
 //
 
 #include "ThePEG/Handlers/EventHandler.h"
 #include "ThePEG/Handlers/CascadeHandler.h"
 #include "ShowerVariation.h"
 #include "Herwig/PDF/HwRemDecayer.fh"
 #include "ThePEG/EventRecord/RemnantParticle.fh"
 #include "UEBase.h"
 #include "PerturbativeProcess.h"
 #include "Herwig/MatrixElement/Matchbox/Matching/HardScaleProfile.h"
 #include "ShowerHandler.fh"
 
 namespace Herwig {
 using namespace ThePEG;
 
 /** \ingroup Shower
  *
  *  This class is the main driver of the shower: it is responsible for 
  *  the proper handling of all other specific collaborating classes
  *  and for the storing of the produced particles in the event record.
  * 
  *  @see \ref ShowerHandlerInterfaces "The interfaces"
  *
  *  @see ThePEG::CascadeHandler
  *  @see MPIHandler
  *  @see HwRemDecayer
  */
 class ShowerHandler: public CascadeHandler {
 
 public:
 
   /**
    * Typedef for a pair of ThePEG::RemnantParticle pointers.
    */
   typedef pair<tRemPPtr, tRemPPtr> RemPair;
 
 public:
 
   /**
    *  Default constructor
    */
   ShowerHandler();
 
   /**
    *  Destructor
    */
   virtual ~ShowerHandler();
 
 public:
 
   /**
    * The main method which manages the multiple interactions and starts
    * the shower by calling cascade(sub, lastXC).
    */
   virtual void cascade();
 
   /**
    *  pointer to "this", the current ShowerHandler.
    */
   static const tShowerHandlerPtr currentHandler() {
     assert(currentHandler_);
     return currentHandler_;
   }
 
+  /**
+   *  pointer to "this", the current ShowerHandler.
+   */
+  static bool currentHandlerIsSet() {
+    return currentHandler_;
+  }
+
 public:
 
   /**
    * Hook to allow vetoing of event after showering hard sub-process
    * as in e.g. MLM merging.
    */
   virtual bool showerHardProcessVeto() const { return false; }
 
   /**
    * Return true, if this cascade handler will perform reshuffling from hard
    * process masses.
    */
   virtual bool isReshuffling() const { return true; }
 
   /**
    * Return true, if the shower handler can generate a truncated 
    * shower for POWHEG style events generated using Matchbox
    */
   virtual bool canHandleMatchboxTrunc() const { return false; }
 
   /**
    * Get the PDF freezing scale
    */
   Energy pdfFreezingScale() const { return pdfFreezingScale_; }
   
   /**
    * Get the local PDFs.
    */
   PDFPtr getPDFA() const {return PDFA_;}
   
   /**
    * Get the local PDFs.
    */
   PDFPtr getPDFB() const {return PDFB_;}
   
   /**
    * Return true if currently the primary subprocess is showered.
    */
   bool firstInteraction() const {
     if (!eventHandler()->currentCollision())return true;
     return ( subProcess_ == 
 	     eventHandler()->currentCollision()->primarySubProcess() );
   }
 
   /**
    * Return the remnant decayer.
    */
   tHwRemDecPtr remnantDecayer() const { return remDec_; }
 
   /**
    *  Split the hard process into production and decays
    * @param tagged The tagged particles from the StepHandler
    * @param hard  The hard perturbative process
    * @param decay The decay particles
    */
   void splitHardProcess(tPVector tagged, PerturbativeProcessPtr & hard,
 			DecayProcessMap & decay) const;
 
   /**
    * Information if the Showerhandler splits the hard process. 
    */
   bool doesSplitHardProcess()const {return splitHardProcess_;}
 
   /**
    *  Decay a particle.
    *  radPhotons switches the generation of photon
    *  radiation on/off.
    *  Required for Dipole Shower but not QTilde Shower.
    */
   tDMPtr decay(PerturbativeProcessPtr,
 	       DecayProcessMap & decay,
 	       bool radPhotons = false) const;
 
   
   /**
    * Cached lookup of decay modes.
    * Generator::findDecayMode() is not efficient.
    */
   tDMPtr findDecayMode(const string & tag) const;
 
 
   /**
    *  A struct to order the particles in the same way as in the DecayMode's
    */
   
   struct ParticleOrdering {
 
     bool operator() (tcPDPtr p1, tcPDPtr p2);
 
   };
   
 
   /**
    * A container for ordered particles required
    * for constructing tags for decay mode lookup.
    */
   typedef multiset<tcPDPtr,ParticleOrdering> OrderedParticles;
 
 
 public:
 
   /**
    * @name Switches for initial- and final-state radiation
    */
   //@{
   /**
    *  Switch for any radiation
    */
   bool doRadiation() const {return doFSR_ || doISR_;}
 
   /**
    * Switch on or off final state radiation.
    */
   bool doFSR() const { return doFSR_;}
   
   /**
    * Switch on or off initial state radiation.
    */
   bool doISR() const { return doISR_;}
   //@}
 
 public:
 
   /**
    * @name Switches for scales
    */
   //@{
   /**
    * Return true if maximum pt should be deduced from the factorization scale
    */
   bool hardScaleIsMuF() const { return maxPtIsMuF_; }
 
   /**
    * The factorization scale factor.
    */
   double factorizationScaleFactor() const {
     return factorizationScaleFactor_;
   }
   
   /**
    * The renormalization scale factor.
    */
   double renFac() const {
     return renormalizationScaleFactor_;
   }
   
   /**
    * The factorization scale factor.
    */
   double facFac() const {
     return factorizationScaleFactor_;
   }
   
   /**
    * The renormalization scale factor.
    */
   double renormalizationScaleFactor() const {
     return renormalizationScaleFactor_;
   }
 
   /**
    * The scale factor for the hard scale
    */
   double hardScaleFactor() const {
     return hardScaleFactor_;
   }
   /**
    * Return true, if the phase space restrictions of the dipole shower should
    * be applied.
    */
   bool restrictPhasespace() const { return restrictPhasespace_; }
 
   /**
    * Return profile scales
    */
   Ptr<HardScaleProfile>::tptr profileScales() const { return hardScaleProfile_; }
 
   /**
    * Return the relevant hard scale to be used in the profile scales
    */
   virtual Energy hardScale() const;
 
   /**
    * Return information about shower phase space choices
    */
   virtual int showerPhaseSpaceOption() const {
     assert(false && "not implemented in general");
     return -1;
   }
   //@}
 
 public:
 
   /**
    * Access the shower variations
    */
   map<string,ShowerVariation>& showerVariations() {
     return showerVariations_;
   }
 
   /**
    * Return the shower variations
    */
   const map<string,ShowerVariation>& showerVariations() const {
     return showerVariations_;
   }
 
   /**
    * Access the current Weights
    */
   map<string,double>& currentWeights() {
     return currentWeights_;
   }
 
   /**
    * Return the current Weights
    */
   const map<string,double>& currentWeights() const {
     return currentWeights_;
   }
 
   /**
    * Change the current reweighting factor
    */
   void reweight(double w) {
     reweight_ = w;
   }
 
   /**
    * Return the current reweighting factor
    */
   double reweight() const {
     return reweight_;
   }
 
 public :
   
   /**
    *   Access to switches for spin correlations
    */
   //@{
   /**
    *   Spin Correlations
    */
   unsigned int spinCorrelations() const {
     return spinOpt_;
   }
   
   /**
    *  Any correlations
    */
   virtual bool correlations() const {
     return spinOpt_!=0;
   }
   //@}
 
 public:
 
   /** 
    * struct that is used to catch exceptions which are thrown
    * due to energy conservation issues of additional scatters
    */
   struct ExtraScatterVeto {};
 
   /** 
    * struct that is used to catch exceptions which are thrown
    * due to fact that the Shower has been invoked more than
    * a defined threshold on a certain configuration
    */
   struct ShowerTriesVeto {
     /** variable to store the number of attempts */
     const int tries;
 
     /** constructor */
     ShowerTriesVeto(int t) : tries(t) {}
   };
 
 public:
 
   /** @name Functions used by the persistent I/O system. */
   //@{
   /**
    * Function used to write out object persistently.
    * @param os the persistent output stream written to.
    */
   void persistentOutput(PersistentOStream & os) const;
 
   /**
    * Function used to read in object persistently.
    * @param is the persistent input stream read from.
    * @param version the version number of the object when written.
    */
   void persistentInput(PersistentIStream & is, int version);
   //@}
 
   /**
    * The standard Init function used to initialize the interfaces.
    * Called exactly once for each class by the class description system
    * before the main function starts or
    * when this class is dynamically loaded.
    */
   static void Init();
 
 protected:
 
   /** @name Functions to perform the cascade
    */
   //@{
   /**
    * The main method which manages the showering of a subprocess.
    */
   virtual tPPair cascade(tSubProPtr sub, XCPtr xcomb);
 
   /**
    * Set up for the cascade
    */
   void prepareCascade(tSubProPtr sub) { 
     current_ = currentStep(); 
     subProcess_ = sub;
   } 
 
   /**
    *  Boost all the particles in the collision so that the collision always occurs
    * in the rest frame with the incoming particles along the z axis
    */
   void boostCollision(bool boost);
   //@}
 
 protected:
 
   /**
    *  Set/unset the current shower handler
    */
   //@{
   /**
    *  Set the current handler
    */
   void setCurrentHandler() {
     currentHandler_ = tShowerHandlerPtr(this);
   }
 
   /**
    * Unset the current handler
    */
   void unSetCurrentHandler() {
     currentHandler_ = tShowerHandlerPtr();
   }
   //@}
 
 protected:
 
   /**
    * @name Members relating to the underlying event and MPI
    */
   //@{
   /**
    * Return true if multiple parton interactions are switched on 
    * and can be used for this beam setup.
    */
   bool isMPIOn() const {
     return MPIHandler_ && MPIHandler_->beamOK();
   }
 
   /**
    * Access function for the MPIHandler, it should only be called after
    * checking with isMPIOn.
    */
   tUEBasePtr getMPIHandler() const {  
     assert(MPIHandler_);
     return MPIHandler_;    
   }
 
   /**
    *  Is a beam particle where hadronic structure is resolved
    */
   bool isResolvedHadron(tPPtr);
 
   /**
    * Get the remnants from the ThePEG::PartonBinInstance es and 
    * do some checks.
    */
   RemPair getRemnants(PBIPair incbins);
 
   /**
    *  Reset the PDF's after the hard collision has been showered
    */
   void setMPIPDFs();
   //@}
 
 public:
 
   /**
    *  Check if a particle decays in the shower
    * @param id The PDG code for the particle
    */
   bool decaysInShower(long id) const {
     return ( particlesDecayInShower_.find( abs(id) ) != 
 	     particlesDecayInShower_.end() );
   }
 
 protected:
 
   /**
    *   Members to handle splitting up of hard process and decays
    */
   //@{
   /**
    *  Find decay products from the hard process and create decay processes
    * @param parent The parent particle
    * @param hard  The hard process
    * @param decay The decay processes
    */
   void findDecayProducts(PPtr parent, PerturbativeProcessPtr hard, DecayProcessMap & decay) const;
 
   /**
    * Find decay products from the hard process and create decay processes
    * @param parent The parent particle
    * @param hard  The parent hard process
    * @param decay The decay processes
    */
   void createDecayProcess(PPtr parent,PerturbativeProcessPtr hard, DecayProcessMap & decay) const;
   //@}
 
   /**
    * @name Functions to return information relevant to the process being showered
    */
   //@{
   /**
    * Return the currently used SubProcess.
    */
   tSubProPtr currentSubProcess() const {
     assert(subProcess_);
     return subProcess_;
   }
 
   /**
    *  Access to the incoming beam particles
    */
   tPPair incomingBeams() const {
     return incoming_;
   }
   //@}
 
 protected:
 
   /**
    *  Weight handling for shower variations
    */
   //@
   /**
    * Combine the variation weights which have been encountered
    */
   void combineWeights();
 
  /**
    * Initialise the weights in currentEvent()
    */
   void initializeWeights();
 
   /**
    * Reset the current weights
    */
   void resetWeights();
   //@}
 
 protected:
 
   /**
    * Return the maximum number of attempts for showering
    * a given subprocess.
    */
   unsigned int maxtry() const { return maxtry_; }
 
 protected:
   
   /**
    *  Parameters for the space-time model
    */
   //@{
   /**
    *   Whether or not to include spa-cetime distances in the shower
    */
   bool includeSpaceTime() const {return includeSpaceTime_;}
 
   /**
    *  The minimum virtuality for the space-time model
    */
   Energy2 vMin() const {return vMin_;}
   //@}
 
 protected:
 
   /** @name Clone Methods. */
   //@{
   /**
    * Make a simple clone of this object.
    * @return a pointer to the new object.
    */
   virtual IBPtr clone() const;
 
   /** Make a clone of this object, possibly modifying the cloned object
    * to make it sane.
    * @return a pointer to the new object.
    */
   virtual IBPtr fullclone() const;
   //@}
 
 protected:
 
   /** @name Standard Interfaced functions. */
   //@{
   /**
    * Initialize this object after the setup phase before saving an
    * EventGenerator to disk.
    * @throws InitException if object could not be initialized properly.
    */
   virtual void doinit();
 
   /**
    * Initialize this object. Called in the run phase just before
    * a run begins.
    */
   virtual void doinitrun();
 
   /**
    * Finalize this object. Called in the run phase just after a
    * run has ended. Used eg. to write out statistics.
    */
   virtual void dofinish();
   //@}
 
 private:
 
   /**
    * The assignment operator is private and must never be called.
    * In fact, it should not even be implemented.
    */
   ShowerHandler & operator=(const ShowerHandler &);
 
 private:
 
   /**
    *  pointer to "this", the current ShowerHandler.
    */
   static tShowerHandlerPtr  currentHandler_;
 
   /**
    * a MPIHandler to administer the creation of several (semihard) 
    * partonic interactions.
    */
   UEBasePtr MPIHandler_;
 
   /**
    *  Pointer to the HwRemDecayer
    */
   HwRemDecPtr remDec_;
 
 private:
 
   /**
    *  Maximum tries for various stages of the showering process
    */
   //@{
   /**
    *  Maximum number of attempts for the
    *   main showering loop
    */
   unsigned int maxtry_;
 
   /**
    *  Maximum number of attempts for the regeneration of an additional
    *  scattering, before the number of scatters is reduced.
    */
   unsigned int maxtryMPI_;
 
   /**
    *  Maximum number of attempts for the regeneration of an additional
    *  hard scattering, before this event is vetoed.
    */
   unsigned int maxtryDP_;
 
   /**
    *  Maximum number of attempts to generate a decay
    */
   unsigned int maxtryDecay_;
   //@}
 
 private:
 
   /**
    *  Factors for the various scales
    */
   //@{
   /**
    * The factorization scale factor.
    */
   double factorizationScaleFactor_;
 
   /**
    * The renormalization scale factor.
    */
   double renormalizationScaleFactor_;
 
   /**
    * The scale factor for the hard scale
    */
   double hardScaleFactor_;
 
   /**
    * True, if the phase space restrictions of the dipole shower should
    * be applied.
    */
   bool restrictPhasespace_;
 
   /**
    * True if maximum pt should be deduced from the factorization scale
    */
   bool maxPtIsMuF_;
 
   /**
    * The profile scales
    */
   Ptr<HardScaleProfile>::ptr hardScaleProfile_;
   //@}
 
   /**
    *  Option to include spin correlations
    */
   unsigned int spinOpt_;
 
 private:
 
   /**
    *  Storage of information about the current event
    */
   //@{
   /**
    *  The incoming beam particles for the current collision
    */
   tPPair incoming_;
 
   /**
    *  Boost to get back to the lab
    */
   LorentzRotation boost_;
 
   /**
    *  Const pointer to the currently handeled ThePEG::SubProcess
    */
   tSubProPtr subProcess_;
 
   /**
    *  Const pointer to the current step
    */
   tcStepPtr current_;
   //@}
 
 private:
 
   /**
    * PDFs to be used for the various stages and related parameters
    */
   //@{
   /**
    * The PDF freezing scale
    */
   Energy pdfFreezingScale_;
 
   /**
    * PDFs to be used for the various stages and related parameters
    */
   //@{
   /**
    * The PDF for beam particle A. Overrides the particle's own PDF setting.
    */
   PDFPtr PDFA_;
 
   /**
    * The PDF for beam particle B. Overrides the particle's own PDF setting.
    */
   PDFPtr PDFB_;
 
   /**
    * The PDF for beam particle A for remnant splitting. Overrides the particle's own PDF setting.
    */
   PDFPtr PDFARemnant_;
 
   /**
    * The PDF for beam particle B for remnant splitting. Overrides the particle's own PDF setting.
    */
   PDFPtr PDFBRemnant_;
 
   /**
    * The MPI PDF's to be used for secondary scatters.
    */
   pair <PDFPtr, PDFPtr> mpipdfs_;
 
   /**
    * The MPI PDF's to be used for secondary scatters.
    */
   pair <PDFPtr, PDFPtr> rempdfs_;
 
   /**
    * The MPI PDF's to be used for secondary scatters.
    */
   pair <PDFPtr, PDFPtr> remmpipdfs_;
   //@}
 
 private:
 
   /**
    * @name Parameters for initial- and final-state radiation
    */
   //@{
   /**
    * Switch on or off final state radiation.
    */
   bool doFSR_;
 
   /**
    * Switch on or off initial state radiation.
    */
   bool doISR_;
   //@}
 
 private:
 
   /**
    * @name Parameters for particle decays
    */
   //@{
   /**
    *  Whether or not to split into hard and decay trees
    */
   bool splitHardProcess_;
 
   /**
    *  PDG codes of the particles which decay during showering
    *  this is fast storage for use during running
    */
   set<long> particlesDecayInShower_;
 
   /**
    *  PDG codes of the particles which decay during showering
    *  this is a vector that is interfaced so they can be changed
    */
   vector<long> inputparticlesDecayInShower_;
   //@}
 
 private:
 
   /**
    *  Parameters for the space-time model
    */
   //@{
   /**
    *   Whether or not to include spa-cetime distances in the shower
    */
   bool includeSpaceTime_;
 
   /**
    *  The minimum virtuality for the space-time model
    */
   Energy2 vMin_;
   //@}
 
 private:
 
   /**
    *  Parameters relevant for reweight and variations
    */
   //@{
   /**
    * The shower variations
    */
   map<string,ShowerVariation> showerVariations_;
 
   /**
    * Command to add a shower variation
    */
   string doAddVariation(string);
 
   /**
    * A reweighting factor applied by the showering
    */
   double reweight_;
 
   /**
    * The shower variation weights
    */
   map<string,double> currentWeights_;
   //@}
 };
 
 }
 
 #endif /* HERWIG_ShowerHandler_H */