diff --git a/EventRecord/Particle.cc b/EventRecord/Particle.cc
--- a/EventRecord/Particle.cc
+++ b/EventRecord/Particle.cc
@@ -1,521 +1,524 @@
 // -*- C++ -*-
 //
 // Particle.cc is a part of ThePEG - Toolkit for HEP Event Generation
 // Copyright (C) 1999-2017 Leif Lonnblad
 //
 // ThePEG 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 member functions of
 // the Particle class.
 //
 #include "Particle.h"
 #include "ThePEG/EventRecord/Step.h"
 #include "ThePEG/EventRecord/Event.h"
 #include "ThePEG/EventRecord/ColourLine.h"
 #include "ThePEG/Utilities/Rebinder.h"
 #include "ThePEG/Config/algorithm.h"
 #include "ThePEG/EventRecord/ParticleTraits.h"
 #include "ThePEG/Persistency/PersistentOStream.h"
 #include "ThePEG/Persistency/PersistentIStream.h"
 #include "ThePEG/PDT/DecayMode.h"
 #include <iostream>
 #include <iomanip>
 #include <cctype>
 
 #ifdef ThePEG_TEMPLATES_IN_CC_FILE
 #include "Particle.tcc"
 #endif
 
 using namespace ThePEG;
 
 Particle::ParticleRep::ParticleRep(const ParticleRep & p)
   : theParents(p.theParents), theChildren(p.theChildren),
     thePrevious(p.thePrevious), theNext(p.theNext),
     theBirthStep(p.theBirthStep), theVertex(p.theVertex),
     theLifeLength(p.theLifeLength), theScale(p.theScale),
     theVetoScale(p.theVetoScale), theNumber(p.theNumber), 
     theExtraInfo(p.theExtraInfo.size()) {
   if ( p.theColourInfo )
     theColourInfo = dynamic_ptr_cast<CBPtr>(p.theColourInfo->clone());
   if ( p.theSpinInfo )
     theSpinInfo = dynamic_ptr_cast<SpinPtr>(p.theSpinInfo->clone());
   for ( int i = 0, N = p.theExtraInfo.size(); i < N; ++i )
     theExtraInfo[i] = p.theExtraInfo[i]->clone();
 }
 
 Particle::Particle(const Particle & p)
   : Base(p), theData(p.theData), theMomentum(p.theMomentum), theRep(p.theRep) {
   if ( p.theRep ) {
     theRep = new ParticleRep(*p.theRep);
     theRep->theParents.clear();
   }
 }
 
 Particle::~Particle() {
   if ( theRep ) {
     if ( colourLine() ) colourLine()->removeColoured(this);
     if ( antiColourLine() ) antiColourLine()->removeAntiColoured(this);
     delete theRep;
   }
   theRep = 0;
   theData = cEventPDPtr();
 }
 
 void Particle::initFull() {
   if ( theRep ) return;
   theRep = new ParticleRep;
 
   Energy width = data().generateWidth(mass());
 
   if ( width > ZERO ) {
     Time lifetime = data().generateLifeTime(mass(), width);
     theRep->theLifeLength.setTau(lifetime);
     theRep->theLifeLength.
       setVect((momentum().vect()*(lifetime /
 				max(mass(), Constants::epsilon*GeV))));
     theRep->theLifeLength.rescaleEnergy();
   }
 }
 
 PPtr Particle::clone() const {
   return ptr_new<PPtr>(*this);
 }
 
 void Particle::rebind(const EventTranslationMap & trans) {
   for ( ParticleVector::iterator pit = rep().theChildren.begin();
 	pit != rep().theChildren.end(); ++pit ) *pit = trans.translate(*pit);
   for ( tParticleVector::iterator pit = rep().theParents.begin();
 	pit != rep().theParents.end(); ++pit ) *pit = trans.translate(*pit);
   rep().thePrevious = trans.translate(rep().thePrevious);
   rep().theNext = trans.translate(rep().theNext);
   if ( hasColourInfo() ) colourInfo()->rebind(trans);
   if ( spinInfo() ) spinInfo()->rebind(trans);
   rep().theBirthStep = trans.translate(rep().theBirthStep);
   for ( EIVector::const_iterator ie = rep().theExtraInfo.begin();
 	ie != rep().theExtraInfo.end(); ++ie ) (**ie).rebind(trans);
 }
 
 tParticleSet Particle::siblings() const {
   tParticleSet theSiblings;
   for ( tParticleVector::const_iterator pit = parents().begin();
 	pit != parents().end(); ++pit )
     theSiblings.insert((*pit)->children().begin(), (*pit)->children().end());
   theSiblings.erase(const_cast<Particle *>(this));
   return theSiblings;
 }
 
 void Particle::colourNeighbour(tPPtr p, bool anti) {
   tColinePtr line = colourLine(!anti);
   if ( !line ) line = ColourLine::create(this, !anti);
   line->addColoured(p, anti);  
 }
 
 void Particle::outgoingColour(tPPtr p, bool anti) {
   tColinePtr line = colourLine(anti);
   if ( !line ) line = ColourLine::create(this, anti);
   line->addColoured(p, anti);  
 }
 
 tPPtr Particle::incomingColour(bool anti) const {
   if ( !hasColourInfo() ) return tPPtr();
   tColinePtr line = colourLine(anti);
   if ( !line ) return tPPtr();
   for ( int i = 0, N = parents().size(); i < N; ++i )
     if ( parents()[i]->hasColourLine(line, anti) ) return parents()[i];
   return tPPtr();
 }
 
 tPPtr Particle::outgoingColour(bool anti) const {
   if ( !hasColourInfo() ) return tPPtr();
   tColinePtr line = colourLine(anti);
   if ( !line ) return tPPtr();
   for ( int i = 0, N = children().size(); i < N; ++i )
     if ( children()[i]->hasColourLine(line, anti) ) return children()[i];
   return tPPtr();
 }
 
 LorentzPoint Particle::labVertex() const {
   LorentzPoint r(rep().theBirthStep && rep().theBirthStep->collision()?
 		 vertex() + rep().theBirthStep->collision()->vertex():
 		 vertex());
   return r;
 }
 
 void Particle::setLabVertex(const LorentzPoint & p) {
   rep().theVertex = ( rep().theBirthStep && rep().theBirthStep->collision()?
 		      p - rep().theBirthStep->collision()->vertex() : p );
 }
 
 void Particle::transform(const LorentzRotation & r) {
   if ( hasRep() && spinInfo() ) spinInfo()->transform(momentum(), r);
   theMomentum.transform(r);
   if ( !hasRep() ) return;
   rep().theVertex.transform(r);
   rep().theLifeLength.transform(r);
 }
 
 void Particle::deepTransform(const LorentzRotation & r) {
   transform(r);
   if ( !theRep ) return;
   for ( int i = 0, N = children().size(); i < N; ++i )
     rep().theChildren[i]->deepTransform(r);
   if ( rep().theNext ) rep().theNext->deepTransform(r);
 }
 
 void Particle::rotateX(double a) {
   LorentzRotation r;
   r.rotateX(a);
   transform(r);
 }
 
 void Particle::deepRotateX(double a) {
   LorentzRotation r;
   r.rotateX(a);
   deepTransform(r);
 }
 
 void Particle::rotateY(double a) {
   LorentzRotation r;
   r.rotateY(a);
   transform(r);
 }
 
 void Particle::deepRotateY(double a) {
   LorentzRotation r;
   r.rotateY(a);
   deepTransform(r);
 }
 
 void Particle::rotateZ(double a) {
   LorentzRotation r;
   r.rotateZ(a);
   transform(r);
 }
 
 void Particle::deepRotateZ(double a) {
   LorentzRotation r;
   r.rotateZ(a);
   deepTransform(r);
 }
 
 void Particle::rotate(double a, const Axis & axis) {
   LorentzRotation r;
   r.rotate(a, axis);
   transform(r);
 }
 
 void Particle::deepRotate(double a, const Axis & axis) {
   LorentzRotation r;
   r.rotate(a, axis);
   deepTransform(r);
 }
 
 string Particle::outputFormat =
 "%n3%s10 %i7 %p[,]0 %c(,) %^^0%vv0 %>>0%<>0 %l{,}0\n"
 "                            %x10.3%y10.3%z10.3%e10.3%m10.3\n";
 
 int getNumber(string::const_iterator & pos, int def) {
   if ( !isdigit(*pos) ) return def;
   def = *pos++ - '0';
   while ( isdigit(*pos) ) def = 10*def + *pos++ - '0';
   return def;
 }
 
 void writePrecision(ostream & os, string::const_iterator & pos,
 			      int defw, int defp, double x) {
   defw = getNumber(pos, defw);
   if ( *pos == '.' ) defp = getNumber(++pos, defp);
   int oldp = os.precision();
   os << setprecision(defp) << setw(defw) << x << setprecision(oldp);
 }
 
 void writeStringAdjusted(ostream & os, bool left, int w, string str) {
   while ( !left && w-- > int(str.size()) ) os << ' ';
   os << str;
   while ( left && w-- > int(str.size()) ) os << ' ';
 }
 
 template <typename Container>
 void writeParticleRanges(ostream & os, const Container & co, char sep, int w) {
   set<int> cnum;
   for ( typename Container::const_iterator it = co.begin();
 	it != co.end(); ++it) cnum.insert((**it).number());
 
   bool elipsis = false;
   int last = -10;
   for ( set<int>::iterator it = cnum.begin(); it != cnum.end(); ++it) {
     int n = *it;
     int next = 0;
     set<int>::iterator itn = it;
     if ( ++itn != cnum.end() ) next = *itn;
     bool writeit = true;
     bool writesep = false;
     if ( elipsis && ( n != last + 1 || n != next - 1 ) )
       elipsis = false;
     else if ( !elipsis && n == last + 1 && n == next -1 ) {
       os << "..";
       elipsis = true;
       writeit = false;
     }
     else if ( elipsis && n == last + 1 && n == next -1 )
       writeit = false;
     else if ( it != cnum.begin() )
       writesep = true;
     if ( writeit ) {
       if ( writesep ) os << sep;
       os << setw(w) << n;
     }
     last = n;
   }
 }
 
 ostream & ThePEG::operator<<(ostream & os, const Particle & p) {
   return p.print(os, p.birthStep());
 }
 
 ostream & Particle::print(ostream & os, tcStepPtr step) const {
   if ( !step ) step = birthStep();
   tCollPtr coll = step? step->collision(): tCollPtr();
   tEventPtr event = coll? coll->event(): tEventPtr();
   string::const_iterator pos = Particle::outputFormat.begin();
   ios::fmtflags saveflags = os.setf(ios::fixed, ios::floatfield);
   while ( pos != Particle::outputFormat.end() ) {
     if ( *pos == '%' && ++pos != Particle::outputFormat.end() ) {
       bool left = false;
       if ( *pos == '-' ) {
 	left = true;
 	os.setf(ios::left, ios::adjustfield);
 	++pos;
       } else {
 	os.setf(ios::right, ios::adjustfield);
       }
       char mark;
       char open;
       char close;
       char sep;
       int w;
       string str;
       string fill;
       if ( pos == Particle::outputFormat.end() ) break;
       bool fullColour = false;
       switch ( *pos ) {
       case 'n':
 	os << setw(getNumber(++pos, 3)) << number();
 	break;
       case 'i':
 	os << setw(getNumber(++pos, 8)) << id();
 	break;
       case 's':
 	writeStringAdjusted(os, left, getNumber(++pos, 8), PDGName());
 	break;
       case 'x':
 	writePrecision(os, ++pos, 10, 3, momentum().x()/GeV);
 	break;
       case 'y':
 	writePrecision(os, ++pos, 10, 3, momentum().y()/GeV);
 	break;
       case 'z':
 	writePrecision(os, ++pos, 10, 3, momentum().z()/GeV);
 	break;
       case 'e':
 	writePrecision(os, ++pos, 10, 3, momentum().e()/GeV);
 	break;
       case 'm':
 	writePrecision(os, ++pos, 10, 3, momentum().mass()/GeV);
 	break;
       case 'P':
 	fullColour = true;
+	[[fallthrough]];
       case 'p':
 	open = *++pos;
 	sep = *++pos;
 	close = *++pos;
 	w = getNumber(++pos, 0);
 	if ( parents().empty() ) break;
 	if ( open ) os << open;
 	writeParticleRanges(os, parents(), sep, w);
 	if ( fullColour && hasColourInfo() &&
 	     ( incomingColour() || incomingAntiColour() ) ) {
 	  if ( close ) os << open;
 	  if ( incomingColour() )
 	    os << "+" << incomingColour()->number();
 	  if ( incomingAntiColour() )
 	    os << "-" << incomingAntiColour()->number();
 	  if ( close ) os << close;
 	}
 	if ( close ) os << close;
 	break;
       case 'l':
 	open = *++pos;
 	sep = *++pos;
 	close = *++pos;
 	w = getNumber(++pos, 0);
 	if ( hasColourInfo() &&
 	     ( colourLine() || antiColourLine() ) && event) {
 	  if ( open ) os << open;
 	  vector<tcColinePtr> clines = colourInfo()->colourLines();
 	  for ( int i = 0, N = clines.size(); i < N; ++i ) {
 	    if ( i > 0 && sep )  os << sep;
 	    clines[i]->write(os, event, false);
 	  }
 	  vector<tcColinePtr> aclines = colourInfo()->antiColourLines();
 	  for ( int i = 0, N = aclines.size(); i < N; ++i ) {
 	    if ( ( i > 0 || clines.size() ) && sep )  os << sep;
 	    aclines[i]->write(os, event, true);
 	  }
 	  if ( close ) os << close;
 	}
 	break;
       case 'C':
 	fullColour = true;
+	[[fallthrough]];
       case 'c':
 	open = *++pos;
 	sep = *++pos;
 	close = *++pos;
 	w = getNumber(++pos, 0);
 	if ( children().empty() ) break;
 	if ( open ) os << open;
 	writeParticleRanges(os, children(), sep, w);
 	if ( fullColour && hasColourInfo() &&
 	     ( outgoingColour() || outgoingAntiColour() ) ) {
 	  if ( close ) os << open;
 	  if ( outgoingColour() )
 	    os << "+" << outgoingColour()->number();
 	  if ( outgoingAntiColour() )
 	    os << "-" << outgoingAntiColour()->number();
 	  if ( close ) os << close;
 	}
 	if ( close ) os << close;
 	break;
       case '>':
 	mark = *++pos;
 	w = getNumber(++pos, 0);
 	if ( hasColourInfo() && step && step->colourNeighbour(this) ) {
 	  os << setw(w-1) << step->colourNeighbour(this)->number() << mark;
 	}
 	break;
       case '<':
 	mark = *++pos;
 	w = getNumber(++pos, 0);
 	if ( hasColourInfo() && step && step->antiColourNeighbour(this) ) {
 	  int n = step->antiColourNeighbour(this)->number();
 	  ostringstream oss;
 	  oss << mark << n;
 	  writeStringAdjusted(os, left, w, oss.str());
 	}
 	break;
       case 'v':
 	mark = *++pos;
 	w = getNumber(++pos, 0);
 	if ( next() ) {
 	  if ( left && mark ) os << mark;
 	  os << setw(w) << next()->number();
 	  if ( !left && mark ) os << mark;
 	}
 	break;
       case '^':
 	mark = *++pos;
 	w = getNumber(++pos, 0);
 	if ( previous() ) {
 	  if ( left && mark ) os << mark;
 	  os << setw(w) << previous()->number();
 	  if ( !left && mark ) os << mark;
 	}
 	break;
       case 'd':
 	switch ( *++pos ) {
 	case 'x':
 	  writePrecision(os, ++pos, 10, 3, lifeLength().x()/mm);
 	  break;
 	case 'y':
 	  writePrecision(os, ++pos, 10, 3, lifeLength().y()/mm);
 	  break;
 	case 'z':
 	  writePrecision(os, ++pos, 10, 3, lifeLength().z()/mm);
 	  break;
 	case 't':
 	  writePrecision(os, ++pos, 10, 3, lifeLength().e()/mm);
 	  break;
 	case 'T':
 	  writePrecision(os, ++pos, 10, 3, lifeLength().tau()/mm);
 	  break;
 	}
 	break;
       case 'V':
 	switch ( *++pos ) {
 	case 'x':
 	  writePrecision(os, ++pos, 10, 3, vertex().x()/mm);
 	  break;
 	case 'y':
 	  writePrecision(os, ++pos, 10, 3, vertex().y()/mm);
 	  break;
 	case 'z':
 	  writePrecision(os, ++pos, 10, 3, vertex().z()/mm);
 	  break;
 	case 't':
 	  writePrecision(os, ++pos, 10, 3, vertex().e()/mm);
 	  break;
 	}
+	break;
       case 'L':
 	switch ( *++pos ) {
 	case 'x':
 	  writePrecision(os, ++pos, 10, 3, labVertex().x()/mm);
 	  break;
 	case 'y':
 	  writePrecision(os, ++pos, 10, 3, labVertex().y()/mm);
 	  break;
 	case 'z':
 	  writePrecision(os, ++pos, 10, 3, labVertex().z()/mm);
 	  break;
 	case 't':
 	  writePrecision(os, ++pos, 10, 3, labVertex().e()/mm);
 	  break;
 	}
 	break;
       default:
 	os << *pos++;
       }
     } else {
       if ( pos != Particle::outputFormat.end() ) os << *pos++;
     }
   }
   os.flags(saveflags);
   return os;
 }
 
 void Particle::debugme() const {
   cerr << *this;
   EventRecordBase::debugme();
 }
 
 void Particle::persistentOutput(PersistentOStream & os) const {
   EventConfig::putParticleData(os, theData);
   os << ounit(theMomentum, GeV) << bool( theRep != 0 );
   if ( !theRep ) return;
   os << rep().theParents << rep().theChildren
      << rep().thePrevious << rep().theNext << rep().theBirthStep
      << ounit(rep().theVertex, mm) << ounit(rep().theLifeLength, mm)
      << ounit(rep().theScale, GeV2) << ounit(rep().theVetoScale, GeV2) 
      << rep().theNumber << rep().theDecayMode
      << rep().theColourInfo << rep().theSpinInfo << rep().theExtraInfo;
 }
 
 void Particle::persistentInput(PersistentIStream & is, int) {
   bool readRep;
   EventConfig::getParticleData(is, theData);
   is >> iunit(theMomentum, GeV) >> readRep;
   if ( !readRep ) return;
   if ( !hasRep() ) theRep = new ParticleRep;
 
   is >> rep().theParents >> rep().theChildren
      >> rep().thePrevious >> rep().theNext >> rep().theBirthStep
      >> iunit(rep().theVertex, mm) >> iunit(rep().theLifeLength, mm)
      >> iunit(rep().theScale, GeV2) >> iunit(rep().theVetoScale, GeV2) 
      >> rep().theNumber >> rep().theDecayMode
      >> rep().theColourInfo >> rep().theSpinInfo >> rep().theExtraInfo;
 }
 
 ClassDescription<Particle> Particle::initParticle;
 
 void Particle::Init() {}
diff --git a/Helicity/Vertex/Tensor/SSTVertex.cc b/Helicity/Vertex/Tensor/SSTVertex.cc
--- a/Helicity/Vertex/Tensor/SSTVertex.cc
+++ b/Helicity/Vertex/Tensor/SSTVertex.cc
@@ -1,161 +1,161 @@
 // -*- C++ -*-
 //
 // SSTVertex.cc is a part of ThePEG - Toolkit for HEP Event Generation
 // Copyright (C) 2003-2017 Peter Richardson, Leif Lonnblad
 //
 // ThePEG 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 SSTVertex class.
 //
 
 #include "SSTVertex.h"
 #include "ThePEG/Utilities/DescribeClass.h"
 #include "ThePEG/Interface/ClassDocumentation.h"
 
 using namespace ThePEG;
 using namespace Helicity;
 
 // The following static variable is needed for the type
 // description system in ThePEG.
 DescribeAbstractNoPIOClass<SSTVertex,AbstractSSTVertex>
 describeThePEGSSTVertex("ThePEG::SSTVertex", "libThePEG.so");
 
 void SSTVertex::Init() {
   
   static ClassDocumentation<SSTVertex> documentation
 ("The SSTVertex class is the implementation of the "
  "helicity amplitude calculation for the scalar-scalar-tensor vertex"
  ", all such vertices should inherit from it");
   
 }
 // evaluate the vertex
 Complex SSTVertex::evaluate(Energy2 q2, const ScalarWaveFunction & sca1,
     				const ScalarWaveFunction & sca2,
     				const TensorWaveFunction & ten) {
   // obtain the coupling
   setCoupling(q2,sca1.particle(),sca2.particle(),ten.particle());
   Complex ii(0.,1.);
   // evaluate the trace of the tensor
   Complex trace = ten.tt()-ten.xx()-ten.yy()-ten.zz();
   // dot product of the two momenta
   Energy2 dot = sca1.momentum()*sca2.momentum();
   Energy mass = sca1.particle()->mass();
   // second term
   complex<Energy2> second = 
     +2.*ten.tt()*sca1.e()*sca2.e()  +2.*ten.xx()*sca1.px()*sca2.px()
     +2.*ten.yy()*sca1.py()*sca2.py()+2.*ten.zz()*sca1.pz()*sca2.pz()
     -(ten.tx()+ten.xt())*(sca1.e()*sca2.px() +sca1.px()*sca2.e())
     -(ten.ty()+ten.yt())*(sca1.e()*sca2.py() +sca1.py()*sca2.e())
     -(ten.tz()+ten.zt())*(sca1.e()*sca2.pz() +sca1.pz()*sca2.e())
     +(ten.xy()+ten.yx())*(sca1.py()*sca2.px()+sca1.px()*sca2.py())
     +(ten.xz()+ten.zx())*(sca1.pz()*sca2.px()+sca1.px()*sca2.pz())
     +(ten.yz()+ten.zy())*(sca1.pz()*sca2.py()+sca1.py()*sca2.pz());
   // return the answer
   return -0.5*ii*norm()*UnitRemoval::InvE2*
     (trace*(mass*mass-dot)+second)*sca1.wave()*sca2.wave();
 }
 // off-shell tensor
 TensorWaveFunction SSTVertex::evaluate(Energy2 q2, int iopt, tcPDPtr out,
 				       const ScalarWaveFunction & sca1,
 				       const ScalarWaveFunction & sca2,
 				       complex<Energy> mass, complex<Energy> width) {
   // obtain the coupling
   setCoupling(q2,sca1.particle(),sca2.particle(),out);
   // array for the tensor
   Complex ten[4][4];
   // calculate the outgoing momentum
   Lorentz5Momentum pout = sca1.momentum()+sca2.momentum();
   // prefactor
   if(mass.real() < ZERO) mass   = out->mass();
   complex<Energy2> mass2 = sqr(mass);
   Energy2 p2    = pout.m2();
   Complex fact  = 0.25*norm()*sca1.wave()*sca2.wave()*
     propagator(iopt,p2,out,mass,width);
   // dot products we need
   Energy2 dot12 = sca1.momentum()*sca2.momentum();
   Energy2 dot1  = sca1.momentum()*pout;
   Energy2 dot2  = pout*sca2.momentum();
   // the vectors that we need for the tensor
   LorentzPolarizationVectorE vec1,vec2;
   Complex a,b;
   Energy2 mphi2 = sqr(sca1.particle()->mass());
   // massive case
   if(mass.real()!=ZERO) {
     Complex norm1=dot1/mass2;
     Complex norm2=dot2/mass2;
-    a = UnitRemoval::InvE2 * ((mphi2+dot12)*(Complex(2.*p2/mass2)-5.)
-			      +4.*(dot12-dot1*dot2/mass2))/3.;
+    a = Complex(UnitRemoval::InvE2 * ((mphi2+dot12)*(Complex(2.*p2/mass2)-5.)
+				      +4.*(dot12-dot1*dot2/mass2)))/3.;
     b = -(-(mphi2+dot12)*(2.+p2/mass2)+4.*(dot12-dot1*(dot2/mass2)))/3./mass2;
     vec1 = LorentzPolarizationVectorE(sca1.momentum()) - 
       LorentzPolarizationVectorE(norm1 * pout);
     vec2 = LorentzPolarizationVectorE(sca2.momentum()) - 
       LorentzPolarizationVectorE(norm2 * pout);
   }
   // massless case
   else {
     a = UnitRemoval::InvE2 * (-5.*(mphi2+dot12)+4.*dot12)/3.;
     b = 0.;
     vec1 = sca1.momentum();
     vec2 = sca2.momentum();
   }
   // calculate the wavefunction
   complex<Energy> vec1_tmp[4] = {vec1.x(), vec1.y(), vec1.z(), vec1.t()};
   complex<Energy> vec2_tmp[4] = {vec2.x(), vec2.y(), vec2.z(), vec2.t()};
   complex<Energy> pout_tmp[4] = {pout.x(), pout.y(), pout.z(), pout.t()};
   for(int ix=0;ix<4;++ix) {
     for(int iy=0;iy<4;++iy) {
       complex<Energy2> temp = -2.*( vec1_tmp[ix]*vec2_tmp[iy] +
 				    vec1_tmp[ix]*vec2_tmp[iy])
 	-b*pout_tmp[ix]*pout_tmp[iy];
       ten[ix][iy]= UnitRemoval::InvE2 * temp;
     }
   }
   ten[3][3]=ten[3][3]-a;
   for(int ix=0;ix<3;++ix){ten[ix][ix]=ten[ix][ix]+a;}
   // prefactor
   for(int ix=0;ix<4;++ix){for(int iy=0;iy<4;++iy){ten[ix][iy]=fact*ten[ix][iy];}}
   // return the wavefunction
   return TensorWaveFunction(pout,out,
 			    ten[0][0],ten[0][1],ten[0][2],ten[0][3],
 			    ten[1][0],ten[1][1],ten[1][2],ten[1][3],
 			    ten[2][0],ten[2][1],ten[2][2],ten[2][3],
 			    ten[3][0],ten[3][1],ten[3][2],ten[3][3]);
 }
 // off-shell scalar
 ScalarWaveFunction SSTVertex::evaluate(Energy2 q2,int iopt, tcPDPtr out,
 				       const ScalarWaveFunction & sca,
 				       const TensorWaveFunction & ten,
 				       complex<Energy> mass, complex<Energy> width) {
   // obtain the coupling
   setCoupling(q2,sca.particle(),out,ten.particle());
   // calculate the outgoing momentum
   Lorentz5Momentum pout = sca.momentum()+ten.momentum();
   // prefactors
   if(mass.real() < ZERO) mass   = out->mass();
   complex<Energy2> mass2 = sqr(mass);
   Energy2 p2    = pout.m2();
   Complex fact  = 0.5*norm()*sca.wave()*propagator(iopt,p2,out,mass,width);
   // trace of the tensor
   Complex trace1 = ten.tt()-ten.xx()-ten.yy()-ten.zz();
   // dot product of the two momenta
   Energy2 dot = sca.momentum()*pout;
   // first term
   complex<Energy2> trace = trace1*(mass2-dot);
   // second term
   complex<Energy2> second = 
     +2.*ten.tt()*sca.e()*pout.e()  +2.*ten.xx()*sca.px()*pout.x()
     +2.*ten.yy()*sca.py()*pout.y()+2.*ten.zz()*sca.pz()*pout.z()
     -(ten.tx()+ten.xt())*( sca.e()*pout.x()+sca.px()*pout.e())
     -(ten.ty()+ten.yt())*( sca.e()*pout.y()+sca.py()*pout.e())
     -(ten.tz()+ten.zt())*( sca.e()*pout.z()+sca.pz()*pout.e())
     +(ten.xy()+ten.yx())*(sca.py()*pout.x()+sca.px()*pout.y())
     +(ten.xz()+ten.zx())*(sca.pz()*pout.x()+sca.px()*pout.z())
     +(ten.yz()+ten.zy())*(sca.py()*pout.z()+sca.pz()*pout.y());
   // put it all together
   second  = fact*(trace+second);
   Complex result = second * UnitRemoval::InvE2;
   return ScalarWaveFunction(pout,out,result);
 }
diff --git a/Helicity/Vertex/Tensor/VVTVertex.cc b/Helicity/Vertex/Tensor/VVTVertex.cc
--- a/Helicity/Vertex/Tensor/VVTVertex.cc
+++ b/Helicity/Vertex/Tensor/VVTVertex.cc
@@ -1,276 +1,277 @@
 // -*- C++ -*-
 //
 // VVTVertex.cc is a part of ThePEG - Toolkit for HEP Event Generation
 // Copyright (C) 2003-2017 Peter Richardson, Leif Lonnblad
 //
 // ThePEG 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 VVTVertex class.
 //
 
 #include "VVTVertex.h"
 #include "ThePEG/Utilities/DescribeClass.h"
 #include "ThePEG/Interface/ClassDocumentation.h"
 
 using namespace ThePEG;
 using namespace Helicity;
 
 // The following static variable is needed for the type
 // description system in ThePEG.
 DescribeAbstractNoPIOClass<VVTVertex,AbstractVVTVertex>
 describeThePEGVVTVertex("ThePEG::VVTVertex", "libThePEG.so");
 
 void VVTVertex::Init() {
     
   static ClassDocumentation<VVTVertex> documentation
     ("The VVTVertex class is the implementation of"
      "the vector-vector tensor vertices for helicity "
      "amplitude calculations. All such vertices should inherit"
      "from it.");
   
 }
 
 // function to evaluate the vertex
 Complex VVTVertex::evaluate(Energy2 q2, const VectorWaveFunction & vec1,
 			    const VectorWaveFunction & vec2, 
 			    const TensorWaveFunction & ten,
 			    Energy vmass) {
   // set the couplings
   setCoupling(q2,vec1.particle(),vec2.particle(),ten.particle());
   // mass of the vector
   if(vmass<ZERO) vmass = vec1.particle()->mass();
   // mass+k1.k2
   Energy2 mdot = vec1.momentum()*vec2.momentum();
   if(vmass!=ZERO) mdot += sqr(vmass);
   // dot product of wavefunctions and momenta
   Complex dotv1v2         = vec1.wave().dot(vec2.wave());
   complex<Energy> dotk1v2 = vec1.momentum()*vec2.wave();
   complex<Energy> dotk2v1 = vec1.wave()*vec2.momentum();
   // dot product of wavefunctions and momenta with the tensor
   LorentzPolarizationVector  tv1 = ten.wave().postDot(vec1.wave());
   LorentzPolarizationVector  tv2 = ten.wave().postDot(vec2.wave());
   LorentzPolarizationVectorE tk1 = ten.wave().postDot(vec1.momentum());
   LorentzPolarizationVectorE tk2 = ten.wave().postDot(vec2.momentum());
   Complex tenv1v2 = 
     vec1.wave    ().dot(tv2) + vec2.wave    ().dot(tv1);
   complex<Energy> tenk1v2 =
     vec1.momentum().dot(tv2) + vec2.wave    ().dot(tk1);
   complex<Energy> tenk2v1 =
     vec2.momentum().dot(tv1) + vec1.wave    ().dot(tk2);
   complex<Energy2> tenk1k2 =
     vec2.momentum().dot(tk1) + vec1.momentum().dot(tk2);
   // trace of the tensor
   Complex trace = ten.tt()-ten.xx()-ten.yy()-ten.zz();
   // evaluate the vertex
   return -0.5*Complex(0.,1.)*norm()*UnitRemoval::InvE2 *
     (trace*(dotk1v2*dotk2v1-dotv1v2*mdot)
      +mdot*tenv1v2-dotk2v1*tenk1v2
      -dotk1v2*tenk2v1+dotv1v2*tenk1k2);
 }
 
 // evaluate an off-shell vector
 VectorWaveFunction VVTVertex::evaluate(Energy2 q2, int iopt, tcPDPtr out,
 				       const VectorWaveFunction & vec,
 				       const TensorWaveFunction & ten,
 				       complex<Energy> mass,
 				       complex<Energy> width) {
   // evaluate the couplings
   setCoupling(q2,vec.particle(),out,ten.particle());
   // outgoing momentum
   Lorentz5Momentum pout = ten.momentum()+vec.momentum();
   // normalisation factor
   if(mass.real() < ZERO) mass   = out->mass();
   complex<Energy2> mass2 = sqr(mass);
   Energy2 p2    = pout.m2();
   Complex fact  = -0.5*norm()*propagator(iopt,p2,out,mass,width);
   // dot product of wavefunctions and momenta
   complex<Energy2> dotk1k2 = vec.momentum()*pout;
   complex<Energy> dotk2v1  = vec.wave()       *pout;
   // mass-k1.k2
   complex<Energy2> mdot = -dotk1k2;
   if(mass.real()!=ZERO) mdot += mass2;
   // components of the tensor
   Complex tentx = ten.tx()+ten.xt();
   Complex tenty = ten.ty()+ten.yt();
   Complex tentz = ten.tz()+ten.zt();
   Complex tenxy = ten.xy()+ten.yx();
   Complex tenxz = ten.xz()+ten.zx();
   Complex tenyz = ten.yz()+ten.zy();
   // dot product of momenta and polarization vectors with the tensor
   complex<Energy> tenk2v1 =
     2.*(+ten.tt()*vec.t()*pout.e() +ten.xx()*vec.x()*pout.x()
         +ten.yy()*vec.y()*pout.y()+ten.zz()*vec.z()*pout.z())
     -tentx*(vec.t()*pout.x()+vec.x()*pout.e())
     -tenty*(vec.t()*pout.y()+vec.y()*pout.e())
     -tentz*(vec.t()*pout.z()+vec.z()*pout.e())
     +tenxy*(vec.x()*pout.y()+vec.y()*pout.x())
     +tenxz*(vec.x()*pout.z()+vec.z()*pout.x())
     +tenyz*(vec.y()*pout.z()+vec.z()*pout.y());
   complex<Energy2> tenk1k2 =
     2.*(+ten.tt()*vec.e()*pout.e()  +ten.xx()*vec.px()*pout.x()
         +ten.yy()*vec.py()*pout.y()+ten.zz()*vec.pz()*pout.z())
     -tentx*(vec.e()*pout.x() +vec.px()*pout.e())
     -tenty*(vec.e()*pout.y() +vec.py()*pout.e())
     -tentz*(vec.e()*pout.z() +vec.pz()*pout.e())
     +tenxy*(vec.px()*pout.y()+vec.py()*pout.x())
     +tenxz*(vec.px()*pout.z()+vec.pz()*pout.x())
     +tenyz*(vec.py()*pout.z()+vec.pz()*pout.y());
   // trace of the tensor
   Complex trace = ten.tt()-ten.xx()-ten.yy()-ten.zz();
   // compute the vector
   Complex vec1[4];
   vec1[0] = UnitRemoval::InvE2*
     (mdot*(+   tentx*   vec.t()-2.*ten.xx()*vec.x()
 	   -   tenxy*   vec.y()-    tenxz*  vec.z()-trace*vec.x())
      +(tenk2v1-trace*dotk2v1)*vec.px()-tenk1k2*vec.x()
      +dotk2v1*(+   tentx*   vec.e() -2.*ten.xx()*vec.px()
 	       -   tenxy*   vec.py()-    tenxz*  vec.pz()));
   vec1[1] = UnitRemoval::InvE2*(
     mdot *
     (+    tenty*  vec.t()
      -    tenxy*  vec.x()
      -2.*ten.yy()*vec.y()
      -    tenyz*  vec.z()-trace*vec.y()
      )
     +(tenk2v1-trace*dotk2v1)*vec.py()
     -tenk1k2*vec.y()
     +dotk2v1*(+    tenty*  vec.e() 
 	      -    tenxy*  vec.px()
 	      -2.*ten.yy()*vec.py()
 	      -    tenyz*  vec.pz()));
 
   
   vec1[2] = UnitRemoval::InvE2*
     (mdot*
      (+   tentz*   vec.t()-    tenxz*  vec.x()
       -   tenyz*   vec.y()-2.*ten.zz()*vec.z()-trace*vec.z())
      +(tenk2v1-trace*dotk2v1)*vec.pz()-tenk1k2*vec.z()
      +dotk2v1*(+   tentz*   vec.e() -    tenxz  *vec.px()
 	       -   tenyz*   vec.py()-2.*ten.zz()*vec.pz()));
   vec1[3] = UnitRemoval::InvE2*
     (mdot*(+2.*ten.tt()*vec.t()-    tentx*  vec.x()
 	   -   tenty*   vec.y()-    tentz*  vec.z()-trace*vec.t())
      +(tenk2v1-trace*dotk2v1)*vec.e() -tenk1k2*vec.t()
      +dotk2v1*(+2.*ten.tt()*vec.e() -    tentx*  vec.px()
 	       -   tenty*   vec.py()-    tentz*  vec.pz()));
   // now add the piece for massive bosons
   if(mass.real()!=ZERO) {
     // DGRELL unit problem?
     Complex dot = tenk2v1 * UnitRemoval::InvE 
       -  dotk1k2 * trace  * UnitRemoval::InvE2;
     vec1[0] -= dot*pout.x() * UnitRemoval::InvE;
     vec1[1] -= dot*pout.y() * UnitRemoval::InvE;
     vec1[2] -= dot*pout.z() * UnitRemoval::InvE;
     vec1[3] -= dot*pout.e() * UnitRemoval::InvE;
   }
   // return the VectorWaveFunction
   for(int ix=0;ix<4;++ix){vec1[ix]=vec1[ix]*fact;}
   return VectorWaveFunction(pout,out,vec1[0],vec1[1],vec1[2],vec1[3]);
 }
 
 // off-shell tensor
 TensorWaveFunction VVTVertex::evaluate(Energy2 q2, int iopt,tcPDPtr out,
 				       const VectorWaveFunction & vec1,
 				       const VectorWaveFunction & vec2,
 				       Energy vmass,
 				       complex<Energy> tmass,
 				       complex<Energy> width) {
   // coupling
   setCoupling(q2,vec1.particle(),vec2.particle(),out);
   // momenta of the outgoing tensor
   // outgoing momentum
   Lorentz5Momentum pout= vec1.momentum()+vec2.momentum();
   // overall normalisation
   if(tmass.real() < ZERO) tmass   = out->mass();
   complex<Energy2> tmass2 = sqr(tmass);
   if(vmass<ZERO) vmass = vec1.particle()->mass();
   Energy2 vmass2 = sqr(vmass);
   Energy2 p2     = pout.m2();
   Complex fact   = 0.25*norm()*propagator(iopt,p2,out,tmass,width);
   // dot products we need to construct the tensor
   complex<Energy2> dotk1k2 = vec1.momentum()*vec2.momentum();
   complex<Energy> dotv1k2  = vec1.wave()*vec2.momentum();
   Complex dotv1v2          = vec1.wave().dot(vec2.wave());
   complex<Energy> dotk1v2  = vec1.momentum()*vec2.wave();
   complex<Energy2> dotkk1  = vec1.momentum()*pout;
   complex<Energy2> dotkk2  = vec2.momentum()*pout;
   complex<Energy> dotkv1   = vec1.wave()*pout;
   complex<Energy> dotkv2   = vec2.wave()*pout;
   // dot product ma^2+k1.k2
   complex<Energy2> mdot = vmass2+dotk1k2;
   // vectors to help construct the tensor
   Complex vecv1[4],vecv2[4];
   complex<Energy> veck1[4],veck2[4];
   complex<InvEnergy2> tmass2inv(ZERO);
   if(tmass.real()> ZERO) tmass2inv =  1./tmass2;
   vecv1[0]=vec1.x() -pout.x()*dotkv1*tmass2inv;
   vecv2[0]=vec2.x() -pout.x()*dotkv2*tmass2inv;
   veck1[0]=vec1.px()-pout.x()*dotkk1*tmass2inv;
   veck2[0]=vec2.px()-pout.x()*dotkk2*tmass2inv;
     
   vecv1[1]=vec1.y() -pout.y()*dotkv1*tmass2inv;
   vecv2[1]=vec2.y() -pout.y()*dotkv2*tmass2inv;
   veck1[1]=vec1.py()-pout.y()*dotkk1*tmass2inv;
   veck2[1]=vec2.py()-pout.y()*dotkk2*tmass2inv;
     
   vecv1[2]=vec1.z() -pout.z()*dotkv1*tmass2inv;
   vecv2[2]=vec2.z() -pout.z()*dotkv2*tmass2inv;
   veck1[2]=vec1.pz()-pout.z()*dotkk1*tmass2inv;
   veck2[2]=vec2.pz()-pout.z()*dotkk2*tmass2inv;
     
   vecv1[3]=vec1.t() -pout.e()*dotkv1*tmass2inv;
   vecv2[3]=vec2.t() -pout.e()*dotkv2*tmass2inv;
   veck1[3]=vec1.e() -pout.e()*dotkk1*tmass2inv;
   veck2[3]=vec2.e() -pout.e()*dotkk2*tmass2inv;
     
   // coefficient of g(nu,mu)-k^muk^nu/m^2
+  Complex omp2 = 1.-Complex(p2*tmass2inv);
   Complex coeff1 = UnitRemoval::InvE2 * 
     (
      +4./3.*mdot*(-2.*dotv1v2+Complex((dotkv1*dotkv2+p2*dotv1v2)*tmass2inv))
      +4./3.*(dotv1k2*(dotk1v2-dotkk1*dotkv2*tmass2inv)
 	     +dotk1v2*(dotv1k2-dotkk2*dotkv1*tmass2inv)
 	     -dotv1v2*(dotk1k2-dotkk1*dotkk2*tmass2inv)
-	     +(1.-p2*tmass2inv)*dotk1v2*dotv1k2)
+	     +omp2*dotk1v2*dotv1k2)
      );
   // coefficient of g(nu,mu)
   Complex coeff2 = UnitRemoval::InvE2 * 
     (
-     2.*mdot*(1.-p2*tmass2inv)*dotv1v2
-     -2.*(1.-p2*tmass2inv)*dotk1v2*dotv1k2
+     2.*mdot*omp2*dotv1v2
+     -2.*omp2*dotk1v2*dotv1k2
      );
   // construct the tensor
   Complex ten[4][4];
   const Energy pout_tmp[4] = {pout.x(), pout.y(), pout.z(), pout.e()};
   for(int ix=0;ix<4;++ix) {
     for(int iy=0;iy<4;++iy) {
       complex<Energy2> temp;
       temp  = 2.*mdot*   (vecv1[ix]*vecv2[iy]+vecv1[iy]*vecv2[ix]);
       temp -= 2.*dotv1k2*(veck1[ix]*vecv2[iy]+veck1[iy]*vecv2[ix]);
       temp -= 2.*dotk1v2*(veck2[ix]*vecv1[iy]+veck2[iy]*vecv1[ix]);
       temp += 2.*dotv1v2*(veck1[ix]*veck2[iy]+veck1[iy]*veck2[ix]);
       
       ten[ix][iy] = UnitRemoval::InvE2 * temp
 	-coeff1*tmass2inv*pout_tmp[ix]*pout_tmp[iy];
     }
   }
   // add the g(mu,nu) term
   ten[0][0] = ten[0][0]-(coeff1+coeff2);
   ten[1][1] = ten[1][1]-(coeff1+coeff2);
   ten[2][2] = ten[2][2]-(coeff1+coeff2);
   ten[3][3] = ten[3][3]+(coeff1+coeff2);
   // overall coefficent
   for(int ix=0;ix<4;++ix) {
     for(int iy=0;iy<4;++iy) {
       ten[ix][iy] = fact*ten[ix][iy];
     }
   }
   // return the wavefunction
   return TensorWaveFunction(pout,out,
 			    ten[0][0],ten[0][1],ten[0][2],ten[0][3],
 			    ten[1][0],ten[1][1],ten[1][2],ten[1][3],
 			    ten[2][0],ten[2][1],ten[2][2],ten[2][3],
 			    ten[3][0],ten[3][1],ten[3][2],ten[3][3]);
 }
diff --git a/MatrixElement/ME2to2Base.cc b/MatrixElement/ME2to2Base.cc
--- a/MatrixElement/ME2to2Base.cc
+++ b/MatrixElement/ME2to2Base.cc
@@ -1,202 +1,202 @@
 // -*- C++ -*-
 //
 // ME2to2Base.cc is a part of ThePEG - Toolkit for HEP Event Generation
 // Copyright (C) 1999-2017 Leif Lonnblad
 //
 // ThePEG 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 ME2to2Base class.
 //
 
 #include "ME2to2Base.h"
 #include "ThePEG/Interface/ClassDocumentation.h"
 #include "ThePEG/Interface/Switch.h"
 #include "ThePEG/Persistency/PersistentOStream.h"
 #include "ThePEG/Persistency/PersistentIStream.h"
 #include "ThePEG/Utilities/SimplePhaseSpace.h"
 #include "ThePEG/Repository/EventGenerator.h"
 #include "ThePEG/Handlers/StandardXComb.h"
 #include "ThePEG/Cuts/Cuts.h"
 
 using namespace ThePEG;
 
 ME2to2Base::~ME2to2Base() {}
 
 Energy2 ME2to2Base::scale() const {
   switch ( scaleChoice() ) {
   case 1:
     return -tHat()*uHat()/(tHat() + uHat());
   default:
     return tHat()*uHat()/sHat();
   }
 }
 
 void ME2to2Base::setKinematics() {
   MEBase::setKinematics();
   theLastTHat = (meMomenta()[0] - meMomenta()[2]).m2();
   theLastUHat = (meMomenta()[1] - meMomenta()[2]).m2();
   theLastPhi = meMomenta()[2].phi();
 }
 
 bool ME2to2Base::generateKinematics(const double * r) {
   // generate the masses of the particles
   for ( int i = 2, N = meMomenta().size(); i < N; ++i ) {
     meMomenta()[i] = Lorentz5Momentum(mePartonData()[i]->generateMass());
   }
 
   double ctmin = -1.0;
   double ctmax = 1.0;
 
   Energy q = ZERO;
   try {
     q = SimplePhaseSpace::
       getMagnitude(sHat(), meMomenta()[2].mass(), meMomenta()[3].mass());
-  } catch ( ImpossibleKinematics ) {
+  } catch ( ImpossibleKinematics & e ) {
     return false;
   }
 
   Energy e = sqrt(sHat())/2.0;
 		    
   Energy2 m22 = meMomenta()[2].mass2();
   Energy2 m32 = meMomenta()[3].mass2();
   Energy2 e0e2 = 2.0*e*sqrt(sqr(q) + m22);
   Energy2 e1e2 = 2.0*e*sqrt(sqr(q) + m22);
   Energy2 e0e3 = 2.0*e*sqrt(sqr(q) + m32);
   Energy2 e1e3 = 2.0*e*sqrt(sqr(q) + m32);
   Energy2 pq = 2.0*e*q;
 
   Energy2 thmin = lastCuts().minTij(mePartonData()[0], mePartonData()[2]);
   if ( thmin > ZERO ) ctmax = min(ctmax, (e0e2 - m22 - thmin)/pq);
 
   thmin = lastCuts().minTij(mePartonData()[1], mePartonData()[2]);
   if ( thmin > ZERO ) ctmin = max(ctmin, (thmin + m22 - e1e2)/pq);
 
   thmin = lastCuts().minTij(mePartonData()[1], mePartonData()[3]);
   if ( thmin > ZERO ) ctmax = min(ctmax, (e1e3 - m32 - thmin)/pq);
 
   thmin = lastCuts().minTij(mePartonData()[0], mePartonData()[3]);
   if ( thmin > ZERO ) ctmin = max(ctmin, (thmin + m32 - e0e3)/pq);
 
   Energy ptmin = max(lastCuts().minKT(mePartonData()[2]),
    		     lastCuts().minKT(mePartonData()[3]));
   if ( ptmin > ZERO ) {
     double ctm = 1.0 - sqr(ptmin/q);
     if ( ctm <= 0.0 ) return false;
     ctmin = max(ctmin, -sqrt(ctm));
     ctmax = min(ctmax, sqrt(ctm));
   }
 
   double ymin2 = lastCuts().minYStar(mePartonData()[2]);
   double ymax2 = lastCuts().maxYStar(mePartonData()[2]);
   double ymin3 = lastCuts().minYStar(mePartonData()[3]);
   double ymax3 = lastCuts().maxYStar(mePartonData()[3]);
   double ytot = lastCuts().Y() + lastCuts().currentYHat();
   if ( ymin2 + ytot > -0.9*Constants::MaxRapidity )
     ctmin = max(ctmin, sqrt(sqr(q) +  m22)*tanh(ymin2)/q);
   if ( ymax2 + ytot < 0.9*Constants::MaxRapidity )
     ctmax = min(ctmax, sqrt(sqr(q) +  m22)*tanh(ymax2)/q);
   if ( ymin3 + ytot > -0.9*Constants::MaxRapidity )
     ctmax = min(ctmax, sqrt(sqr(q) +  m32)*tanh(-ymin3)/q);
   if ( ymax3 + ytot < 0.9*Constants::MaxRapidity )
     ctmin = max(ctmin, sqrt(sqr(q) +  m32)*tanh(-ymax3)/q);
 
   if ( ctmin >= ctmax ) return false;
     
   double cth = getCosTheta(ctmin, ctmax, r);
 
   Energy pt = q*sqrt(1.0-sqr(cth));
   theLastPhi = rnd(2.0*Constants::pi);
   meMomenta()[2].setVect(Momentum3( pt*sin(phi()),  pt*cos(phi()),  q*cth));
 
   meMomenta()[3].setVect(Momentum3(-pt*sin(phi()), -pt*cos(phi()), -q*cth));
 
   meMomenta()[2].rescaleEnergy();
   meMomenta()[3].rescaleEnergy();
 
   vector<LorentzMomentum> out(2);
   out[0] = meMomenta()[2];
   out[1] = meMomenta()[3];
   tcPDVector tout(2);
   tout[0] = mePartonData()[2];
   tout[1] = mePartonData()[3];
   if ( !lastCuts().passCuts(tout, out, mePartonData()[0], mePartonData()[1]) )
     return false;
 
   theLastTHat = pq*cth + m22 - e0e2;
   theLastUHat = m22 + m32 - sHat() - theLastTHat;
   jacobian((pq/sHat())*Constants::pi*jacobian());
   return true;
 }
 
 double ME2to2Base::getCosTheta(double ctmin, double ctmax, const double * r) {
   double cth = 0.0;
   static const double eps = 1.0e-6;
   if ( 1.0 + ctmin <= eps && 1.0 - ctmax <= eps ) {
     jacobian(ctmax - ctmin);
     cth = ctmin + (*r)*jacobian();
   } else if (  1.0 + ctmin <= eps ) {
     cth = 1.0 - (1.0 - ctmax)*pow((1.0 - ctmin)/(1.0 - ctmax), *r);
     jacobian(log((1.0 - ctmin)/(1.0 - ctmax))*(1.0 - cth));
   } else if (  1.0 - ctmax <= eps ) {
     cth = -1.0 + (1.0 + ctmin)*pow((1.0 + ctmax)/(1.0 + ctmin), *r);
     jacobian(log((1.0 + ctmax)/(1.0 + ctmin))*(1.0 + cth));
   } else {
     double zmin = 0.5*(1.0 - ctmax);
     double zmax = 0.5*(1.0 - ctmin);
     double A1 = -ctmin/(zmax*(1.0-zmax));
     double A0 = -ctmax/(zmin*(1.0-zmin));
     double A = *r*(A1 - A0) + A0;
     double z = A < 2.0? 2.0/(sqrt(sqr(A) + 4.0) + 2 - A):
       0.5*(A - 2.0 + sqrt(sqr(A) + 4.0))/A;
     cth = 1.0 - 2.0*z;
     jacobian(2.0*(A1 - A0)*sqr(z)*sqr(1.0 - z)/(sqr(z) + sqr(1.0 - z)));
   }
   return cth;
 }
 
 CrossSection ME2to2Base::dSigHatDR() const {
   return me2()*jacobian()/(16.0*sqr(Constants::pi)*sHat())*sqr(hbarc);
 }
 
 void ME2to2Base::persistentOutput(PersistentOStream & os) const {
   os << theScaleChoice << ounit(theLastTHat, GeV2) << ounit(theLastUHat, GeV2)
      << theLastPhi;
 }
 
 void ME2to2Base::persistentInput(PersistentIStream & is, int) {
   is >> theScaleChoice >> iunit(theLastTHat, GeV2) >> iunit(theLastUHat, GeV2)
      >> theLastPhi;
 }
 
 AbstractClassDescription<ME2to2Base> ME2to2Base::initME2to2Base;
 // Definition of the static class description member.
 
 Switch<ME2to2Base,int> & ME2to2Base::interfaceScaleChoice() {
   static Switch<ME2to2Base,int> dummy
     ("ScaleChoice",
      "Different options for calculating the scale of the generated "
      "hard sub-process.",
      &ME2to2Base::theScaleChoice, 0, false, false);
   return dummy;
 }
 
 void ME2to2Base::Init() {
 
   static ClassDocumentation<ME2to2Base> documentation
     ("The ThePEG::ME2to2Base class may be used as a base class "
      "for all \\f$2\\rightarrow 2\\f$ matrix elements.");
 
   static SwitchOption interfaceScaleChoice0
     (interfaceScaleChoice(),
      "that.uhat/shat", "\\f$\\hat{t}\\hat{u}/\\hat{s}\\f$", 0);
 
   static SwitchOption interfaceScaleChoice1
     (interfaceScaleChoice(),
      "that.uhat/(that+uhat)",
      "\\f$-\\hat{t}\\hat{u}/(\\hat{t}+\\hat{u})\\f$", 1);
 
 }
 
diff --git a/PDF/PartonExtractor.cc b/PDF/PartonExtractor.cc
--- a/PDF/PartonExtractor.cc
+++ b/PDF/PartonExtractor.cc
@@ -1,653 +1,653 @@
 // -*- C++ -*-
 //
 // PartonExtractor.cc is a part of ThePEG - Toolkit for HEP Event Generation
 // Copyright (C) 1999-2017 Leif Lonnblad
 //
 // ThePEG 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 PartonExtractor class.
 //
 
 #include "PartonExtractor.h"
 #include "ThePEG/Handlers/XComb.h"
 #include "ThePEG/Cuts/Cuts.h"
 #include "ThePEG/PDF/NoPDF.h"
 #include "ThePEG/PDF/RemnantHandler.h"
 #include "ThePEG/PDF/BeamParticleData.h"
 #include "ThePEG/Persistency/PersistentOStream.h"
 #include "ThePEG/Persistency/PersistentIStream.h"
 #include "ThePEG/EventRecord/Particle.h"
 #include "ThePEG/EventRecord/Step.h"
 #include "ThePEG/EventRecord/SubProcess.h"
 #include "ThePEG/Interface/Reference.h"
 #include "ThePEG/Interface/RefVector.h"
 #include "ThePEG/Interface/Parameter.h"
 #include "ThePEG/Interface/Switch.h"
 #include "ThePEG/Interface/ClassDocumentation.h"
 #include "ThePEG/Utilities/SimplePhaseSpace.h"
 #include "ThePEG/Utilities/UtilityBase.h"
 #include "ThePEG/Repository/EventGenerator.h"
 #include "ThePEG/PDT/EnumParticles.h"
 
 using namespace ThePEG;
 
 PartonExtractor::PartonExtractor()
   : theMaxTries(100), flatSHatY(false) {}
 
 PartonExtractor::~PartonExtractor() {}
 
 IBPtr PartonExtractor::clone() const {
   return new_ptr(*this);
 }
 
 IBPtr PartonExtractor::fullclone() const {
   return new_ptr(*this);
 }
 
 PartonPairVec PartonExtractor::
 getPartons(Energy maxEnergy, const cPDPair & incoming,
 	   const Cuts & kc) const {
   PartonPairVec result;
   PartonVector first;
   PDFCuts cuts1(kc, true, maxEnergy);
   PBPtr p1 =
     new_ptr(PartonBin(PDPtr(), PBPtr(), incoming.first, PDFPtr(), cuts1));
   addPartons(p1, cuts1,  theFirstPDF, first);
   PartonVector second;
   PDFCuts cuts2(kc, false, maxEnergy);
   PBPtr p2 =
     new_ptr(PartonBin(PDPtr(), PBPtr(), incoming.second, PDFPtr(), cuts2));
   addPartons(p2, cuts2, theSecondPDF, second);
   for ( PartonVector::iterator it1 = first.begin();
 	it1 != first.end(); ++it1 )
     for ( PartonVector::iterator it2 = second.begin();
 	it2 != second.end(); ++it2 )
       result.push_back(PBPair(*it1, *it2));
 
   // We add the original parton bins as well to avoid them being
   // deleted.
   result.push_back(PBPair(p1, p2));
   return result;
 }
 
 void PartonExtractor::
 addPartons(tPBPtr incoming, const PDFCuts & cuts, tcPDFPtr pdf,
 	   PartonVector & pbins) const {
   if(!pdf) pdf = getPDF(incoming->parton());
   if ( dynamic_ptr_cast<Ptr<NoPDF>::tcp>(pdf) ||
        incoming->parton() == incoming->particle() ) {
     pbins.push_back(incoming);
     return;
   }
   cPDVector partons = pdf->partons(incoming->parton());
   for ( int i = 0, N = partons.size(); i < N; ++i ) {
     PBPtr pb =
       new_ptr(PartonBin(incoming->parton(), incoming, partons[i], pdf, cuts));
     incoming->addOutgoing(pb);
     addPartons(pb, cuts, PDFPtr(), pbins);
   }
 
 }
 
 tcPDFPtr PartonExtractor::getPDF(tcPDPtr particle) const {
   for ( vector<PDFPtr>::const_iterator it = theSpecialDensities.begin();
 	it != theSpecialDensities.end(); ++it )
     if ( (**it).canHandle(particle) ) return *it;
   Ptr<BeamParticleData>::tcp p = 
     dynamic_ptr_cast<Ptr<BeamParticleData>::tcp>(particle);
   if ( !p || !p->pdf() ) return noPDF();
   return p->pdf();
 }
 
 void PartonExtractor::select(tXCombPtr newXComb) {
   theLastXComb = newXComb;
 }
 
 tPBIPtr PartonExtractor::partonBinInstance(tcPPtr p) const {
   PartonBinInstanceMap::const_iterator it = partonBinInstances().find(p);
   return it == partonBinInstances().end()? PBIPtr(): it->second;
 }
 
 void PartonExtractor::
 colourConnect(tPPtr particle, tPPtr parton, const tPVector & remnants) const {
 
   // Sorry cannot handle coloured resolved particles.
   if ( particle->coloured() ) throw RemColException(*this);
 
   // First connect the loose colour line from the extacted parton.
   if ( parton->hasColour() )
     findConnect(parton->colourLine(), parton, true,
 		remnants.rbegin(), remnants.rend());
 
   // First connect the loose anti-colour line from the extacted parton.
   if ( parton->hasAntiColour() )
     findConnect(parton->antiColourLine(), parton, false,
 		remnants.begin(), remnants.end());
 
   // Go through the rest of the remnants and create new colour lines
   // if needed. Go through it forwards and backwards to catch possible
   // inconsistencies.
   for ( tPVector::const_iterator it = remnants.begin();
 	it != remnants.end(); ++it ) {
     if ( (**it).hasAntiColour() && !(**it).antiColourLine() )
       findConnect(ColourLine::create(*it, true), *it, false,
 		it + 1, remnants.end());
   }
   for ( tPVector::const_reverse_iterator it = remnants.rbegin();
 	it != remnants.rend(); ++it ) {
     if ( (**it).hasColour() && !(**it).colourLine() )
       findConnect(ColourLine::create(*it), *it, true, it + 1, remnants.rend());
   } 
 }
 
 Energy2 PartonExtractor::newScale() {
   return lastScale();
 }
 
 pair<int,int> PartonExtractor::nDims(const PBPair & pbins) {
   // if photon from a lepton or proton generate scale
   bool genscale[2]={false,false};
   for(unsigned int ix=0;ix<2;++ix) {
     PBPtr bin = ix==0 ? pbins.first : pbins.second;
     if (!bin || !bin->particle() || !bin->parton()) continue;
     if(bin->pdf()->partons(bin->particle()).size()==1 &&
        bin->particle()->id()!=bin->parton()->id())
       genscale[ix]=true;
   }
   return make_pair(pbins.first ->nDim(genscale[0]),
 		   pbins.second->nDim(genscale[1]));
 }
 
 void PartonExtractor::prepare(const PBIPair & pbins) {
   partonBinInstances().clear();
   pbins.first->prepare();
   pbins.second->prepare();
 }
 
 void PartonExtractor::updatePartonBinInstances(const PBIPair & pbins) {
   partonBinInstances().clear();
   tPBIPtr current = pbins.first;
   while ( current->incoming() ) {
     partonBinInstances()[current->parton()] = current;
     current = current->incoming();
   }
   current = pbins.second;
   while ( current->incoming() ) {
     partonBinInstances()[current->parton()] = current;
     current = current->incoming();
   }
 }
 
 bool PartonExtractor::
 generateL(const PBIPair & pbins, const double * r1, const double * r2) {
   Direction<0> dir(true);
   generateL(*pbins.first, r1);
   dir.reverse();
   generateL(*pbins.second, r2);
   if ( !flatSHatY || pbins.first->hasPoleIn1() || pbins.second->hasPoleIn1() )
     return true;
 
   Energy2 shmax = lastCuts().sHatMax();
   Energy2 shmin = lastCuts().sHatMin();
   Energy2 sh = shmin*pow(shmax/shmin, *r1);
   double ymax = lastCuts().yHatMax();
   double ymin = lastCuts().yHatMin();
   double km = log(shmax/shmin);
   ymax = min(ymax, log(lastCuts().x1Max()*sqrt(lastS()/sh)));
   ymin = max(ymin, -log(lastCuts().x2Max()*sqrt(lastS()/sh)));
 
   double y = ymin + (*r2)*(ymax - ymin);
   double l1 = 0.5*log(lastS()/sh) - y;
   double l2 = 0.5*log(lastS()/sh) + y;
 
   pbins.first->li(l1 - pbins.first->l() + pbins.first->li());
   pbins.first->l(l1);
   pbins.first->jacobian(km*(ymax - ymin));
   pbins.second->li(l2 - pbins.second->l() + pbins.second->li());
   pbins.second->l(l2);
   pbins.second->jacobian(1.0);
   return ( pbins.first->li() >= 0.0 && pbins.second->li() >= 0.0 );
 }
 
 Energy2 PartonExtractor::
 generateSHat(Energy2, const PBIPair & pbins,
 	     const double * r1, const double * r2,
 	     bool haveMEPartons) {
   Direction<0> dir(true);
   if(pbins.first->bin()->pdfDim()<=1) pbins.first->scale(-lastScale());
   if ( !generate(*pbins.first, r1, lastSHat(),
 		 pbins.first->getFirst()->parton()->momentum(),
 		 haveMEPartons) )
     return -1.0*GeV2;
   dir.reverse();
   if(pbins.second->bin()->pdfDim()<=1) pbins.second->scale(-lastScale());
   if ( !generate(*pbins.second, r2, lastSHat(),
 		 pbins.second->getFirst()->parton()->momentum(),
 		 haveMEPartons) )
     return -1.0*GeV2;
   
   return (pbins.first->parton()->momentum() +
 	  pbins.second->parton()->momentum()).m2();
 }
 
 void PartonExtractor::
 generateL(PartonBinInstance & pb, const double * r) {
   if ( !pb.incoming() ) return;
 
   pb.parton(pb.partonData()->produceParticle(Lorentz5Momentum()));
   generateL(*pb.incoming(), r + pb.bin()->pdfDim() + pb.bin()->remDim());
   pb.particle(pb.incoming()->parton());
 
   if ( pb.li() >= 0 ) return;
 
   double jac = 1.0;
   if ( pb.bin()->pdfDim() )
     pb.li(pb.pdf()->flattenL(pb.particleData(), pb.partonData(),
 			     pb.bin()->cuts(), *r++, jac));
   pb.scale(-1.0*GeV2);
   if ( pb.bin()->pdfDim() > 1 )
     pb.scale(pb.pdf()->flattenScale(pb.particleData(), pb.partonData(),
 				    pb.bin()->cuts(), pb.li(), *r++, jac)
 	     *pb.bin()->cuts().scaleMaxL(pb.li()));
   pb.jacobian(jac);
   pb.l(pb.incoming()->l() + pb.li());
 }
 
 bool PartonExtractor::
 generate(PartonBinInstance & pb, const double * r,
 	 Energy2 shat, const Lorentz5Momentum & first,
 	 bool haveMEPartons) {
   if ( !pb.incoming() ) return true;
   if ( !generate(*pb.incoming(), r + pb.bin()->pdfDim() + pb.bin()->remDim(),
 		 shat/pb.xi(), first) )
     return false;
   pb.remnantWeight(1.0);
   pb.parton()->setMomentum
     (pb.remnantHandler()->generate(pb, r + pb.bin()->pdfDim(), pb.scale(), shat,
 				   pb.particle()->momentum(),haveMEPartons));
   if ( pb.remnantWeight() <= 0.0 ) return false;
   partonBinInstances()[pb.parton()] = &pb;
   return true;
 }
 
 void PartonExtractor::
 constructRemnants(const PBIPair & pbins, tSubProPtr sub, tStepPtr step) const {
   partonBinInstances().clear();
   LorentzMomentum k1 = pbins.first->parton()->momentum();
   LorentzMomentum k2 = pbins.second->parton()->momentum();
   LorentzMomentum Ph = k1 + k2;
   LorentzMomentum Phold = Ph;
   LorentzRotation Rh = Utilities::getBoostToCM(make_pair(k1, k2));
 
   bool pickside = rndbool();
   if ( pickside && pbins.first->incoming() ) {
     Direction<0> dir(true);
     constructRemnants(*pbins.first, Ph, k2);
     construct(*pbins.first, step, false);
   }
   if ( pbins.second->incoming() ) {
     Direction<0> dir(false);
     constructRemnants(*pbins.second, Ph, pbins.first->parton()->momentum());
     construct(*pbins.second, step, false);
   }
   if ( (!pickside) && pbins.first->incoming() ) {
     Direction<0> dir(true);
     constructRemnants(*pbins.first, Ph, pbins.second->parton()->momentum());
     construct(*pbins.first, step, false);
   }
   //  LorentzRotation rot = Utilities::transformToMomentum(Phold, Ph);
   k1 = pbins.first->parton()->momentum();
   k2 = pbins.second->parton()->momentum();
   LorentzRotation rot = Utilities::getBoostFromCM(make_pair(k1, k2))*Rh;
   Utilities::transform(sub->outgoing(), rot);
   Utilities::transform(sub->intermediates(), rot);
   Ph = k1 + k2;
   if ( abs(Ph.m2() - Phold.m2())/Phold.m2() > 0.000001 )
     cerr << Ph.m2()/GeV2 << " was (" << Phold.m2()/GeV2 << ")" << endl;
 }
 
 void PartonExtractor::
 constructRemnants(PartonBinInstance & pb, LorentzMomentum & Ph,
 		  const LorentzMomentum & k) const {
   LorentzMomentum P = pb.particle()->momentum();
   DVector r = UseRandom::rndvec(pb.bin()->remDim());
   if ( r.empty() ) r.push_back(0.0);
   pb.parton()->setMomentum(pb.remnantHandler()->
 			   generate(pb, &r[0], pb.scale(), Ph.m2(), P));
   if ( pb.remnantWeight() <= 0.0 ) throw Veto();
   pb.remnantHandler()->boostRemnants(pb);
   LorentzMomentum Pr = Utilities::sumMomentum(pb.remnants());
   transformRemnants(Ph, Pr, k, pb.particle()->momentum());
   pb.parton()->setMomentum(pb.particle()->momentum() - Pr);
   try {
     Utilities::setMomentum(pb.remnants().begin(),
 			   pb.remnants().end(),
 			   static_cast<const LorentzMomentum &>(Pr));
   }
   catch ( ThePEG::Exception & e) {
     throw e;
   }
   catch ( ThePEG::Veto ) {
     throw;
   }
   catch ( std::exception & e ) {
     throw Exception() << "Caught non-ThePEG exception " << e.what() << "in "
 		      << "PartonExtractor::constructRemnants"
 		      << Exception::eventerror;
   }
   partonBinInstances()[pb.parton()] = &pb;
   if ( !pb.incoming()->incoming() ) return;
 
   // We get here if we need to construct remnants recursively.
   LorentzMomentum Phnew = Ph + Pr;
   constructRemnants(*pb.incoming(), Phnew, k);
   LorentzRotation rot = Utilities::transformToMomentum(Ph + Pr, Phnew);
   Utilities::transform(pb.remnants(), rot);
   Ph.transform(rot);
 }
 
 LorentzRotation PartonExtractor::
 boostRemnants(PBIPair & bins, LorentzMomentum k1, LorentzMomentum k2,
 	 bool side1, bool side2) const {
   if ( !side1 && !side2 ) return LorentzRotation();
 
   LorentzMomentum P1 =
     bins.first? LorentzMomentum(bins.first->parton()->momentum()): k1;
   LorentzMomentum Pr1;
   if ( side1 ) {
     P1 = bins.first->particle()->momentum();
     Pr1 = Utilities::sumMomentum(bins.first->remnants());
   }
   LorentzMomentum P2 =
     bins.second? LorentzMomentum(bins.second->parton()->momentum()): k2;
   LorentzMomentum Pr2;
   if ( side2 ) {
     P2 = bins.second->particle()->momentum();
     Pr2 = Utilities::sumMomentum(bins.second->remnants());
   }
 
   LorentzRotation Rh = Utilities::getBoostToCM(make_pair(k1, k2));
   LorentzMomentum Ph = k1 + k2;
   //  LorentzMomentum Phold = Ph;
 
   bool otherside = rndbool();
   if ( otherside && side2 ){
     Direction<0> dir(false);
     transformRemnants(Ph, Pr2, k1, P2);
     k2 = P2 - Pr2;
   }
   if ( side1 ){
     Direction<0> dir(true);
     transformRemnants(Ph, Pr1, k2, P1);
     k1 = P1 - Pr1;
   }
   if ( side2 && !otherside ) {
     Direction<0> dir(false);
     transformRemnants(Ph, Pr2, k1, P2);
     k2 = P2 - Pr2;
   }
 
   if ( bins.first ) {
     if ( bins.first->remnants().size() == 1 )
       bins.first->remnants()[0]->setMomentum(Pr1);
     else
       Utilities::setMomentum(bins.first->remnants().begin(),
 			     bins.first->remnants().end(),
 			     static_cast<const LorentzMomentum &>(Pr1));
     bins.first->parton()->setMomentum(k1);
   }
 
   if ( bins.second ) {
     if ( bins.second->remnants().size() == 1 )
       bins.second->remnants()[0]->setMomentum(Pr2);
     else
       Utilities::setMomentum(bins.second->remnants().begin(),
 			     bins.second->remnants().end(),
 			     static_cast<const LorentzMomentum &>(Pr2));
     bins.second->parton()->setMomentum(k2);
   }
 
   Rh.transform(Utilities::getBoostFromCM(make_pair(k1, k2)));
 
   // LorentzMomentum phh = Rh*Phold;
 
   return Rh;
 
   //  return Utilities::transformToMomentum(Phold, Ph);
 
 }
 
 void PartonExtractor::
 transformRemnants(LorentzMomentum & Ph, LorentzMomentum & Pr,
 		  const LorentzMomentum & k, const LorentzMomentum & P) const {
   // don't do this for very soft remnants, as
   // we may run into numerical troubles; threshold
   // needs to become a parameter at some point
   if ( Pr.vect().mag2()/k.vect().mag2() < 1e-10 &&
        sqr(Pr.e()/k.e()) < 1e-10 )
     return;
   TransverseMomentum pt = Pr;
   try {
     if ( Direction<0>::pos() )
       SimplePhaseSpace::CMS(Pr, Ph, (P + k).m2(), 1.0, 0.0);
     else
       SimplePhaseSpace::CMS(Ph, Pr, (k + P).m2(), 1.0, 0.0);
     LorentzRotation rpt;
     if ( sqr(Pr.z()) > ZERO ) rpt.rotateY(asin(pt.pt()/Pr.z()));
     rpt.rotateZ(pt.phi());
     rpt = Direction<0>::pos()?
       Utilities::getBoostFromCM(make_pair(P, k))*rpt:
       Utilities::getBoostFromCM(make_pair(k, P))*rpt;
     Ph.transform(rpt);
     Pr.transform(rpt);
-  } catch ( ImpossibleKinematics ) {}
+  } catch ( ImpossibleKinematics & e ) {}
 }
 
 
 double PartonExtractor::fullFn(const PBIPair & pbins, Energy2 scale,
 			       pair<bool,bool> noLastPDF) {
   if(pbins.first->bin()->pdfDim()<=1) pbins.first->scale(scale);
   if(pbins.second->bin()->pdfDim()<=1) pbins.second->scale(scale);
   return fullFn(*pbins.first,noLastPDF.first)*fullFn(*pbins.second,noLastPDF.second);
 }
 
 double PartonExtractor::fullFn(const PartonBinInstance & pb,
 			       bool noLastPDF) {
   if ( !pb.incoming() ) return 1.0;
   if (noLastPDF)
     return 
       fullFn(*pb.incoming(),false) * pb.jacobian() * 
       pb.remnantWeight() * exp(-pb.li());
   return fullFn(*pb.incoming(),false) * pb.jacobian() * pb.remnantWeight() *
     pb.pdf()->xfl(pb.particleData(), pb.partonData(), pb.scale(),
 		  pb.li(), pb.incoming()->scale());
 }
 
 void PartonExtractor::
 construct(const PBIPair & pbins, tStepPtr step) const {
   // if a long chain we need to break some mother/child relationships
   if(pbins.first->incoming()) {
     if(pbins.first->incoming()->incoming()) {
       if(!pbins.first->parton()->parents().empty()) {
 	tParticleVector parents=pbins.first->parton()->parents();
 	tPPtr parton = pbins.first->parton();
 	for(unsigned int ix=0;ix<parents.size();++ix) parents[ix]->abandonChild(parton);
       }
     }
   }
   if(pbins.second->incoming()) {
     if(pbins.second->incoming()->incoming()) {
       if(!pbins.second->parton()->parents().empty()) {
 	tParticleVector parents=pbins.second->parton()->parents();
 	tPPtr parton = pbins.second->parton();
 	for(unsigned int ix=0;ix<parents.size();++ix) parents[ix]->abandonChild(parton);
       }
     }
   }
   Direction<0> dir(true);
   construct(*pbins.first, step);
   dir.reverse();
   construct(*pbins.second, step);
 }
 
 void PartonExtractor::
 construct(PartonBinInstance & pb, tStepPtr step, bool boost) const {
   if ( !pb.incoming() ) return;
   if ( boost ) pb.remnantHandler()->boostRemnants(pb);
   if ( pb.incoming()->incoming() ) {
     step->insertIntermediate(pb.particle(),pb.incoming()->particle(),pb.parton());
   }
   tPVector rem(pb.remnants().begin(), pb.remnants().end());
   if ( !step->addDecayProduct(pb.particle(), rem.begin(), rem.end(), false) )
     {}
   colourConnect(pb.particle(), pb.parton(), rem);
   construct(*pb.incoming(), step);
 }
 
 PBIPair PartonExtractor::newRemnants(tPPair oldp, tPPair newp, tStepPtr step) {
   PBIPair pb;
   Direction<0> dir(true);
   pb.first = newRemnants(partonBinInstance(oldp.first),
 			 newp.first, newp.second->momentum());
   dir.reverse();
   pb.second = newRemnants(partonBinInstance(oldp.second),
 			  newp.second, newp.first->momentum());
   addNewRemnants(partonBinInstance(oldp.first), pb.first, step);
   addNewRemnants(partonBinInstance(oldp.second), pb.second, step);
   return pb;
 }
 
 PBIPtr PartonExtractor::
 newRemnants(tPBIPtr oldpb, tPPtr newp, const LorentzMomentum & k) {
   if ( ! oldpb || !oldpb->incoming() ) return oldpb;
   Energy2 shat = (k + newp->momentum()).m2();
 
   // Loop over all possible PartonBin sisters to find the one
   // corresponding to the newly extracted parton.
   const PartonBin::PBVector & sisters = oldpb->incoming()->bin()->outgoing();
   for ( int i = 0, N = sisters.size(); i < N; ++i )
     if ( sisters[i]->parton() == newp->dataPtr() ) {
       // Setup necessary info in new PartonBinInstance object.
       PBIPtr newpb = new_ptr(PartonBinInstance(sisters[i], oldpb->incoming()));
       newpb->particle(oldpb->particle());
       newpb->parton(newp);
       newpb->li(log(oldpb->particle()->momentum().dirPlus()/
 		    newp->momentum().dirPlus()));
       newpb->l(oldpb->l() - oldpb->li() + newpb->li());
       Energy2 sc = -newp->scale();
       newpb->scale(newp->scale());
       if ( oldpb->incoming()->incoming() )
 	sc = -newpb->particle()->momentum().m2();
       // Now we can construct the new remnants.
       newpb->remnantWeight(1.0);
       if ( !newpb->remnantHandler()->
 	   recreateRemnants(*newpb, oldpb->parton(), newp, newpb->li(),
 			    sc, shat, newpb->particle()->momentum()) )
 	throw Veto();
       if ( newpb->remnantWeight() <= 0.0 ) throw Veto();
       return newpb;
     }
   throw Veto();
 }
 
 void PartonExtractor::
 addNewRemnants(tPBIPtr oldpb, tPBIPtr newpb, tStepPtr step) {
   if ( oldpb == newpb ) return;
   if ( oldpb->parton() != newpb->parton() ) {
     step->removeDecayProduct(newpb->particle(), oldpb->parton());
     if ( !step->addDecayProduct(newpb->particle(), newpb->parton()) )
       throw Veto();
   }
   tPVector rem(newpb->remnants().begin(), newpb->remnants().end());
   colourConnect(newpb->particle(), newpb->parton(), rem);
   partonBinInstances()[newpb->parton()] = newpb;
   if ( !step->addDecayProduct(oldpb->remnants().begin(),
 			      oldpb->remnants().end(),
  			      rem.begin(), rem.end()) )
     throw Veto();
 }
 
 void PartonExtractor::persistentOutput(PersistentOStream & os) const {
   os << theLastXComb << theSpecialDensities << theNoPDF << theMaxTries
      << flatSHatY << theFirstPDF << theSecondPDF;
 }
 
 void PartonExtractor::persistentInput(PersistentIStream & is, int) {
   is >> theLastXComb >> theSpecialDensities >> theNoPDF >> theMaxTries
      >> flatSHatY >> theFirstPDF >> theSecondPDF;
 }
 
 ClassDescription<PartonExtractor> PartonExtractor::initPartonExtractor;
 
 void PartonExtractor::Init() {
 
   static ClassDocumentation<PartonExtractor> documentation
     ("There is no documentation for the ThePEG::PartonExtractor class");
 
   static RefVector<PartonExtractor,PDFBase> interfaceSpecialDensities
     ("SpecialDensities",
      "A list of parton density objects to be used for incoming particles "
      "overriding possible densities given for particles of the "
      "BeamParticleData class.",
      &PartonExtractor::theSpecialDensities, 0, false, false, true, false);
 
   static Reference<PartonExtractor,PDFBase> interfaceNoPDF
     ("NoPDF",
      "A fixed reference to a NoPDF object to be used for particles without "
      "substructure.",
      &PartonExtractor::theNoPDF, true, true, true, false);
 
   static Parameter<PartonExtractor,int> interfaceMaxTries
     ("MaxTries",
      "The maximum number of attempts allowed when trying to generate "
      "remnants.",
      &PartonExtractor::theMaxTries, 100, 1, 1000, false, false, true);
 
   static Switch<PartonExtractor,bool> interfaceFlatSHatY
     ("FlatSHatY",
      "The possibility to override the l-generation in the PDFs and generate "
      "a flat distribution in \\f$\\log(\\hat{s})\\f$ and \\f$y\\f$. This only "
      "applies if the parton densities do not have poles in \\f$x=1\\f$.",
      &PartonExtractor::flatSHatY, false, false, false);
 
   static SwitchOption interfaceFlatSHatY0
     (interfaceFlatSHatY,
      "Off", "Use the l-generation defined by the PDFs", false);
 
   static SwitchOption interfaceFlatSHatY1
     (interfaceFlatSHatY,
      "On", "Generate flat rapidity and \\f$\\log(\\hat{s})\\f$", true);
 
   static SwitchOption interfaceFlatSHatNo
     (interfaceFlatSHatY,
      "No", "Use the l-generation defined by the PDFs", false);
 
   static SwitchOption interfaceFlatSHatYes
     (interfaceFlatSHatY,
      "Yes", "Generate flat rapidity and \\f$\\log(\\hat{s})\\f$", true);
 
   static Reference<PartonExtractor,PDFBase> interfaceFirstPDF
     ("FirstPDF",
      "PDF to override the default PDF for the first beam particle",
      &PartonExtractor::theFirstPDF, false, false, true, true, false);
 
   static Reference<PartonExtractor,PDFBase> interfaceSecondPDF
     ("SecondPDF",
      "PDF to override the default PDF for the second beam particle",
      &PartonExtractor::theSecondPDF, false, false, true, true, false);
 
 }
 
 RemColException::RemColException(const PartonExtractor & pe) {
   theMessage << "Parton extractor '" << pe.name() << "' failed to connect "
 	     << "the colours of the outgoing partons and the remnants.";
   severity(maybeabort);
 }
   
 void PartonExtractor::dofinish() {
   partonBinInstances().clear();
   HandlerBase::dofinish();
 }
diff --git a/PDT/DecayMode.cc b/PDT/DecayMode.cc
--- a/PDT/DecayMode.cc
+++ b/PDT/DecayMode.cc
@@ -1,691 +1,692 @@
 // -*- C++ -*-
 //
 // DecayMode.cc is a part of ThePEG - Toolkit for HEP Event Generation
 // Copyright (C) 1999-2017 Leif Lonnblad
 //
 // ThePEG 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 DecayMode class.
 //
 
 #include "DecayMode.h"
 #include "DecayMode.xh"
 #include "ThePEG/Repository/Repository.h"
 #include "ThePEG/Persistency/PersistentOStream.h"
 #include "ThePEG/Persistency/PersistentIStream.h"
 #include "ThePEG/Utilities/Rebinder.h"
 #include "ThePEG/Interface/Parameter.h"
 #include "ThePEG/Interface/Reference.h"
 #include "ThePEG/Interface/Switch.h"
 #include "ThePEG/Interface/ClassDocumentation.h"
 #include "ThePEG/Utilities/EnumIO.h"
 
 using namespace ThePEG;
 
 DecayMode::DecayMode()
   : theBrat(0.0), isOn(false) {}
 
 DecayMode::DecayMode(tPDPtr newParticle, double newBrat, bool newOn)
   : theBrat(newBrat), isOn(newOn), theParent(newParticle) {}
 
 DecayMode::DecayMode(const DecayMode & dm)
   : Interfaced(dm), theTag(dm.theTag), theBrat(dm.theBrat), isOn(dm.isOn),
     theParent(dm.theParent), theProducts(dm.theProducts),
     theOrderedProducts(dm.theOrderedProducts),
     theCascadeProducts(dm.theCascadeProducts), theMatchers(dm.theMatchers),
     theWildMatcher(dm.theWildMatcher), theExcluded(dm.theExcluded),
     theOverlap(dm.theOverlap), theDecayer(dm.theDecayer),
     theAntiPartner(dm.theAntiPartner), theLinks(dm.theLinks) {}
 
 DecayMode::~DecayMode() {}
 
 DMPtr DecayMode::Create(tPDPtr newParent, double newBrat, bool newOn) {
   DMPtr dm = new_ptr(DecayMode(newParent, newBrat, newOn));
   Repository::Register(dm, newParent->fullName() + "/NEWMODE");
   if ( !newParent->CC() ) return dm;
   DMPtr adm = new_ptr(DecayMode(newParent->CC(), newBrat, newOn));
   Repository::Register(adm, newParent->CC()->fullName() + "/NEWMODE");
   dm->theAntiPartner = adm;
   adm->theAntiPartner = dm;
   return dm;
 }
 
 void DecayMode::readSetup(istream & is) {
   string decnam;
   is >> theBrat >> ienum(isOn) >> decnam;
   if ( decnam.empty() ) return;
   BaseRepository::DirectoryAppend(decnam);
   setDecayer(BaseRepository::GetObject<tDecayerPtr>(decnam));	       
 }
 
 IBPtr DecayMode::clone() const {
   return dmclone();
 }
 
 DMPtr DecayMode::dmclone() const {
   return new_ptr(*this);
 }
 
 IBPtr DecayMode::fullclone() const {
   DMPtr dm = dmclone();
   Repository::Register(dm);
   if ( !CC() ) return dm;
   DMPtr adm = CC()->dmclone();
   Repository::Register(adm);
   dm->theAntiPartner = adm;
   adm->theAntiPartner = dm;
   return dm;
 }
 
 void DecayMode::doupdate() {
   Interfaced::doupdate();
   bool redo = touched();
   UpdateChecker::check(decayer(), redo);
   if ( !redo ) return;
   if ( theBrat > 0.0 && isOn && !decayer()->accept(*this) )
     throw DecModNoAccept(tag(), decayer()->name());
 }
 
 void DecayMode::rebind(const TranslationMap & trans) {
   try {
     theParent = trans.alwaysTranslate(theParent);
     ParticleMSet newProducts;
     trans.alwaysTranslate(inserter(newProducts),
 			  products().begin(), products().end());
     products().swap(newProducts);
     tPDVector newOrdered;
     trans.alwaysTranslate(inserter(newOrdered),
 			  orderedProducts().begin(), orderedProducts().end());
     theOrderedProducts.swap(newOrdered);
     ModeMSet newCasc;
     trans.alwaysTranslate(inserter(newCasc),
 			  cascadeProducts().begin(), cascadeProducts().end());
     cascadeProducts().swap(newCasc);
     MatcherMSet newMatchers;
     trans.alwaysTranslate(inserter(newMatchers),
 			  productMatchers().begin(), productMatchers().end());
     productMatchers().swap(newMatchers);
     wildProductMatcher() = trans.alwaysTranslate(wildProductMatcher());
     ParticleMSet newExclude;
     trans.alwaysTranslate(inserter(newExclude),
 			  excluded().begin(), excluded().end());
     excluded().swap(newExclude);
     theAntiPartner = trans.alwaysTranslate(CC());
 
     for ( int i = 0, N = theLinks.size(); i < N; ++i ) {
       theLinks[i].first = trans.alwaysTranslate(theLinks[i].first);
       theLinks[i].second = trans.alwaysTranslate(theLinks[i].second);
     }
   }
   catch (IBPtr ip) {
     throw DecModRebind(name(), ip->name());
   }
   catch (...) {
     throw DecModRebind(name(), "<unknown>");
   }
 }
 
 IVector DecayMode::getReferences() {
   IVector ret;
   ret.push_back(theParent);
   ret.insert(ret.end(), products().begin(), products().end());
   ret.insert(ret.end(), cascadeProducts().begin(), cascadeProducts().end());
   ret.insert(ret.end(), productMatchers().begin(), productMatchers().end());
   if ( wildProductMatcher() ) ret.push_back(wildProductMatcher());
   ret.insert(ret.end(), excluded().begin(), excluded().end());
   if ( CC() ) ret.push_back(CC());
   return ret;
 }
 
 bool DecayMode::addOverlap(tcDMPtr d) {
   bool inc = includes(*d);
   if ( !inc ) return false;
   if ( find(theOverlap.begin(), theOverlap.end(), d) != theOverlap.end() )
     return true;
   theOverlap.push_back(d);
   return true;
 }
 
 void DecayMode::resetOverlap() {
   theOverlap.clear();
 }
 
 bool DecayMode::
 compareId(const ParticleMSet & s1, const ParticleMSet & si2) const {
   if ( generator() ) return s1 == si2;
   ParticleMSet s2 = si2;
   for ( ParticleMSet::const_iterator p1 = s1.begin(); p1 != s1.end(); ++p1 ) {
     ParticleMSet::const_iterator p2 = s2.begin();
     while ( p2 != s2.end() && (**p2).id() != (**p1).id() ) ++p2;
     if ( p2 == s2.end() ) return false;
     s2.erase(p2);
   }
   return s2.empty();
 }
 
 ParticleMSet::const_iterator
 DecayMode::findId(const ParticleMSet & s, const ParticleData & p) const {
   for ( ParticleMSet::const_iterator pit = s.begin(); pit != s.end(); ++pit )
     if ( (**pit).id() == p.id() ) return pit;
   return s.end();
 }
 
 struct IdCmp {
   bool operator()(tcPDPtr p1, tcPDPtr p2) { return p1->id() == p2->id(); }
 };
 
 bool DecayMode::includes(const DecayMode & d) const {
   // Fast check for ordinary decay modes.
   if (  cascadeProducts().empty() && productMatchers().empty() &&
 	excluded().empty() &&  !wildProductMatcher() &&
 	d.cascadeProducts().empty() &&  d.productMatchers().empty() &&
 	d.excluded().empty() &&  !d.wildProductMatcher() ) {
     if ( links().size() != d.links().size() ) return false;
     if ( !compareId(products(), d.products()) ) return false;
     LinkVector dlinks = d.links();
     for ( int i = 0, N = links().size(); i < N; ++i ) {
       for ( int j = 0, M = dlinks.size(); j < M; ++j ) {
 	if ( ( links()[i].first->id() == dlinks[j].first->id() &&
 	       links()[i].second->id() == dlinks[j].second->id() ) ||
 	     ( links()[i].first->id() == dlinks[j].second->id() &&
 	       links()[i].second->id() == dlinks[j].first->id() ) ) {
 	  dlinks.erase(dlinks.begin() + j);
 	  break;
 	}
       }
       return false;
     }
     return dlinks.empty();
   }
 
   // First check that none of the excluded products in this are
   // present in the other.
   ParticleMSet::const_iterator pit;
   for ( pit = excluded().begin(); pit != excluded().end(); ++pit ) {
     if ( findId(d.products(), **pit ) != d.products().end() ) return false;
     for ( ModeMSet::const_iterator mit = d.cascadeProducts().begin();
 	  mit != d.cascadeProducts().end(); ++mit )
       if ( (**pit).id() == (**mit).parent()->id() ) return false;
   }
 
   // Check that all cascade decays in this overlaps with one in the
   // other. Save the ones that are left
   ModeMSet cascleft = d.cascadeProducts();
   for ( ModeMSet::iterator mit = cascadeProducts().begin();
 	mit != cascadeProducts().end(); ++mit ) {
     ModeMSet::iterator mit2 = cascleft.begin();
     while ( mit2 != cascleft.end() && !(**mit).includes(**mit2) ) ++mit2;
     if ( mit2 == cascleft.end() ) return false;
   }
 
 
   // Check that all cascade product parents in the other matches
   // something in this. Otherwise expand the cascade product.
   ParticleMSet partleft = d.products();
   MatcherMSet matchleft = d.productMatchers();
   ParticleMSet excludeleft = d.excluded();
   MatcherMSet wildleft;
   if ( d.wildProductMatcher() ) wildleft.insert(wildProductMatcher());
   ParticleMSet part = products();
   MatcherMSet match = productMatchers();
   while ( cascleft.size() ) {
     ModeMSet::iterator cdmit = cascleft.begin();
     cDMPtr cdm = *cdmit;
     ParticleMSet::iterator pit = findId(part, *(cdm->parent()));
     if ( pit != part.end() ) {
       cascleft.erase(cdmit);
       part.erase(pit);
     } else {
       MatcherMSet::iterator mit = match.begin();
       while ( mit != match.end() && !(**mit).matches(*(cdm->parent())) ) ++mit;
       if ( mit != match.end() ) {
 	cascleft.erase(cdmit);
 	match.erase(mit);
       } else {
 	if ( wildProductMatcher() &&
 	     wildProductMatcher()->matches(*(cdm->parent())) ) {
 	  cascleft.erase(cdmit);
 	} else {
 	  cascleft.erase(cdmit);
 	  partleft.insert(cdm->products().begin(), cdm->products().end());
 	  matchleft.insert(cdm->productMatchers().begin(),
 			   cdm->productMatchers().end());
 	  if ( cdm->wildProductMatcher() )
 	    wildleft.insert(cdm->wildProductMatcher());
 	  excludeleft.insert(cdm->excluded().begin(), cdm->excluded().end());
 	  cascleft.insert(cdm->cascadeProducts().begin(),
 			  cdm->cascadeProducts().end());
 	}
       }
     }
   }
 
   // Check that all excluded left in the other are absent in this.
   if ( find_first_of(excludeleft.begin(), excludeleft.end(), part.begin(),
 		     part.end(), IdCmp()) != excludeleft.end() ) return false;
 
   // Now all particles and matches left in this must match something
   // in the other.
   pit = part.begin();
   while ( pit != part.end() ) {
     ParticleMSet::iterator pit2 = findId(partleft, **pit++);
     if ( pit2 == partleft.end() ) return false;
     partleft.erase(pit2);
   }
   MatcherMSet::const_iterator pmit = match.begin();
   while ( pmit != match.end() ) {
     ParticleMSet::iterator pit2 = partleft.begin();
     while ( pit2 != partleft.end() && ! (**pmit).matches(**pit2) ) ++pit2;
     if ( pit2 != partleft.end() ) {
       partleft.erase(pit2);
     } else {
       MatcherMSet::iterator pmit2 = matchleft.begin();
       while ( pmit2 != matchleft.end() && ! (**pmit).matches(**pmit2) ) ++pmit2;
       if ( pmit2 != matchleft.end() ) {
 	matchleft.erase(pmit2);
       } else
 	return false;
     }
   }
 
   // Now all particles and matchers left in the other must be matched
   // by the wild match in this.
   if ( wildProductMatcher() ) {
     pit = partleft.begin();
     while ( pit != partleft.end() )
       if ( !(wildProductMatcher()->matches(**pit++)) ) return false;
     pmit = matchleft.begin();
     while (pmit != matchleft.end() )
       if ( !(wildProductMatcher()->matches(**pmit++)) ) return false;
     pmit = wildleft.begin();
     while (pmit != wildleft.end() )
       if ( !(wildProductMatcher()->matches(**pmit++)) ) return false;
   } else
     return partleft.empty() && matchleft.empty() && wildleft.empty();
   return true;
 }
 
 DMPtr DecayMode::clone(tPDPtr pd) const {
   DMPtr dm = dmclone();
   dm->theParent = pd;
   Repository::Register(dm, pd->fullName() + "/" + dm->name());
   if ( !theDecayer || !theDecayer->accept(*dm) ) dm->isOn = false;
   if ( pd->CC() ) {
     DMPtr adm = CC()? CC()->dmclone(): dmclone();
     adm->theParent = pd->CC();
     Repository::Register(adm, pd->CC()->fullName() + "/" + adm->name());
     dm->theAntiPartner = adm;
     adm->theAntiPartner = dm;
     if ( !adm->theDecayer->accept(*adm) ) adm->isOn = false;
   } else
     dm->theAntiPartner = DMPtr();
   return dm;
 }
 
 void DecayMode::synchronize() {
   if ( !CC() ) return;
   theBrat = CC()->theBrat;
   isOn = CC()->isOn;
   theDecayer = CC()->theDecayer;
 }
 
 struct ParticleOrdering {
   bool operator()(tcPDPtr p1, tcPDPtr p2) {
     return abs(p1->id()) > abs(p2->id()) ||
       ( abs(p1->id()) == abs(p2->id()) && p1->id() > p2->id() ) ||
       ( p1->id() == p2->id() && p1->fullName() > p2->fullName() );
   }
 };
 
 struct ModeOrdering {
   bool operator()(tcDMPtr d1, tcDMPtr d2) {
     ParticleOrdering ord;
     return ord(d1->parent(), d2->parent()) ||
       ( !ord(d2->parent(), d1->parent()) &&
 	( d1->tag() < d2->tag() ||
 	  ( d1->tag() == d2->tag() && d1->fullName() < d2->fullName() ) ) );
   }
 };
 
 struct MatcherOrdering {
   bool operator()(tcPMPtr m1, tcPMPtr m2) {
     return m1->name() < m2->name() ||
       ( m1->name() == m2->name() && m1->fullName() < m2->fullName() );
   }
 };
 
 PVector DecayMode::produceProducts() const {
   PVector ret;
   for ( int i = 0, N = orderedProducts().size(); i < N; ++i )
     ret.push_back(orderedProducts()[i]->produceParticle());
   return ret;
 }
 
 string DecayMode::makeTag() const {
   string ret;
   typedef multiset<tcPDPtr,ParticleOrdering> OrderedParticles;
   typedef multiset<tcPMPtr,MatcherOrdering> OrderedMatchers;
   typedef multiset<tcDMPtr,ModeOrdering> OrderedModes;
   LinkVector dlinks = links();
 
   ret = theParent->PDGName() + "->";
   if ( dlinks.empty() ) {
     OrderedParticles prod(products().begin(), products().end());
     for (OrderedParticles::iterator pit = prod.begin();
 	 pit != prod.end(); ++pit )
       ret += (**pit).PDGName() + ",";
   } else {
     unsigned int dl = 0;
     for ( int i = 0, N = orderedProducts().size(); i < N; ++i ) {
       if ( dl < dlinks.size() && orderedProducts()[i] == dlinks[dl].first ) {
 	ret +=  orderedProducts()[i]->PDGName() + "=";
 	++dl;
       } else 
 	ret +=  orderedProducts()[i]->PDGName() + ",";
     }
   }
 
   OrderedModes casc(cascadeProducts().begin(), cascadeProducts().end());
   for ( OrderedModes::iterator dmit = casc.begin();dmit != casc.end(); ++dmit )
     ret += "[" + (**dmit).tag() + "],";
   OrderedMatchers match(productMatchers().begin(), productMatchers().end());
   for ( OrderedMatchers::iterator mit = match.begin();
 	mit != match.end(); ++mit ) ret += "?" +(**mit).name() + ",";
   if ( theWildMatcher )
     ret += "*" + theWildMatcher->name() + ",";
   OrderedParticles ex(excluded().begin(), excluded().end());
   for ( OrderedParticles::iterator pit = ex.begin(); pit != ex.end(); ++pit )
     ret += "!" + (**pit).PDGName() + ",";
   ret[ret.size()-1] = ';';
   return ret;
 }
 
 void DecayMode::brat(double newBrat) {
   theBrat = newBrat;
   if ( theBrat <= 0.0 ) switchOff();
   if ( CC() && parent()->synchronized() ) CC()->theBrat = newBrat;
 }
 
 double DecayMode::brat() const {
   return isOn? theDecayer->brat(*this, *theParent, theBrat): 0.0;
 }
 
 double DecayMode::brat(const Particle & p) const {
   return isOn && p.dataPtr() == parent()?
     theDecayer->brat(*this, p, theBrat): 0.0;
 }
 
 void DecayMode::switchOn() {
   isOn = true;
   if ( CC() && parent()->synchronized() ) CC()->isOn = true;
 }
 
 void DecayMode::switchOff() {
   isOn = false;
   if ( CC() && parent()->synchronized() ) CC()->isOn = false;
 }
 
 void DecayMode::addProduct(tPDPtr pd) {
   products().insert(pd);
   theOrderedProducts.push_back(pd);
   if ( CC() ) {
     CC()->products().insert(pd->CC()? pd->CC(): pd);
     CC()->theOrderedProducts.push_back(pd->CC()? pd->CC(): pd);
   }
   resetTag();
 }
 
 void DecayMode::addLink(tPDPtr a, tPDPtr b) {
   theLinks.push_back(make_pair(a, b));
   if ( CC() ) CC()->theLinks.push_back(make_pair(a->CC()? a->CC(): a,
 						 b->CC()? b->CC(): b));
   resetTag();
 }
 
 void DecayMode::addCascadeProduct(tDMPtr dm) {
   cascadeProducts().insert(dm);
   if ( CC() ) CC()->cascadeProducts().insert(dm->CC()? dm->CC(): dm);
   resetTag();
 }
 
 void DecayMode::addProductMatcher( tPMPtr pm) {
   productMatchers().insert(pm);
   if ( CC() ) CC()->productMatchers().insert(pm->CC()? pm->CC(): pm);
   resetTag();
 }
 
 void DecayMode::setWildMatcher(tPMPtr pm) {
   wildProductMatcher() = pm;
   if ( CC() ) CC()->wildProductMatcher() = pm->CC()? pm->CC(): pm;
   resetTag();
 }
 
 void DecayMode::addExcluded(tPDPtr pd) {
   excluded().insert(pd);
   if ( CC() ) CC()->excluded().insert(pd->CC()? pd->CC(): pd);
   resetTag();
 }
 
 void DecayMode::decayer(tDecayerPtr dec) {
   if ( !dec || !dec->accept(*this) )
     throw DecModSetupNoAccept(tag(), dec->name());
   if ( CC() && parent()->synchronized() ) {
     if ( !dec->accept(*CC()) )
       throw DecModSetupNoAccept(CC()->tag(), dec->name());
     CC()->theDecayer = dec;
   }
   theDecayer = dec;
 }
 
 DMPtr DecayMode::constructDecayMode(string & tag, vector<DMPtr> * save) {
   DMPtr rdm;
   DMPtr adm;
   int level = 0;
   string::size_type end = 0;
   while ( end < tag.size() && ( tag[end] != ']' || level ) ) {
     switch ( tag[end++] ) {
     case '[':
       ++level;
       break;
     case ']':
       --level;
       break;
     }
   }
   string::size_type next = tag.find("->");
   if ( next == string::npos ) return rdm;
   if ( tag.find(';') == string::npos ) return rdm;
   tPDPtr pd = Repository::findParticle(tag.substr(0,next));
   if ( !pd ) return rdm;
 
   rdm = ptr_new<DMPtr>();
   rdm->parent(pd);
   if ( pd->CC() ) {
     adm = ptr_new<DMPtr>();
     adm->parent(pd->CC());
     rdm->theAntiPartner = adm;
     adm->theAntiPartner = rdm;
   }
   bool error = false;
   tag = tag.substr(next+2);
   tPDPtr lastprod;
   bool dolink = false;
   do {
     switch ( tag[0] ) {
     case '[':
       {
 	tag = tag.substr(1);
 	DMPtr cdm = constructDecayMode(tag, save);
 	if ( save ) save->push_back(cdm);
 	if ( cdm ) rdm->addCascadeProduct(cdm);
 	else error = true;
       } break;
     case '=':
       dolink = true;
+      [[fallthrough]]; 
     case ',':
     case ']':
       tag = tag.substr(1);
       break;
     case '?':
       {
 	next = min(tag.find(','), tag.find(';'));
 	tPMPtr pm = Repository::findMatcher(tag.substr(1,next-1));
 	if ( pm ) rdm->addProductMatcher(pm);
 	else error = true;
 	tag = tag.substr(next);
       } break;
     case '!':
       {
 	next = min(tag.find(','), tag.find(';'));
 	tPDPtr pd = Repository::findParticle(tag.substr(1,next-1));
 	if ( pd ) rdm->addExcluded(pd);
 	else error = true;
 	tag = tag.substr(next);
       } break;
     case '*':
       {
 	next = min(tag.find(','), tag.find(';'));
 	tPMPtr pm = Repository::findMatcher(tag.substr(1,next-1));
 	if ( pm ) rdm->setWildMatcher(pm);
 	else error = true;
 	tag = tag.substr(next);
       } break;
     default:
       {
 	next = min(tag.find('='), min(tag.find(','), tag.find(';')));
 	tPDPtr pdp = Repository::findParticle(tag.substr(0,next));
 	if ( pdp ) rdm->addProduct(pdp);
 	else error = true;
 	tag = tag.substr(next);
 	if ( dolink && lastprod ) {
 	  rdm->addLink(lastprod, pdp);
 	  dolink = false;
 	}
 	lastprod = pdp;
       } break;
     }
   } while ( tag[0] != ';' && tag.size() );
   if ( tag[0] != ';' || error ) {
     return DMPtr();
   }
 
   tag = tag.substr(1);
   
   for ( DecaySet::const_iterator dit = pd->decayModes().begin();
 	dit != pd->decayModes().end(); ++dit )
     if ( (**dit).tag() == rdm->tag() ) return *dit;
 
   if ( save ) {
     save->push_back(rdm);
     save->push_back(adm);
   } else {
     pd->addDecayMode(rdm);
     Repository::Register(rdm, pd->fullName() + "/" + rdm->tag());
     if ( adm )
       Repository::Register(adm, pd->CC()->fullName() + "/" + adm->tag());
   }
   return rdm;
 }
 
 void DecayMode::persistentOutput(PersistentOStream & os) const {
   multiset<tcPDPtr,ParticleOrdering> prod(products().begin(), products().end());
   multiset<tcDMPtr,ModeOrdering>
     casc(cascadeProducts().begin(), cascadeProducts().end());
   multiset<tcPMPtr,MatcherOrdering>
     match(productMatchers().begin(), productMatchers().end());
   multiset<tcPDPtr,ParticleOrdering>  ex(excluded().begin(), excluded().end());
   multiset<tcDMPtr,ModeOrdering> ovlap(overlap().begin(), overlap().end());
 
   os << theTag << theBrat << isOn << theParent << prod << theOrderedProducts
      << casc << match << theWildMatcher << ex << ovlap << theDecayer
      << theAntiPartner << theLinks;
 }
 
 void DecayMode::persistentInput(PersistentIStream & is, int) {
   is >> theTag >> theBrat >> isOn >> theParent >> theProducts
      >> theOrderedProducts >> theCascadeProducts >> theMatchers
      >> theWildMatcher >> theExcluded >> theOverlap >> theDecayer
      >> theAntiPartner >> theLinks;
 }
 
 ClassDescription<DecayMode> DecayMode::initDecayMode;
 
 void DecayMode::setOn(long i) {
   isOn = i;
 }
 
 long DecayMode::getOn() const {
   return isOn;
 }
 
 void DecayMode::setDecayer(DecayerPtr dp) {
   decayer(dp);
 }
 
 void DecayMode::Init() {
 
   static ClassDocumentation<DecayMode> documentation
     ("Represents a specific decay channel of a particle.");
 
   static Parameter<DecayMode,double> interfaceBrat
     ("BranchingRatio",
      "The branching fraction for this decay mode. Note that if the sum of "
      "branching ratios for one particle is always renormalized to 1. Also, "
      "the decaying particle may change this branching ratio if it has a "
      "ThePEG::WidthGenerator object assigned to it. ",
      &DecayMode::theBrat, 0.0, 0.0, 1.0, false, false, true);
   interfaceBrat.setHasDefault(false);
 
   static Switch<DecayMode> interfaceOn
     ("OnOff",
      "Indicates if the decay mode is switched on or off.",
      0, 0, false, false, &DecayMode::setOn, &DecayMode::getOn);
   static SwitchOption interfaceOnYes
     (interfaceOn, "On", "The decay channel is switched on.", 1);
   static SwitchOption interfaceOnNo
     (interfaceOn, "Off", "The decay channel is switched off.", 0);
   interfaceOn.setHasDefault(false);
 
   static Switch<DecayMode> interfaceActive
     ("Active",
      "Indicates if the decay mode is switched on or off.",
      0, 0, false, false, &DecayMode::setOn, &DecayMode::getOn);
   static SwitchOption interfaceActiveYes
     (interfaceActive, "Yes", "The decay channel is switched on.", 1);
   static SwitchOption interfaceActiveNo
     (interfaceActive, "No", "The decay channel is switched off.", 0);
   interfaceActive.setHasDefault(false);
 
   static Reference<DecayMode,Decayer> interfaceDecayer
     ("Decayer",
      "The ThePEG::Decayer object responsible for performing this decay.",
      &DecayMode::theDecayer, false, false, true, false,
      &DecayMode::setDecayer);
 
   interfaceBrat.rank(10);
   interfaceDecayer.rank(9);
   interfaceOn.rank(8);
   interfaceActive.rank(8);
 
 }
 
 DecModNoAccept::DecModNoAccept(string tag, string dec) {
   theMessage << "The Decayer '" << dec << "' is not capable to "
 	     << "perform the decay in the DecayMode '" << tag << "'.";
   severity(warning);
 }
 
 DecModSetupNoAccept::DecModSetupNoAccept(string tag, string dec) {
   theMessage << "The Decayer '" << dec << "' is not capable to "
 	     << "perform the decay in the DecayMode '" << tag << "'.";
   severity(warning);
 }
 
 DecModRebind::DecModRebind(string tag, string obj) {
   theMessage << "'Rebind' of DecayMode '" << tag << "' failed because "
 	     << "the object '" << obj << "' refered to lacked a translation.";
   severity(abortnow);
 }
diff --git a/PDT/ParticleData.cc b/PDT/ParticleData.cc
--- a/PDT/ParticleData.cc
+++ b/PDT/ParticleData.cc
@@ -1,1038 +1,1038 @@
 // -*- C++ -*-
 //
 // ParticleData.cc is a part of ThePEG - Toolkit for HEP Event Generation
 // Copyright (C) 1999-2017 Leif Lonnblad
 //
 // ThePEG 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 ParticleData class.
 //
 
 #include "ParticleData.h"
 #include "ParticleData.xh"
 #include "ThePEG/PDT/DecayMode.h"
 #include "ThePEG/Utilities/HoldFlag.h"
 #include "ThePEG/Utilities/Rebinder.h"
 #include "ThePEG/Utilities/StringUtils.h"
 #include "ThePEG/EventRecord/Particle.h"
 #include "ThePEG/Interface/Parameter.h"
 #include "ThePEG/Interface/Switch.h"
 #include "ThePEG/Interface/Reference.h"
 #include "ThePEG/Interface/RefVector.h"
 #include "ThePEG/Interface/Command.h"
 #include "ThePEG/Interface/ClassDocumentation.h"
 #include "ThePEG/Repository/Repository.h"
 #include "ThePEG/Persistency/PersistentOStream.h"
 #include "ThePEG/Persistency/PersistentIStream.h"
 #include "ThePEG/Config/algorithm.h"
 #include "ThePEG/Utilities/Exception.h"
 #include "ThePEG/Utilities/EnumIO.h"
 #include "ThePEG/Repository/UseRandom.h"
 
 namespace ThePEG {
 
 ParticleData::ParticleData()
   : theId(0), thePDGName(""), theMass(-1.0*GeV), theWidth(-1.0*GeV),
     theHardProcessMass(-1.0*GeV), hardProcessMassSet(false),
     theHardProcessWidth(-1.0*GeV), hardProcessWidthSet(false),
     theWidthUpCut(-1.0*GeV), theWidthLoCut(-1.0*GeV), theCTau(-1.0*mm),
     theCharge(PDT::ChargeUnknown),
     theSpin(PDT::SpinUnknown), theColour(PDT::ColourUnknown), isStable(true),
     theVariableRatio(false), syncAnti(false), theDefMass(-1.0*GeV),
     theDefWidth(-1.0*GeV), theDefCut(-1.0*GeV), theDefCTau(-1.0*mm),
     theDefCharge(PDT::ChargeUnknown), theDefSpin(PDT::SpinUnknown),
     theDefColour(PDT::ColourUnknown) {}
 
 ParticleData::
 ParticleData(PID newId, const string & newPDGName)
   : theId(newId), thePDGName(newPDGName), theMass(-1.0*GeV), theWidth(-1.0*GeV),
     theHardProcessMass(-1.0*GeV), hardProcessMassSet(false),
     theHardProcessWidth(-1.0*GeV), hardProcessWidthSet(false),
     theWidthUpCut(-1.0*GeV), theWidthLoCut(-1.0*GeV), theCTau(-1.0*mm),
     theCharge(PDT::ChargeUnknown),
     theSpin(PDT::SpinUnknown), theColour(PDT::ColourUnknown), isStable(true),
     theVariableRatio(false), syncAnti(false), theDefMass(-1.0*GeV),
     theDefWidth(-1.0*GeV), theDefCut(-1.0*GeV), theDefCTau(-1.0*mm),
     theDefCharge(PDT::ChargeUnknown), theDefSpin(PDT::SpinUnknown),
     theDefColour(PDT::ColourUnknown) {}
 
 ParticleData::~ParticleData() {}
 
 PDPtr ParticleData::Create(PID newId, const string & newPDGName) {
   return new_ptr(ParticleData(newId, newPDGName));
 }
 
 PDPair ParticleData::
 Create(PID newId, const string & newPDGName, const string & newAntiPDGName) {
   PDPair pap;
   pap.first = new_ptr(ParticleData(newId, newPDGName));
   pap.second = new_ptr(ParticleData(-newId, newAntiPDGName));
   antiSetup(pap);
   return pap;
 }
 
 void ParticleData::readSetup(istream & is) {
   long id;
   is >> id >> thePDGName >> iunit(theDefMass, GeV) >> iunit(theDefWidth, GeV)
      >> iunit(theDefCut, GeV) >> iunit(theDefCTau, mm) >> ienum(theDefCharge)
      >> ienum(theDefColour) >> ienum(theDefSpin) >> ienum(isStable);
   theId = id;
   theMass = theDefMass;
   theWidth = theDefWidth;
   theWidthUpCut = theDefCut;
   theWidthLoCut = theDefCut;
   theCTau = theDefCTau;
   theCharge = theDefCharge;
   theColour = theDefColour;
   theSpin = theDefSpin;
   if ( PDGName() == "-" ) thePDGName = name();
   return;
 }
   
 void ParticleData::antiSetup(const PDPair & pap) {
   pap.first->theAntiPartner = pap.second;
   pap.second->theAntiPartner = pap.first;
   pap.first->syncAnti = pap.second->syncAnti = true;
 }
 
 PDPtr ParticleData::pdclone() const {
   return new_ptr(*this);
 }
 
 IBPtr ParticleData::clone() const {
   return pdclone();
 }
   
 IBPtr ParticleData::fullclone() const {
   PDPtr pd = pdclone();
   Repository::Register(pd);
   pd->theDecaySelector.clear();
   pd->theDecayModes.clear();
   pd->isStable = true;
   PDPtr apd;
   if ( CC() ) {
     apd = CC()->pdclone();
     Repository::Register(apd);
     apd->theDecaySelector.clear();
     apd->theDecayModes.clear();
     apd->isStable = true;
     pd->theAntiPartner = apd;
     apd->theAntiPartner = pd;
     pd->syncAnti = syncAnti;
     apd->syncAnti = CC()->syncAnti;
   }
   HoldFlag<> dosync(pd->syncAnti, true);
   for ( DecaySet::const_iterator it = theDecayModes.begin();
 	it != theDecayModes.end(); ++it )
     pd->addDecayMode(*it);
   return pd;
 }
 
 Energy ParticleData::mass(Energy mi) {
   theMass = mi;
   if ( synchronized() && CC() ) CC()->theMass = theMass;
   return theMass;
 }
 
 Energy ParticleData::width(Energy wi) {
   theWidth = wi;
   if ( synchronized() && CC() ) CC()->theWidth = theWidth;
   return theWidth;
 }
 
 Energy ParticleData::widthUpCut(Energy wci) {
   theWidthUpCut = wci;
   if ( synchronized() && CC() ) CC()->theWidthUpCut = theWidthUpCut;
   return theWidthUpCut;
 }
 
 Energy ParticleData::widthLoCut(Energy wci) {
   theWidthLoCut = wci;
   if ( synchronized() && CC() ) CC()->theWidthLoCut = theWidthLoCut;
   return theWidthLoCut;
 }
 
 Length ParticleData::cTau(Length ti) {
   theCTau = ti;
   if ( synchronized() && CC() ) CC()->theCTau = theCTau;
   return theCTau;
 }
 
 PDT::Charge ParticleData::iCharge(PDT::Charge ci) {
   theCharge = ci;
   if ( synchronized() && CC() ) CC()->theCharge = PDT::Charge(-ci);
   return theCharge;
 }
 
 PDT::Spin ParticleData::iSpin(PDT::Spin si) {
   theSpin = si;
   if ( synchronized() && CC() ) CC()->theSpin = si;
   return si;
 }
 
 PDT::Colour ParticleData::iColour(PDT::Colour ci) {
   theColour = ci;
   if ( synchronized() && CC() ) CC()->theColour = PDT::Colour(-ci);
   return theColour;
 }
 
 void ParticleData::stable(bool s) {
   isStable = s;
   if ( synchronized() && CC() ) CC()->isStable = s;
 }
 
 void ParticleData::synchronized(bool h) {
   syncAnti = h;
   if ( CC() ) CC()->syncAnti = h;
 }
 
 void ParticleData::variableRatio(bool varRatio) {
   theVariableRatio=varRatio;
 }
 
 void ParticleData::addDecayMode(tDMPtr dm) {
   if ( member(theDecayModes, dm) ) return;
   cPDPtr parent = dm->parent();
   if ( !parent ) parent = this;
   if ( parent != this ) {
     dm = dm->clone(this);
   }
   theDecayModes.insert(dm);
   theDecaySelector.insert(dm->brat(), dm);
   if ( CC() ) {
     if ( !synchronized() ) dm->CC()->switchOff();
     CC()->theDecayModes.insert(dm->CC());
     CC()->theDecaySelector.insert(dm->CC()->brat(), dm->CC());
   }
 }
 
 void ParticleData::removeDecayMode(tDMPtr dm) {
   theDecayModes.erase(theDecayModes.find(dm));
   if(theDecayModes.empty()) isStable = true;
   theDecaySelector.erase(dm);
   if ( !CC() ) return;
   CC()->theDecayModes.erase(dm->CC());
   if(CC()->theDecayModes.empty()) CC()->isStable = true;
   CC()->theDecaySelector.erase(dm->CC());
 }
 
 void ParticleData::synchronize() {
   if ( !CC() ) return;
   isStable = CC()->isStable;
   theMass = CC()->theMass;
   theHardProcessMass = CC()->theHardProcessMass;
   hardProcessMassSet = CC()->hardProcessMassSet;
   theWidth = CC()->theWidth;
   theHardProcessWidth = CC()->theHardProcessWidth;
   hardProcessWidthSet = CC()->hardProcessWidthSet;
   theWidthUpCut = CC()->theWidthUpCut;
   theWidthLoCut = CC()->theWidthLoCut;
   theCTau = CC()->theCTau;
   theCharge = PDT::Charge(-CC()->theCharge);
   theSpin = CC()->theSpin;
   theColour = PDT::antiColour(CC()->theColour);
   theMassGenerator = CC()->theMassGenerator;
   theWidthGenerator = CC()->theWidthGenerator;
   syncAnti = CC()->syncAnti;
   theDecaySelector.clear();
   for ( DecaySet::iterator it = theDecayModes.begin();
 	it != theDecayModes.end(); ++it ) {
     (*it)->synchronize();
     theDecaySelector.insert((*it)->brat(), *it);
   }
 }
 
 void ParticleData::doupdate() {
   Interfaced::doupdate();
   bool redo = touched();
   for_each(theDecayModes, UpdateChecker(redo));
   UpdateChecker::check(theMassGenerator, redo);
   UpdateChecker::check(theWidthGenerator, redo);
   if ( !redo ) return;
 
   theDecaySelector.clear();
   for ( DecaySet::const_iterator dit = theDecayModes.begin();
 	dit != theDecayModes.end(); ++dit ) {
     tDMPtr dm = *dit;
     dm->resetOverlap();
     for ( DecaySet::const_iterator dit2 = theDecayModes.begin();
 	  dit2 != theDecayModes.end(); ++dit2 )
       if ( dit2 != dit ) dm->addOverlap(dm);
     if ( dm->brat() > 0.0 ) theDecaySelector.insert(dm->brat(), dm);
   }
   if ( theMassGenerator && !theMassGenerator->accept(*this) )
     throw UpdateException();
   if ( theWidthGenerator &&
        !theWidthGenerator->accept(*this) )
     throw UpdateException();
   if ( theWidthGenerator ) theDecaySelector = theWidthGenerator->rate(*this);
   touch();
 }
 
 tDMPtr ParticleData::selectMode(Particle & p) const {
   if ( &(p.data()) != this ) return tDMPtr();
   try {
     if ( !theWidthGenerator || !theVariableRatio )
       return theDecaySelector.select(UseRandom::current());
     DecaySelector local;
     if ( theWidthGenerator )
       local = theWidthGenerator->rate(p);
     else
       for ( DecaySet::const_iterator mit = theDecayModes.begin();
 	    mit != theDecayModes.end(); ++mit  )
 	local.insert((*mit)->brat(p), *mit);
     return local.select(UseRandom::current());
   }
-  catch (range_error) {
+  catch (range_error & e) {
     return tDMPtr();
   }
 }
 
 void ParticleData::rebind(const TranslationMap & trans) {
   if ( CC() ) theAntiPartner = trans.translate(theAntiPartner);
   DecaySet newModes;
   DecaySelector newSelector;
   for ( DecaySet::iterator it = theDecayModes.begin();
 	it != theDecayModes.end(); ++it ) {
     DMPtr dm;
     dm = trans.translate(*it);
     if ( !dm ) throw RebindException();
     newModes.insert(dm);
     newSelector.insert(dm->brat(), dm);
   }
   theDecayModes.swap(newModes);
   theDecaySelector.swap(newSelector);
 }
 
 IVector ParticleData::getReferences() {
   IVector refs = Interfaced::getReferences();
   if ( CC() ) refs.push_back(CC());
   refs.insert(refs.end(), theDecayModes.begin(), theDecayModes.end());
   return refs;
 }
 
 
 
 void ParticleData::massGenerator(tMassGenPtr mg) {
   if ( mg && !mg->accept(*this) ) return;
   if ( mg && synchronized() && CC() && !mg->accept(*CC()) ) return;
   theMassGenerator = mg;
   if ( synchronized() && CC() ) CC()->theMassGenerator = mg;
 }
 
 void ParticleData::widthGenerator(tWidthGeneratorPtr newGen) {
   if ( newGen && !newGen->accept(*this) ) return;
   if ( newGen && synchronized() && CC() && !newGen->accept(*CC()) ) return;
   theWidthGenerator = newGen;
   if ( synchronized() && CC() ) CC()->theWidthGenerator = newGen;
 }
 
 Energy ParticleData::generateMass() const {
   return massGenerator()? massGenerator()->mass(*this): mass();
 }
 
 Energy ParticleData::generateWidth(Energy m) const {
   return widthGenerator()? widthGenerator()->width(*this, m): width();
 }
 
 Length ParticleData::generateLifeTime(Energy m, Energy w) const {
   return widthGenerator() ? 
     widthGenerator()->lifeTime(*this, m, w) :
     UseRandom::rndExp(cTau());
 }
 
 PPtr ParticleData::produceParticle(const Lorentz5Momentum & pp) const {
   PPtr p = new_ptr(Particle(this));
   p->set5Momentum(pp);
   return p;
 }
 
 PPtr ParticleData::produceParticle(const LorentzMomentum & pp) const {
   PPtr p(produceParticle(Lorentz5Momentum(pp)));
   return p;
 }
 
 PPtr ParticleData::produceParticle(const LorentzMomentum & pp, Energy m) const {
   PPtr p(produceParticle(Lorentz5Momentum(pp, m)));
   return p;
 }
 
 PPtr ParticleData::produceParticle(Energy m, const Momentum3 & pp) const {
   PPtr p(produceParticle(Lorentz5Momentum(m, pp)));
   return p;
 }
 
 PPtr ParticleData::produceParticle(const Momentum3 & pp) const {
   PPtr p(produceParticle(Lorentz5Momentum(generateMass(), pp)));
   return p;
 }
 
 PPtr ParticleData::
 produceParticle(Energy plus, Energy minus, Energy px, Energy py) const {
   PPtr p(produceParticle(LorentzMomentum(px, py, 0.5*(plus-minus),
 					 0.5*(plus+minus))));
   return p;
 }
 
 void ParticleData::setMass(Energy mi) {
   mass(mi);
 }
 
 void ParticleData::setHardProcessMass(Energy mi) {
   theHardProcessMass = mi;
   hardProcessMassSet = true;
   ParticleData * apd = CC().operator->();
   if ( synchronized() && apd ) {
     apd->theHardProcessMass = theHardProcessMass;
     apd->hardProcessMassSet = true;
   }
 }
 
 void ParticleData::setHardProcessWidth(Energy mi) {
   theHardProcessWidth = mi;
   hardProcessWidthSet = true;
   ParticleData * apd = CC().operator->();
   if ( synchronized() && apd ) {
     apd->theHardProcessWidth = theHardProcessWidth;
     apd->hardProcessWidthSet = true;
   }
 }
 
 string ParticleData::doUnsetHardProcessMass(string) {
   hardProcessMassSet = false;  
   theHardProcessMass = -1.*GeV;
   return "";
 }
 
 string ParticleData::doAdjustNominalMass(string) {
   if ( hardProcessMassSet )
     setMass(theHardProcessMass);
   return "";
 }
   
 string ParticleData::doUnsetHardProcessWidth(string) {
   hardProcessWidthSet = false;  
   theHardProcessWidth = -1.*GeV;
   return "";
 }
 
 Energy ParticleData::defMass() const {
   return theDefMass;
 }
 
 void ParticleData::setWidth(Energy wi) {
   width(wi);
 }
 
 Energy ParticleData::getWidth() const {
   return width();
 }
 
 Energy ParticleData::defWidth() const {
   return theDefWidth;
 }
 
 void ParticleData::setCut(Energy ci) {
   widthCut(ci);
 }
 
 Energy ParticleData::getCut() const {
   return (theWidthUpCut >= ZERO && theWidthLoCut >= ZERO)?
     max(theWidthUpCut, theWidthLoCut): min(theWidthUpCut, theWidthLoCut);
 }
 
 Energy ParticleData::defCut() const {
   return theDefCut;
 }
 
 void ParticleData::setUpCut(Energy ci) {
   widthUpCut(ci);
 }
 
 Energy ParticleData::getUpCut() const {
   return theWidthUpCut;
 }
 
 void ParticleData::setLoCut(Energy ci) {
   widthLoCut(ci);
 }
 
 Energy ParticleData::getLoCut() const {
   return theWidthLoCut;
 }
 
 void ParticleData::setCTau(Length ti) {
   cTau(ti);
 }
 
 Length ParticleData::getCTau() const {
   return cTau();
 }
 
 Length ParticleData::defCTau() const {
   return theDefCTau;
 }
 
 void ParticleData::setStable(long is) {
   stable(is);
 }
 
 long ParticleData::getStable() const {
   return stable();
 }
 
 void ParticleData::setSync(long is) {
   synchronized(is);
 }
 
 long ParticleData::getSync() const {
   return synchronized();
 }
 
 void ParticleData::setVariableRatio(long is) {
   variableRatio(is);
 }
 
 long ParticleData::getVariableRatio() const {
   return variableRatio();
 }
 
 string ParticleData::doSync(string) {
   synchronize();
   return "";
 }
 
 void ParticleData::setMassGenerator(MassGenPtr gi) {
   massGenerator(gi);
 }
 
 void ParticleData::setWidthGenerator(WidthGeneratorPtr wg) {
   widthGenerator(wg);
 }
 
 void ParticleData::setColour(long c) {
   theColour = PDT::Colour(c);
 }
 
 long ParticleData::getColour() const {
   return theColour;
 }
 
 long ParticleData::defColour() const {
   return theDefColour;
 }
 
 void ParticleData::setCharge(int c) {
   theCharge = PDT::Charge(c);
 }
 
 string ParticleData::ssetCharge(string arg) {
   istringstream is(arg);
   long i;
   if ( is >> i ) {
     theCharge = PDT::Charge(i);
     return "New charge is " + arg;
   }
   if ( arg == "unknown" )
     theCharge = PDT::ChargeUnknown;
   else if ( arg == "charged" )
     theCharge = PDT::Charged;
   else if ( arg == "positive" )
     theCharge = PDT::Positive;
   else if ( arg == "negative" )
     theCharge = PDT::Negative;
   else throw ParticleChargeCommand(*this, arg);
   return  "New charge is " + arg;
 }
 
 int ParticleData::getCharge() const {
   return theCharge;
 }
 
 int ParticleData::defCharge() const {
   return theDefCharge;
 }
 
 void ParticleData::setSpin(int s) {
   theSpin = PDT::Spin(s);
 }
 
 int ParticleData::getSpin() const {
   return theSpin;
 }
 
 int ParticleData::defSpin() const {
   return theDefSpin;
 }
 
 ClassDescription<ParticleData> ParticleData::initParticleData;
 
 struct ParticleOrdering {
   bool operator()(tcPDPtr p1, tcPDPtr p2) {
     return abs(p1->id()) > abs(p2->id()) ||
       ( abs(p1->id()) == abs(p2->id()) && p1->id() > p2->id() ) ||
       ( p1->id() == p2->id() && p1->fullName() > p2->fullName() );
   }
 };
 
 struct ModeOrdering {
   bool operator()(const tcDMPtr & d1, const tcDMPtr & d2) {
     ParticleOrdering ord;
     return ord(d1->parent(), d2->parent()) ||
       ( !ord(d2->parent(), d1->parent()) &&
 	( d1->tag() < d2->tag() ||
 	  ( d1->tag() == d2->tag() && d1->fullName() < d2->fullName() ) ) );
   }
 };
 
 void ParticleData::persistentOutput(PersistentOStream & os) const {
   multiset<tcDMPtr,ModeOrdering>
     modes(theDecayModes.begin(), theDecayModes.end());
   os << long(theId) << thePDGName << ounit(theMass, GeV) << ounit(theWidth, GeV)
      << ounit(theHardProcessMass,GeV) << hardProcessMassSet
      << ounit(theHardProcessWidth,GeV) << hardProcessWidthSet
      << ounit(theWidthUpCut, GeV) << ounit(theWidthLoCut, GeV)
      << ounit(theCTau, mm) << oenum(theCharge) << oenum(theSpin)
      << oenum(theColour);
   os << theMassGenerator << isStable << modes << theDecaySelector
      << theWidthGenerator << theVariableRatio << theAntiPartner << syncAnti
      << ounit(theDefMass, GeV) << ounit(theDefWidth, GeV)
      << ounit(theDefCut, GeV) << ounit(theDefCTau, mm) << oenum(theDefColour)
      << oenum(theDefCharge) << oenum(theDefSpin);
 }
 
 void ParticleData::persistentInput(PersistentIStream & is, int) {
   long id;
   is >> id >> thePDGName >> iunit(theMass, GeV) >> iunit(theWidth, GeV)
      >> iunit(theHardProcessMass,GeV) >> hardProcessMassSet
      >> iunit(theHardProcessWidth,GeV) >> hardProcessWidthSet
      >> iunit(theWidthUpCut, GeV) >> iunit(theWidthLoCut, GeV)
      >> iunit(theCTau, mm) >> ienum(theCharge) >> ienum(theSpin)
      >> ienum(theColour) >> theMassGenerator >> isStable
      >> theDecayModes >> theDecaySelector >> theWidthGenerator >> theVariableRatio
      >> theAntiPartner >> syncAnti >> iunit(theDefMass, GeV)
      >> iunit(theDefWidth, GeV) >> iunit(theDefCut, GeV)
      >> iunit(theDefCTau, mm) >> ienum(theDefColour) >> ienum(theDefCharge)
      >> ienum(theDefSpin);
   theId = id;
 }
 
 void ParticleData::Init() {
 
   static ClassDocumentation<ParticleData> documentation
     ("There is no documentation for the ThePEG::ParticleData class");
 
   static Parameter<ParticleData,Energy> interfaceMass
     ("NominalMass",
      "The nominal mass in GeV of the particle. The actual mass "
      "of a particle instance is generated depending on the "
      "nominal mass and the width and is generated by the "
      "<interface>Mass_generator</interface> object associated with the "
      "particle.",
      &ParticleData::theMass, GeV, ZERO, ZERO, Constants::MaxEnergy,
      false, false, Interface::lowerlim,
      &ParticleData::setMass, 0, 0, 0, &ParticleData::defMass);
 
   static Parameter<ParticleData,Energy> interfaceHardProcessMass
     ("HardProcessMass",
      "The mass in GeV of the particle to be used in calculating hard process cross sections.",
      &ParticleData::theHardProcessMass, GeV, ZERO, ZERO, Constants::MaxEnergy,
      false, false, Interface::lowerlim,
      &ParticleData::setHardProcessMass, 0, 0, 0, 0);
 
   static Parameter<ParticleData,Energy> interfaceDefMass
     ("DefaultMass",
      "The default nominal mass in GeV of the particle. The actual mass "
      "of a particle instance is generated depending on the "
      "nominal mass and the width and is generated by the "
      "<interface>Mass_generator</interface> object associated with the "
      "particle.",
      &ParticleData::theDefMass, GeV, ZERO, ZERO, Constants::MaxEnergy,
      false, true, Interface::lowerlim);
   interfaceDefMass.setHasDefault(false);
 
   static Parameter<ParticleData,Energy> interfaceWidth
     ("Width",
      "The width of the particle in GeV.",
      0, GeV, ZERO, ZERO, Constants::MaxEnergy,
      false, false, Interface::lowerlim,
      &ParticleData::setWidth, &ParticleData::getWidth,
      0, 0, &ParticleData::defWidth);
 
   static Parameter<ParticleData,Energy> interfaceHardProcessWidth
     ("HardProcessWidth",
      "The width in GeV of the particle to be used in calculating hard process cross sections.",
      &ParticleData::theHardProcessWidth, GeV, ZERO, ZERO, Constants::MaxEnergy,
      false, false, Interface::lowerlim,
      &ParticleData::setHardProcessWidth, 0, 0, 0, 0);
 
   static Parameter<ParticleData,Energy> interfaceDefWidth
     ("DefaultWidth",
      "The default width of the particle in GeV.",
      &ParticleData::theDefWidth, GeV, ZERO, ZERO, Constants::MaxEnergy,
      false, true, Interface::lowerlim);
   interfaceDefWidth.setHasDefault(false);
 
   static Parameter<ParticleData,Energy> interfaceWidthUpCut
     ("WidthUpCut",
      "The upper hard cutoff in GeV in generated mass, which is the maximum "
      "allowed upwards deviation from the nominal mass. A negative value "
      "corresponds to no limit.",
      0, GeV, ZERO, -1.0*GeV, Constants::MaxEnergy,
      false, false, Interface::lowerlim,
      &ParticleData::setUpCut, &ParticleData::getUpCut,
      0, 0, &ParticleData::defCut);
   
   static Parameter<ParticleData,Energy> interfaceWidthLoCut
     ("WidthLoCut",
      "The lower hard cutoff in GeV in generated mass, which is the maximum "
      "allowed downwards deviation from the nominal mass. A negative value "
      "corresponds to no limit.",
      0, GeV, ZERO, -1.0*GeV, Constants::MaxEnergy,
      false, false, Interface::lowerlim,
      &ParticleData::setLoCut, &ParticleData::getLoCut,
      0, 0, &ParticleData::defCut);
   
   static Parameter<ParticleData,Energy> interfaceWidthCut
     ("WidthCut",
      "The hard cutoff in GeV in generated mass, which is the maximum "
      "allowed deviation from the nominal mass. Sets both the upper and lower "
      "cut. (The displayed value is the maximium of the upper and lower cut.) "
      "A negative value corresponds to no limit.",
      0, GeV, ZERO, -1.0*GeV, Constants::MaxEnergy,
      false, false, Interface::lowerlim,
      &ParticleData::setCut, &ParticleData::getCut,
      0, 0, &ParticleData::defCut);
   interfaceWidthCut.setHasDefault(false);
   
   static Parameter<ParticleData,Energy> interfaceDefWidthCut
     ("DefaultWidthCut",
      "The default hard cutoff in GeV in generated mass, which is the maximum "
      "allowed deviation from the nominal mass. For the actual cutoff, the "
      "upper and lower cut can be set separately.",
      &ParticleData::theDefCut, GeV, ZERO, ZERO, Constants::MaxEnergy,
      false, true, Interface::lowerlim);
   interfaceDefWidthCut.setHasDefault(false);
   
   static Parameter<ParticleData,Length> interfaceCTau
     ("LifeTime",
      "c times the average lifetime of the particle measuerd in mm."
      "The actual lifetime of a particle instance is generated "
      "from this number by the <interface>Mass_generator</interface> "
      "object associated with the particle.",
      0, mm, ZERO, ZERO, Constants::MaxLength,
      false, false, Interface::lowerlim,
      &ParticleData::setCTau, &ParticleData::getCTau,
      0, 0, &ParticleData::defCTau);
   interfaceCTau.setHasDefault(false);
 
   static Parameter<ParticleData,Length> interfaceDefCTau
     ("DefaultLifeTime",
      "c times the default average lifetime of the particle measuerd in mm."
      "The actual lifetime of a particle instance is generated "
      "from this number by the <interface>Mass_generator</interface> "
      "object associated with the particle.",
      &ParticleData::theDefCTau, mm, ZERO, ZERO, Constants::MaxLength,
      false, true, Interface::lowerlim);
   interfaceDefCTau.setHasDefault(false);
 
   static Switch<ParticleData> interfaceColour
     ("Colour",
      "The colour quantum number of this particle type.",
      0, -1, false, false, &ParticleData::setColour, &ParticleData::getColour,
      &ParticleData::defColour);
   static SwitchOption interfaceColourUndefined
     (interfaceColour, "Undefined", "The coulur is undefined.", -1);
   static SwitchOption interfaceColourNeutral
     (interfaceColour, "Neutral", "This particle is colour neutral.", 0);
   static SwitchOption interfaceColour3
     (interfaceColour, "Triplet", "This particle is a colour triplet.", 3);
   static SwitchOption interfaceColour3bar
     (interfaceColour, "AntiTriplet",
      "This particle is a colour anti-triplet.", -3);
   static SwitchOption interfaceColour6
     (interfaceColour, "Sextet", "This particle is a colour sextet.", 6);
   static SwitchOption interfaceColour6bar
     (interfaceColour, "AntiSextet",
      "This particle is a colour anti-sextet.", -6);
   static SwitchOption interfaceColour8
     (interfaceColour, "Octet", "This particle is a colour octet.", 8);
   
   static Switch<ParticleData,PDT::Colour> interfaceDefColour
     ("DefaultColour",
      "The default colour quantum number of this particle type.",
      &ParticleData::theDefColour, PDT::Colour(-1), false, true);
   static SwitchOption interfaceDefColourUndefined
     (interfaceDefColour, "Undefined", "The coulur is undefined.", -1);
   static SwitchOption interfaceDefColourNeutral
     (interfaceDefColour, "Neutral", "This particle is colour neutral.", 0);
   static SwitchOption interfaceDefColour3
     (interfaceDefColour, "Triplet", "This particle is a colour triplet.", 3);
   static SwitchOption interfaceDefColour3bar
     (interfaceDefColour, "AntiTriplet",
      "This particle is a colour anti-triplet.", -3);
   static SwitchOption interfaceDefColour6
     (interfaceDefColour, "Sextet", "This particle is a colour sextet.", 6);
   static SwitchOption interfaceDefColour6bar
     (interfaceDefColour, "AntiSextet",
      "This particle is a colour anti-sextet.", -6);
   static SwitchOption interfaceDefColour8
     (interfaceDefColour, "Octet", "This particle is a colour octet.", 8);
   interfaceDefColour.setHasDefault(false);  
 
   static Parameter<ParticleData, int> interfaceCharge
     ("Charge",
      "The charge of this particle in units of e/3. "
      "See also the command interface <interface>SetCharge</interface>.",
      0, 0, -24, 24, false, false, true,
      &ParticleData::setCharge, &ParticleData::getCharge, 0, 0,
      &ParticleData::defCharge);
 
   static Parameter<ParticleData, PDT::Charge> interfaceDefCharge
     ("DefaultCharge",
      "The default charge of this particle in units of e/3. "
      "See also the command interface <interface>SetCharge</interface>.",
      &ParticleData::theDefCharge, PDT::Charge(0), PDT::Charge(-24),
      PDT::Charge(24), false, true, true);
   interfaceDefCharge.setHasDefault(false);
 
   static Command<ParticleData> interfaceSetCharge
     ("SetCharge",
      "Set the charge of this particle. The argument should be given as an "
      "interger giving three times the unit charge, or 'unknown', "
      "'charged', 'positive' or 'negative'", &ParticleData::ssetCharge);
 
   static Parameter<ParticleData, int> interfaceSpin
     ("Spin",
      "The spin quantim number of this particle on the form 2j+1.",
      0, 0, 0, 9, false, false, true,
      &ParticleData::setSpin, &ParticleData::getSpin, 0, 0,
      &ParticleData::defSpin);
 
   static Parameter<ParticleData, PDT::Spin> interfaceDefSpin
     ("DefaultSpin",
      "The default spin quantim number of this particle on the form 2j+1.",
      &ParticleData::theDefSpin, PDT::Spin(0), PDT::Spin(0), PDT::Spin(9),
      false, true, true);
   interfaceDefSpin.setHasDefault(false);
 
   static Switch<ParticleData> interfaceStable
     ("Stable",
      "Indicates if the particle is stable or not.",
      0, 0, false, false,
      &ParticleData::setStable, &ParticleData::getStable, 0);
   static SwitchOption interfaceStableYes
     (interfaceStable,
      "Stable",
      "This particle is stable",
      1);
   static SwitchOption interfaceStableNo
     (interfaceStable,
      "Unstable",
      "This particle is not stable",
      0);
   interfaceStable.setHasDefault(false);
 
   static Switch<ParticleData> interfaceVariableRatio
     ("VariableRatio",
      "Indicates if the branching ratios of the particle are allowed"
      " to vary for given Particle instances depending on the mass of the instance.",
      0, 0, false, false,
      &ParticleData::setVariableRatio, &ParticleData::getVariableRatio, 0);
   static SwitchOption interfaceVariableRatioYes
     (interfaceVariableRatio,
      "Yes",
      "The branching ratio varies.",
      1);
   static SwitchOption interfaceVariableRatioNo
     (interfaceVariableRatio,
      "No",
      "The branching ratio does not vary.",
      0);
 
   static Switch<ParticleData> interfaceSync
     ("Synchronized",
      "Indicates if the changes to this particle is propagated to "
      "its anti-partner or not. Note that setting this switch does not "
      "actually synchronize the properties with the anti-partner, "
      "it only assures that following changes are propagated. "
      "To sync the particle with its anti-particle, use the "
      "<interface>Synchronize</interface> command.",
      0, 1, false, false,
      &ParticleData::setSync, &ParticleData::getSync, 0);
   static SwitchOption interfaceSyncYes
     (interfaceSync,
      "Synchronized",
      "Changes to this particle will propagate to its "
      "anti-partner",
      1);
   static SwitchOption interfaceSyncNo
     (interfaceSync,
      "Not_synchronized",
      "Changes to this particle will propagate to its "
      "anti-partner",
      0);
   interfaceSync.setHasDefault(false);
 
   static Command<ParticleData> interfaceSynchronize
     ("Synchronize",
      "Synchronizes this particle so that all its properties "
      "correspond to those of its anti-partner",
      &ParticleData::doSync, false);
 
   static Reference<ParticleData,MassGenerator> interfaceMassGenerator
     ("Mass_generator",
      "An object derived from the ThePEG::MassGenerator"
      "class, which is able to generate a mass for a given "
      "particle instance",
      &ParticleData::theMassGenerator, false, false, true, true,
      &ParticleData::setMassGenerator, 0, 0);
 
   static Reference<ParticleData,WidthGenerator> interfaceWidthGenerator
     ("Width_generator",
      "An object derived from the ThePEG::WidthGenerator class, "
      "which is able to calculate the full and partial widths for"
      "this particle type and for a given instance of this "
      "particle type.",
      &ParticleData::theWidthGenerator, false, false, true, true,
      &ParticleData::setWidthGenerator, 0, 0);
 
   static RefVector<ParticleData,DecayMode> interfaceDecayModes
     ("DecayModes",
      "The list of decay modes defined for this particle type.",
      0, -1, false, false, false, false, 0,
      &ParticleData::insDecayModes, &ParticleData::delDecayModes,
      &ParticleData::getDecayModes);
 
 
   static Command<ParticleData> interfaceSelectDecayModes
     ("SelectDecayModes",
      "Only the decay modes which are given as (white-space separated) "
      "decay tags will be switched on, all others will be switched off. "
      "If no argument or 'none' is given, all decay modes are switched off. "
      "If the argument is 'all', all decay modes are switched on.",
      &ParticleData::doSelectDecayModes, false);
 
 
   static Command<ParticleData> interfacePrintDecayModes
     ("PrintDecayModes",
      "Print all decay modes of this particle.",
      &ParticleData::doPrintDecayModes, true);
 
 
 
   static Command<ParticleData> interfaceUnsetHardProcessMass
     ("UnsetHardProcessMass",
      "Unset a previously set hard process mass.",
      &ParticleData::doUnsetHardProcessMass, false);
 
   static Command<ParticleData> interfaceAdjustNominalMass
     ("AdjustNominalMass",
      "Unset a previously set hard process mass.",
      &ParticleData::doAdjustNominalMass, false);
 
   static Command<ParticleData> interfaceUnsetHardProcessWidth
     ("UnsetHardProcessWidth",
      "Unset a previously set hard process width.",
      &ParticleData::doUnsetHardProcessWidth, false);
 
   interfaceStable.rank(14);
   interfaceDecayModes.rank(13);
   interfaceMass.rank(12);
   interfaceWidth.rank(11);
   interfaceWidthCut.rank(10);
   interfaceCTau.rank(9);
   interfaceMassGenerator.rank(8);
   interfaceWidthGenerator.rank(7);
   interfaceWidthUpCut.rank(-0.1);
   interfaceWidthLoCut.rank(-0.1);
 
 
 }
 
 string ParticleData::doPrintDecayModes(string) {
   multimap<double,tDMPtr, std::greater<double> > sorted;
   for ( DecaySet::iterator it = decayModes().begin();
 	it != decayModes().end(); ++it )
     sorted.insert(make_pair((**it).brat(), *it));
   ostringstream os;
   for ( multimap<double,tDMPtr, 
 	  std::greater<double> >::iterator it = sorted.begin();
 	it != sorted.end(); ++it )
     os << it->second->tag()
        << (it->second->on()? " ": " (off) ")
        << it->first << endl;
   return os.str();
 }
 
 
 string ParticleData::doSelectDecayModes(string args) {
   DecaySet on;
   while ( !args.empty() ) {
     string arg = StringUtils::car(args);
     if ( arg == "all" ) {
       on = decayModes();
       break;
     }
     if ( arg == "none" ) {
       on.clear();
       break;
     }
     string name = arg;
     args = StringUtils::cdr(args);
     if ( arg.empty() ) continue;
     if ( arg[0] != '/' ) arg = fullName() + "/" + arg;
     DMPtr dm = Repository::GetPtr<DMPtr>(arg);
     if ( !dm ) return "Error: No decay mode with tag '" + name + "' exists.";
     on.insert(dm);
   }
   for ( DecaySet::iterator it = decayModes().begin();
 	it != decayModes().end(); ++it ) {
     if ( on.find(*it) != on.end() ) {
       (**it).switchOn();
       on.erase(*it);
     } else {
       (**it).switchOff();
     }
   }
   if ( !on.empty() )
     return "Error: decay mode '" + (**on.begin()).tag() + "'was not available.";
   return "";
 }
 
 void ParticleData::insDecayModes(DMPtr dm, int) {
   addDecayMode(dm);
 }
 
 void ParticleData::delDecayModes(int i) {
   vector<DMPtr> mv = getDecayModes();
   if ( i >= 0 && static_cast<unsigned int>(i) < mv.size() ) removeDecayMode(mv[i]);
 }
 
 vector<DMPtr> ParticleData::getDecayModes() const {
   return vector<DMPtr>(theDecayModes.begin(), theDecayModes.end());
 }
 
 ParticleChargeCommand::
 ParticleChargeCommand(const ParticleData & pd, string arg) {
   theMessage << "Cannot set the charge of particle '" << pd.name()
 	     << "' to '" << arg << "'.";
   severity(warning);
 }
 
 void ParticleData::doinit() {
   Interfaced::doinit();
   if( theMassGenerator )  theMassGenerator->init();
   if( theWidthGenerator ) theWidthGenerator->init();
 }
 
 void ParticleData::doinitrun() {
   Interfaced::doinitrun();
   if( theMassGenerator )  theMassGenerator->initrun();
   if( theWidthGenerator ) theWidthGenerator->initrun();
 }
 
 }
diff --git a/PDT/QuarksToHadronsDecayer.cc b/PDT/QuarksToHadronsDecayer.cc
--- a/PDT/QuarksToHadronsDecayer.cc
+++ b/PDT/QuarksToHadronsDecayer.cc
@@ -1,235 +1,235 @@
 // -*- C++ -*-
 //
 // QuarksToHadronsDecayer.cc is a part of ThePEG - Toolkit for HEP Event Generation
 // Copyright (C) 1999-2017 Leif Lonnblad
 //
 // ThePEG 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 QuarksToHadronsDecayer class.
 //
 
 #include "QuarksToHadronsDecayer.h"
 #include "ThePEG/Interface/ClassDocumentation.h"
 #include "ThePEG/Interface/Parameter.h"
 #include "ThePEG/Interface/Reference.h"
 #include "ThePEG/PDT/DecayMode.h"
 #include "ThePEG/PDT/StandardMatchers.h"
 #include "ThePEG/Repository/EventGenerator.h"
 #include "ThePEG/Utilities/SimplePhaseSpace.h"
 #include "ThePEG/Persistency/PersistentOStream.h"
 #include "ThePEG/Persistency/PersistentIStream.h"
 
 using namespace ThePEG;
 
 QuarksToHadronsDecayer::~QuarksToHadronsDecayer() {}
 
 IBPtr QuarksToHadronsDecayer::clone() const {
   return new_ptr(*this);
 }
 
 IBPtr QuarksToHadronsDecayer::fullclone() const {
   return new_ptr(*this);
 }
 
 bool QuarksToHadronsDecayer::accept(const DecayMode & dm) const {
   int col = 0;
   int acol = 0;
   if ( !dm.productMatchers().empty() ) {
     for ( MatcherMSet::const_iterator it = dm.productMatchers().begin();
 	  it != dm.productMatchers().end(); ++it ) {
       if ( typeid(**it) == typeid(MatchLightQuark) ) ++col;
       else if ( typeid(**it) == typeid(MatchLightAntiQuark) ) ++acol;
       else return false;
     }
     if ( col != 1 || col != acol ) return false;
   }
   if ( dm.orderedProducts().size() + col + acol < 2 ||
        !dm.cascadeProducts().empty() || dm.wildProductMatcher() ) return false;
   for ( int i = 0, N = dm.orderedProducts().size(); i < N; ++i ) {
     if ( DiquarkMatcher::Check(*dm.orderedProducts()[i]) ) {
       if ( i + 1 != N ) return false;
       if ( dm.orderedProducts()[i]->id() < 0 ) ++col;
       else ++acol;
     }
     if ( QuarkMatcher::Check(*dm.orderedProducts()[i]) ) {
       if ( dm.orderedProducts()[i]->id() > 0 ) ++col;
       else ++acol;
     }
   }
   if ( acol != col || col < 1 || col > 2 ) return false;
   return true;
 }
 
 PVector QuarksToHadronsDecayer::decay(const DecayMode & dm,
 				      const Particle & parent) const {
   PVector children;
   tcPDVector quarks;
   if ( !dm.productMatchers().empty() ) {
     tcPDPtr pd = getParticleData(flavourGenerator()->selectQuark());
     quarks.push_back(pd);
     quarks.push_back(pd->CC());
   }
   Energy summq = ZERO;
   Energy summp = ZERO;
   tPDVector prods = dm.orderedProducts();
   for ( int i = 0, N = prods.size(); i < N; ++i )
     if ( QuarkMatcher::Check(*prods[i]) || DiquarkMatcher::Check(*prods[i])) {
       quarks.push_back(prods[i]);
       summq += quarks.back()->mass();
     } else {
       children.push_back(prods[i]->produceParticle());
       summp += children.back()->mass();
     }
 
   Energy summh = ZERO;
   PVector hadrons;
 
   if ( !quarks.empty() ) do {
 
     hadrons = getHadrons(getN(parent.mass(), summq, quarks.size()), quarks);
 
     summh = ZERO;
     for ( int i = 0, N = hadrons.size(); i < N; ++i )
       summh += hadrons[i]->mass();
 
   } while ( hadrons.empty() || summp + summh >= parent.mass() );
 
   children.insert(children.end(), hadrons.begin(), hadrons.end());
 
   distribute(parent, children);
 
   finalBoost(parent, children);
   setScales(parent, children);
 
   return children;
 
 }
 
 int QuarksToHadronsDecayer::getN(Energy m0, Energy summq, int Nq) const {
   int Nh = fixedN();
   if ( Nh >= 2 ) return Nh;
 
   double c = c1()*log((m0 - summq)/c2()) + c3();
   if ( c < 0.0 ) return minN();
   while ( true ) {
     using namespace Constants;
     Nh = int(0.5 + double(Nq)/4.0 + c +
 	     sqrt(-2.0*c*log(max(1.0e-10, rnd())))*sin(2.0*pi*rnd()));
     if ( Nh >= minN() ) return Nh;
   }
 }
 
 PVector QuarksToHadronsDecayer::
 getHadrons(int Nh, tcPDVector quarks) const {
   PVector hadrons;
   Nh -= quarks.size()/2;
   while ( Nh-- > 0 ) {
     int i = irnd(quarks.size() - 1);
     tcPDPair hq = flavourGenerator()->alwaysGenerateHadron(quarks[i]);
     hadrons.push_back(hq.first->produceParticle());
     quarks[i] = hq.second;
   }
   if ( DiquarkMatcher::Check(*quarks[0]) && DiquarkMatcher::Check(*quarks[1]) )
     return PVector();
   tcPDPtr h = flavourGenerator()->alwaysGetHadron(quarks[0], quarks[1]);
   hadrons.push_back(h->produceParticle());
   if ( quarks.size() <= 2 ) return hadrons;
   if ( DiquarkMatcher::Check(*quarks[2]) && DiquarkMatcher::Check(*quarks[3]) )
     return PVector();
   h = flavourGenerator()->alwaysGetHadron(quarks[2], quarks[3]);
   hadrons.push_back(h->produceParticle());
   return hadrons;
 }
 
 void QuarksToHadronsDecayer::
 distribute(const Particle & parent, PVector & children) const {
   do {
     try {
       SimplePhaseSpace::CMSn(children, parent.mass());
     }
-    catch ( ImpossibleKinematics ) {
+    catch ( ImpossibleKinematics & e) {
       children.clear();
       return;
     }
   } while ( reweight(parent, children) < rnd() );
 }
 
 double QuarksToHadronsDecayer::
 reweight(const Particle &, const PVector &) const {
   return 1.0;
 }
 
 void QuarksToHadronsDecayer::persistentOutput(PersistentOStream & os) const {
   os << theFixedN << theMinN << theC1 << ounit(theC2,GeV) << theC3 << theFlavourGenerator;
 }
 
 void QuarksToHadronsDecayer::persistentInput(PersistentIStream & is, int) {
   is >> theFixedN >> theMinN >> theC1 >> iunit(theC2,GeV) >> theC3 >> theFlavourGenerator;
 }
 
 ClassDescription<QuarksToHadronsDecayer> QuarksToHadronsDecayer::initQuarksToHadronsDecayer;
 // Definition of the static class description member.
 
 void QuarksToHadronsDecayer::Init() {
 
   static ClassDocumentation<QuarksToHadronsDecayer> documentation
     ("This class decays particles to nq (2 or 4) quarks which then are "
      "decayes to hadrons according to phase space. The number of final "
      "hadrons can either be given by a fixed number or as a Gaussian "
      "multiplicity distribution centered around c+nq/4+c3 and a width "
      "sqrt(c), where c = c1 log((m - summ)/c2), m is the mass of the "
      "decaying particle, summ the sum of the quark masses and ci real "
      "parameters.");
 
   static Parameter<QuarksToHadronsDecayer,int> interfaceFixedN
     ("FixedN",
      "The fixed number of hadrons to be produced. If less than 2, the "
      "number is instead given by a gaussian multiplicity distribution.",
      &QuarksToHadronsDecayer::theFixedN, 0, 0, 10,
      true, false, true);
 
   static Parameter<QuarksToHadronsDecayer,int> interfaceMinN
     ("MinN",
      "The minimum hadrons to be produced.",
      &QuarksToHadronsDecayer::theMinN, 2, 2, 10,
      true, false, true);
 
   static Parameter<QuarksToHadronsDecayer,double> interfaceC1
     ("C1",
      "The c1 parameter of the gaussian multiplicity distribution centered "
      "around c1 log((m - summ)/c2) +c3.",
      &QuarksToHadronsDecayer::theC1, 4.5, 0.0, 10.0,
      true, false, true);
 
   static Parameter<QuarksToHadronsDecayer,Energy> interfaceC2
     ("C2",
      "The c2 parameter of the gaussian multiplicity distribution centered "
      "around c1 log((m - summ)/c2) +c3.",
      &QuarksToHadronsDecayer::theC2, GeV, 0.7*GeV, ZERO, 10.0*GeV,
      true, false, true);
 
   static Parameter<QuarksToHadronsDecayer,double> interfaceC3
     ("C3",
      "The c3 parameter of the gaussian multiplicity distribution centered "
      "around c1 log((m - summ)/c2) +c3.",
      &QuarksToHadronsDecayer::theC3, 0.0, 0.0, 10.0,
      true, false, true);
 
   static Reference<QuarksToHadronsDecayer,FlavourGenerator>
     interfaceFlavourGenerator
     ("FlavourGenerator",
      "The object in charge of generating hadrons spieces from given quark "
      "flavours.",
      &QuarksToHadronsDecayer::theFlavourGenerator,
      true, false, true, false, true);
 
   interfaceFixedN.rank(10);
   interfaceMinN.rank(9);
   interfaceFlavourGenerator.rank(8);
   interfaceMinN.setHasDefault(false);;
 
 }
 
diff --git a/Repository/BaseRepository.cc b/Repository/BaseRepository.cc
--- a/Repository/BaseRepository.cc
+++ b/Repository/BaseRepository.cc
@@ -1,978 +1,977 @@
 // -*- C++ -*-
 //
 // BaseRepository.cc is a part of ThePEG - Toolkit for HEP Event Generation
 // Copyright (C) 1999-2017 Leif Lonnblad
 //
 // ThePEG 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 BaseRepository class.
 //
 
 // macro is passed in from -D compile flag
 #ifndef THEPEG_PKGDATADIR
 #error Makefile.am needs to define THEPEG_PKGDATADIR
 #endif
 
 #include "BaseRepository.h"
 #include "ThePEG/Config/algorithm.h"
 #include "ThePEG/Interface/ClassDocumentation.h"
 #include "ThePEG/Interface/InterfaceBase.h"
 #include "ThePEG/Interface/Reference.h"
 #include "ThePEG/Interface/RefVector.h"
 #include "ThePEG/Interface/Command.h"
 #include "ThePEG/Utilities/ClassDescription.h"
 #include "ThePEG/Utilities/DescriptionList.h"
 #include "ThePEG/Utilities/HoldFlag.h"
 #include "ThePEG/Utilities/TypeInfo.h"
 #include "ThePEG/Utilities/DynamicLoader.h"
 #include "ThePEG/Utilities/StringUtils.h"
 #include "ThePEG/Utilities/Throw.h"
 #include "ThePEG/PDT/DecayMode.h"
 
 #ifdef ThePEG_TEMPLATES_IN_CC_FILE
 #include "BaseRepository.tcc"
 #endif
 
 using namespace ThePEG;
 
 ostream *& BaseRepository::coutp() {
   static ostream * theCout = &std::cout;
   return theCout;
 }
 
 ostream *& BaseRepository::cerrp() {
   static ostream * theCerr = &std::cerr;
   return theCerr;
 }
 
 ostream *& BaseRepository::clogp() {
   static ostream * theClog = &std::clog;
   return theClog;
 }
 
 bool & BaseRepository::updating() {
   static bool theBool = false;
   return theBool;
 }
 
 ObjectMap & BaseRepository::objects() {
   static ObjectMap theObjectMap;
   return theObjectMap;
 }
 
 ObjectSet & BaseRepository::allObjects() {
   static ObjectSet theObjectSet;
   return theObjectSet;
 }
 
 BaseRepository::TypeInterfaceMap & BaseRepository::interfaces() {
   static TypeInterfaceMap theInterfaceMap;
   return theInterfaceMap;
 }
 
 BaseRepository::TypeDocumentationMap & BaseRepository::documentations() {
   static TypeDocumentationMap theDocumentationMap;
   return theDocumentationMap;
 }
 
 BaseRepository::DirectorySet & BaseRepository::directories() {
-  static char root[1][2] = {"/"};
-  static DirectorySet theDirectories(root, root+1);
+  static DirectorySet theDirectories = {"/"};
   return theDirectories;
 }
 
 vector<string> & BaseRepository::globalLibraries() {
   static vector<string> theGlobalLibraries;
   return theGlobalLibraries;
 }
 
 stack<string> & BaseRepository::currentReadDirStack() {
   static stack<string> theCurrentReadDirStack;
   if ( theCurrentReadDirStack.empty() ) theCurrentReadDirStack.push("");
   return theCurrentReadDirStack;
 }
 
 vector<string> & BaseRepository::readDirs() {
   // macro is passed in from -D compile flag
   static vector<string>
     theReadDirs(1, THEPEG_PKGDATADIR);
   return theReadDirs;
 }
 
 const vector<string> & BaseRepository::listReadDirs() {
   return BaseRepository::readDirs();
 }
 
 void BaseRepository::prependReadDir(string dir) {
   readDirs().insert(readDirs().begin(), dir);
 }
 
 void BaseRepository::prependReadDir(const std::vector<std::string>& dirs) {
   readDirs().insert(readDirs().begin(), dirs.begin(), dirs.end());
 }
 
 void BaseRepository::appendReadDir(string dir) {
   readDirs().push_back(dir);
 }
 
 void BaseRepository::appendReadDir(const std::vector<std::string>& dirs) {
   readDirs().insert(readDirs().end(), dirs.begin(), dirs.end());
 }
 
 BaseRepository::StringVector & BaseRepository::directoryStack() {
   static StringVector theDirectoryStack(1, "/");
   return theDirectoryStack;
 }
 
 void BaseRepository::Register(const InterfaceBase & ib, const type_info & i) {
   const ClassDescriptionBase * db = DescriptionList::find(i);
   if ( db ) interfaces()[db].insert(&ib);
 }
 
 void BaseRepository::
 Register(const ClassDocumentationBase & cd, const type_info & i) {
   const ClassDescriptionBase * db = DescriptionList::find(i);
   if ( db ) documentations()[db] = &cd;
 }
 
 void BaseRepository::Register(IBPtr ip, string newName) {
   DirectoryAppend(newName);
   ip->name(newName);
   Register(ip);
 }
 
 void BaseRepository::Register(IBPtr ip) {
   if ( !ip || member(allObjects(), ip) ) return;
   if ( member(objects(), ip->fullName()) )
     throw RepoNameExistsException(ip->fullName());
   objects()[ip->fullName()] = ip;
   allObjects().insert(ip);
   ip->clear();
   ip->update();
   ip->touch();
 }
 
 void BaseRepository::DirectoryAppend(string & name) {
   if ( name == "." ) name = directoryStack().back();
   if ( name[0] != '/' ) name = directoryStack().back() + name;
 }  
 
 void BaseRepository::CreateDirectory(string name) {
   DirectoryAppend(name);
   if ( name[name.size()-1] != '/' ) name += "/";
   if ( member(directories(), name) ) return;
   directories().insert(name);
   name = name.substr(0, name.size() - 1);
   name = name.substr(0, name.rfind('/'));
   if ( name.size() ) CreateDirectory(name);
 }
 
 void BaseRepository::CheckObjectDirectory(string name) {
   if ( name[name.size() - 1] != '/' )
     name = name.substr(0, name.rfind('/') + 1);
   CheckDirectory(name);
 }
 
 void BaseRepository::CheckDirectory(string name) {
   DirectoryAppend(name);
   if ( name[name.size()-1] != '/' ) name += "/";  
   if ( member(directories(), name) ) return;
   throw RepositoryNoDirectory(name);
 }
 
 void BaseRepository::ChangeDirectory(string name) {
   DirectoryAppend(name);
   if ( name[name.size()-1] != '/' ) name += "/";  
   if ( member(directories(), name) ) {
     directoryStack().back() = name;
     return;
   }
   throw RepositoryNoDirectory(name);
 }
 
 void BaseRepository::PushDirectory(string name) {
   DirectoryAppend(name);
   if ( name[name.size()-1] != '/' ) name += "/";  
   if ( member(directories(), name) ) {
     directoryStack().push_back(name);
     return;
   }
   throw RepositoryNoDirectory(name);
 }
 
 void BaseRepository::PopDirectory() {
   if ( directoryStack().size() > 1 ) directoryStack().pop_back();
 }
 
 IBPtr BaseRepository::GetPointer(string name) {
   ObjectMap::iterator it = objects().find(name);
   return it == objects().end()? IBPtr(): it->second;
 }
 
 IVector BaseRepository::SearchDirectory(string name, string className) {
   IVector ret;
   DirectoryAppend(name);
   const ClassDescriptionBase * cdb = 0;
   if ( className.size() ) {
     cdb = DescriptionList::find(className);
     if ( !cdb ) return ret;
   }
   if ( name[name.size()-1] != '/' ) name += "/";
   string::size_type size = name.size();
   for ( ObjectMap::const_iterator i = objects().begin();
 	i != objects().end(); ++i ) {
     if ( cdb && !DescriptionList::find(typeid(*(i->second)))->isA(*cdb) )
       continue;
     if ( i->first.substr(0, size) == name ) ret.push_back(i->second);
   }
   return ret;
 }
 
 IVector BaseRepository::GetObjectsReferringTo(IBPtr obj) {
   IVector ret;
   for ( ObjectMap::const_iterator i = objects().begin();
 	i != objects().end(); ++i ) {
     if ( obj == i->second ) continue;
     IVector ov = DirectReferences(i->second);
     if ( member(ov, obj) ) ret.push_back(i->second);
   }
   return ret;
 }
 
 IVector BaseRepository::DirectReferences(IBPtr obj) {
   IVector ov = obj->getReferences();
   InterfaceMap interfaceMap = getInterfaces(typeid(*obj));
   for ( InterfaceMap::iterator iit = interfaceMap.begin();
 	iit != interfaceMap.end(); ++iit ) {
     IVector ovi = iit->second->getReferences(*obj);
     ov.insert(ov.end(), ovi.begin(), ovi.end());
   }
   return ov;
 }
 
 void BaseRepository::
 addReferences(tIBPtr obj, ObjectSet & refs) {
   if ( !obj ) return;
   refs.insert(obj);
   IVector ov = obj->getReferences();
   for ( IVector::const_iterator it = ov.begin(); it != ov.end(); ++it )
     if ( !member(refs, *it) ) addReferences(*it, refs);
   InterfaceMap interfaceMap = getInterfaces(typeid(*obj));
   for ( InterfaceMap::iterator iit = interfaceMap.begin();
 	iit != interfaceMap.end(); ++iit ) {
     IVector ov = iit->second->getReferences(*obj);
     for ( IVector::const_iterator it = ov.begin(); it != ov.end(); ++it )
       if ( !member(refs, *it) ) addReferences(*it, refs);
   }
 }
 
 void BaseRepository::
 addInterfaces(const ClassDescriptionBase & db,
 	      InterfaceMap & interfaceMap, bool all) {
   for ( ClassDescriptionBase::DescriptionVector::const_iterator it =
 	  db.descriptions().begin(); it != db.descriptions().end(); ++it )
     if ( *it ) addInterfaces(**it, interfaceMap, all);
   TypeInterfaceMap::const_iterator cit = interfaces().find(&db);
   if ( cit == interfaces().end() ) return;
   for ( InterfaceSet::const_iterator iit = (cit->second).begin();
 	iit != (cit->second).end(); ++iit ) {
     string n = (**iit).name();
     while ( all && member(interfaceMap, n) ) n = "+" + n;
     interfaceMap[n] = *iit;
   }
 }
 
 InterfaceMap BaseRepository::getInterfaces(const type_info & ti, bool all) {
   InterfaceMap interfaceMap;
   const ClassDescriptionBase * db = DescriptionList::find(ti);
   if ( !db ) return interfaceMap;
   addInterfaces(*db, interfaceMap, all);
   return interfaceMap;
 }
 
 void BaseRepository::
 rebind(InterfacedBase & i, const TranslationMap & trans,
        const IVector & defaults) {
   InterfaceMap interfaceMap = getInterfaces(typeid(i), true);
   for ( InterfaceMap::iterator iit = interfaceMap.begin();
 	iit != interfaceMap.end(); ++iit )
     iit->second->rebind(i, trans, defaults);
   i.rebind(trans);
 }
 
 void BaseRepository::update() {
   for_each(allObjects(), mem_fun(&InterfacedBase::update));
   clearAll(allObjects());
 }
 
 template <typename Set1, typename Set2>
 bool overlap(const Set1 & s1, const Set2 & s2) {
   typename Set1::const_iterator i1 = s1.begin();
   typename Set2::const_iterator i2 = s2.begin();
   while ( i1 != s1.end() && i2 != s2.end() ) {
     if ( *i1 == *i2 ) return true;
     if ( *i1 < *i2 ) {
       i1 = s1.lower_bound(*i2);
       if ( *i1 == *i2 ) return true;
       ++i1;
     } else {
       i2 = s2.lower_bound(*i1);
       if ( *i1 == *i2 ) return true;
       ++i2;
     }
   }
   return false;
 }
 
 void BaseRepository::remove(tIBPtr ip) {
   ObjectMap::iterator it = objects().find(ip->fullName());
   if ( it == objects().end() || ip != it->second ) return;
   objects().erase(it);
   allObjects().erase(ip);
 }
 
 string BaseRepository::remove(const ObjectSet & rmset) {
   ObjectSet refset;
   for ( ObjectSet::const_iterator oi = rmset.begin();
 	oi != rmset.end(); ++oi ) {
     IVector ov = GetObjectsReferringTo(*oi);
     refset.insert(ov.begin(), ov.end());
   }
   for ( ObjectSet::iterator oi = rmset.begin(); oi != rmset.end(); ++oi )
     refset.erase(*oi);
   if ( refset.empty() ) {
     for ( ObjectSet::iterator oi = rmset.begin(); oi != rmset.end(); ++oi )
       remove(*oi);
     return "";
   }
   string ret = "Error: cannot remove the objects because the following "
     "objects refers to some of them:\n";
   for ( ObjectSet::iterator oi = refset.begin(); oi != refset.end(); ++oi )
     ret += (**oi).fullName() + "\n";
   return ret;
 }
    
 void BaseRepository::rename(tIBPtr ip, string newName) {
   ObjectSet::iterator it = allObjects().find(ip);
   if ( it == allObjects().end() ) {
     Register(ip, newName);
     return;
   }
   ObjectMap::iterator mit = objects().find(ip->fullName());
   if ( mit == objects().end() || mit->second != ip )
     throw RepoNameException(ip->fullName());
   
   objects().erase(mit);
   ip->name(newName);
   while ( member(objects(), ip->fullName()) ) ip->name(ip->fullName() + "#");
   objects()[ip->fullName()] = ip;
 }
 
 const InterfaceBase * BaseRepository::FindInterface(IBPtr ip, string name) {
   InterfaceMap imap = getInterfaces(typeid(*ip), false);
   InterfaceMap::iterator it = imap.find(name);
   return it == imap.end()? 0: it->second;
 }
 
 const ClassDocumentationBase * BaseRepository::getDocumentation(tcIBPtr ip) {
   TypeDocumentationMap::const_iterator cdoc =
     documentations().find(DescriptionList::find(typeid(*ip)));
   return cdoc != documentations().end()? cdoc->second: 0;
 }
 
 string BaseRepository::getModelDescription(tcIBPtr ip) {
   const ClassDocumentationBase *  cd = getDocumentation(ip);
   return cd? cd->modelDescription(): string("");
 }
 
 string BaseRepository::getModelReferences(tcIBPtr ip) {
   const ClassDocumentationBase *  cd = getDocumentation(ip);
   return cd? cd->modelReferences(): string("");
 }
 
 IBPtr BaseRepository::TraceObject(string path) {
   DirectoryAppend(path);
   string::size_type colon = path.find(':');
   IBPtr ip = GetPointer(path.substr(0, colon));
   if ( !ip ) {
     // Do special check if this is a decay mode.
     string name = path.substr(0, colon);
     string::size_type slash = name.rfind('/');
     if ( slash != string::npos ) name = name.substr(slash + 1);
     if ( name.find("->") != string::npos && name[name.length() - 1] == ';' ) {
       vector<DMPtr> save;
       DMPtr dm = DecayMode::constructDecayMode(name, &save);
       if ( dm )	ip = dynamic_ptr_cast<DMPtr>(GetPointer(path.substr(0, slash + 1)
 							+ dm->tag()));
       if ( ip ) Throw<Exception>()
 		  << "Warning: rewriting DecayMode name '"
 		  << path.substr(0, colon).substr(slash + 1) << "' to '"
 		  << ip->name() << Exception::warning;
     }
   }
   while ( colon != string::npos ) {
   if ( !ip ) throw RepositoryNotFound(path);
     path = path.substr(colon+1);
     colon = path.find(':');
     string::size_type bra = path.find('[');
     const InterfaceBase * ifb =
       FindInterface(ip, path.substr(0, min(colon, bra)));
     const ReferenceBase * rb = dynamic_cast<const ReferenceBase *>(ifb);
     if ( rb ) {
       ip = rb->get(*ip);
       continue;
     }
     const RefVectorBase * rvb = dynamic_cast<const RefVectorBase *>(ifb);
     if ( rvb ) {
       unsigned int place = 0;
       if ( bra < colon ) {
 	string::size_type ket = path.find(']');
 	place = atoi(path.substr(bra + 1,ket - bra - 1).c_str());
       }
       IVector iv = rvb->get(*ip);
       if ( place >= iv.size() ) throw RepositoryNotFound(path);
       ip = iv[place];
       continue;
     }
     const CommandBase * cb = dynamic_cast<const CommandBase *>(ifb);
     if ( cb ) {
       string::size_type ket = path.find(']');
       string newobj = cb->cmd(*ip, path.substr(bra + 1,ket - bra - 1));
       ip = GetPointer(newobj);
       continue;
     } 
     throw RepositoryNotFound(path);
   }
   if ( !ip ) throw RepositoryNotFound(path);
   return ip;
 }
 
 IBPtr BaseRepository::getObjectFromNoun(string noun) {
   string::size_type colon = noun.rfind(':');
   return TraceObject(noun.substr(0, colon));
 }
 
 string BaseRepository::getInterfaceFromNoun(string noun) {
   string::size_type colon = noun.rfind(':');
   string interface = noun.substr(colon+1);
   string::size_type bra = interface.find('[');
   if ( bra != string::npos ) return interface.substr(0, bra);
   else return interface;  
 }
 
 string BaseRepository::getPosArgFromNoun(string noun) {
   string::size_type colon = noun.rfind(':');
   string interface = noun.substr(colon+1);
   string::size_type bra = interface.find('[');
   if ( bra != string::npos ) {
     string::size_type ket = interface.find(']');
     return interface.substr(bra + 1,ket - bra - 1);
   }
   return "";
 }
 
 string BaseRepository::
 GetInterfacedBaseClasses(const ClassDescriptionBase * cdb) {
   if ( !cdb || cdb->name() == "ThePEG::Interfaced" ||
        cdb->name() == "ThePEG::InterfacedBase" ) return "";
   string ret = cdb->name() + "\n";
   for ( int i = 0, N = cdb->descriptions().size(); i < N; ++i )
     ret += GetInterfacedBaseClasses(cdb->descriptions()[i]);
   return ret;
 }
 
 struct InterfaceOrder {
   bool operator()(const InterfaceBase * x, const InterfaceBase * y) const {
     return x->rank() > y->rank() ||
       ( x->rank() == y->rank() && x->name() < y->name() );
   }
 };
 
 void BaseRepository::readSetup(tIBPtr ip, istream & is) {
   ip->setup(is);
 }
 
 string BaseRepository::exec(string command, ostream &) {
   string verb = StringUtils::car(command);
   command = StringUtils::cdr(command);
   if ( verb.empty() || verb[0] == '#' ) return "";
   try {
     if ( verb == "DISABLEREADONLY" ) {
       InterfaceBase::NoReadOnly = true;
       return "";
     }
     if ( verb == "ENABLEREADONLY" ) {
       InterfaceBase::NoReadOnly = false;
       return "";
     }
     if ( verb == "cd" || verb == "pushd" || verb == "mkdir") {
       string dir = StringUtils::car(command);
       if ( verb == "cd" )
 	ChangeDirectory(dir);
       else if ( verb == "pushd" )
 	PushDirectory(dir);
       else
 	CreateDirectory(dir);
       return "";
     }
     if ( verb == "popd" ) {
       PopDirectory();
       return "";
     }
     if ( verb == "pwd" ) return directoryStack().back();
     if ( verb == "dirs" ) {
       string ret;
       for ( StringVector::reverse_iterator it = directoryStack().rbegin();
 	    it != directoryStack().rend(); ++it ) ret += *it;
       return ret;
     }
     if ( verb == "cp" || verb == "mv" ) {
       string oldname = StringUtils::car(command);
       DirectoryAppend(oldname);
       IBPtr obj = GetPointer(oldname);
       if ( !obj ) return "Error: No object named '" + oldname + "' available.";
       command = StringUtils::cdr(command);
       string newname = StringUtils::car(command);
       DirectoryAppend(newname);
       if ( newname[newname.size() - 1] == '/' ) newname += obj->name();
       if ( verb == "cp" ) obj = obj->fullclone();
       rename(obj, newname);
       return "";
     }
     if ( verb == "check" ) {
       string name = StringUtils::car(command);
       if ( directories().find(name) != directories().end() ) return name;
       if ( objects().find(name) != objects().end() ) return name;
       return "Not found";
     }
     if ( verb == "ls" ) {
       string className;
       string dir = StringUtils::car(command);
       if ( dir.size() ) {
 	PushDirectory(dir);
 	command = StringUtils::cdr(command);
 	className = StringUtils::car(command);
       }
       string ret;
       string thisdir = directoryStack().back();
       for ( DirectorySet::iterator it = directories().begin();
 	    it != directories().end(); ++it ) {
 	string d = *it;
 	if ( d.size() <= thisdir.size() ) continue;
 	string d0 = d.substr(0, thisdir.size());
 	string d1 = d.substr(thisdir.size());
 	if ( d0 == thisdir && d1.find('/') == d1.size() - 1 ) {
 	  if ( className.size() && SearchDirectory(d, className).empty() )
 	    continue;
 	  ret += (dir.size()? d: d1) + "\n";
 	}
       }
       for ( ObjectMap::iterator it = objects().begin();
 	    it != objects().end(); ++it ) {
 	if ( className.size() ) {
 	  const ClassDescriptionBase * cdb = DescriptionList::find(className);
 	  if ( cdb &&
 	       !DescriptionList::find(typeid(*(it->second)))->isA(*cdb) )
 	    continue;
 	}
 	if ( thisdir + it->second->name() == it->first )
 	  ret += (dir.size()? it->first: it->second->name()) + '\n';
       }
       if ( dir.size() ) PopDirectory();
       return ret;
     }
     if ( verb == "library" ) {
       string library = StringUtils::car(command);
       if ( library.empty() ) return "Error: No library specified.";
       if ( !DynamicLoader::load(library) )
 	return "Error: Could not load library " + library +
 	  "\n - " + DynamicLoader::lastErrorMessage;
       return "";
     }
 
     if ( verb == "globallibrary" ) {
       string library = StringUtils::car(command);
       if ( library.empty() ) return "Error: No library specified.";
       if ( !DynamicLoader::load(library) )
 	return "Error: Could not load library " + library +
 	  "\n - " + DynamicLoader::lastErrorMessage;
       globalLibraries().push_back(library);
       return "";
     }
 
     if ( verb == "rmgloballibrary" ) {
       string library = StringUtils::car(command);
       if ( library.empty() ) return "Error: No library specified.";
       vector<string>::iterator it;
       while ( (it = find(globalLibraries(), library)) != globalLibraries().end() )
 	globalLibraries().erase(it);
       return "";
     }
 
     if ( verb == "appendpath" ) {
       string path = StringUtils::car(command);
       if ( !path.empty() ) DynamicLoader::appendPath(path);
       return "";
     }
 
     if ( verb == "lspaths" ) {
       string paths;
       for ( int i = 0, N = DynamicLoader::allPaths().size(); i < N; ++i )
 	paths += DynamicLoader::allPaths()[i] + "\n";
       return paths;
     }
 
     if ( verb == "prependpath" ) {
       string path = StringUtils::car(command);
       if ( !path.empty() ) DynamicLoader::prependPath(path);
       return "";
     }
 
     if ( verb == "create" ) {
       string className = StringUtils::car(command);
       command = StringUtils::cdr(command);
       string name = StringUtils::car(command);
       const ClassDescriptionBase * db = DescriptionList::find(className);
       command = StringUtils::cdr(command);
       while ( !db && command.length() ) {
 	string library = StringUtils::car(command);
 	command = StringUtils::cdr(command);
 	DynamicLoader::load(library);
 	db = DescriptionList::find(className);
       }
       if ( !db )  {
 	string msg = "Error: " + className + ": No such class found.";
 	if ( !DynamicLoader::lastErrorMessage.empty() )
 	  msg += "\nerror message from dynamic loader:\n" +
 	    DynamicLoader::lastErrorMessage;
 	return msg;
       }
       IBPtr obj = dynamic_ptr_cast<IBPtr>(db->create());
       if ( !obj ) return "Error: Could not create object of class "+className;
       if ( name.empty() ) return "Error: No name specified.";
       Register(obj, name);
       return "";
     }
     if ( verb == "setup" ) {
       string name = StringUtils::car(command);
       DirectoryAppend(name);
       IBPtr obj = GetPointer(name);
       if ( !obj ) return "Error: Could not find object named " + name;
       istringstream is(StringUtils::cdr(command));
       readSetup(obj, is);
       return "";
     }
     if ( verb == "rm" ) {
       ObjectSet rmset;
       while ( !command.empty() ) {
 	string name = StringUtils::car(command);
 	DirectoryAppend(name);
 	IBPtr obj = GetPointer(name);
 	if ( !obj ) return "Error: Could not find object named " + name;
 	rmset.insert(obj);
 	command = StringUtils::cdr(command);
       }
       return remove(rmset);
     }
     if ( verb == "rmdir" || verb == "rrmdir" ) {
       string dir = StringUtils::car(command);
       DirectoryAppend(dir);
       if ( dir[dir.size() - 1] != '/' ) dir += '/';
       if ( !member(directories(), dir) )
 	return verb == "rmdir"? "Error: No such directory.": "";
       IVector ov = SearchDirectory(dir);
       if ( ov.size() && verb == "rmdir" )
 	return "Error: Cannot remove a non-empty directory. "
 	  "(Use rrmdir do remove all object and subdirectories.)";
       ObjectSet rmset(ov.begin(), ov.end());
       string ret = remove(rmset);
       if ( !ret.empty() ) return ret;
       StringVector dirs(directories().begin(), directories().end());
       for ( int i = 0, N = dirs.size(); i < N; ++ i )
 	if ( dirs[i].substr(0, dir.size()) == dir )
 	  directories().erase(dirs[i]);
       for ( int i = 0, N = directoryStack().size(); i < N; ++i )
 	if ( directoryStack()[i].substr(0, dir.size()) == dir )
 	  directoryStack()[i] = '/';
       return "";
     }
     if ( verb == "rcp" ) {
       string name = StringUtils::car(command);
       DirectoryAppend(name);
       string newName = StringUtils::car(StringUtils::cdr(command));
       if ( newName.empty() )
 	return "Error: No destination directory specified.";
       DirectoryAppend(newName);
       CreateDirectory(newName);
       if ( newName[newName.size() - 1]  != '/' ) newName += '/';
       IBPtr obj = GetPointer(name);
       if ( name[name.size() - 1]  != '/' ) name += '/';
       IVector ov = SearchDirectory(name);
       ov.push_back(obj);
       if ( ov.empty() ) return "Error: No such object or directory.";
       ObjectSet toclone;
       for ( IVector::iterator i = ov.begin(); i != ov.end(); ++i ) {
 	toclone.insert(*i);
 	addReferences(*i, toclone);
       }
       for ( ObjectSet::iterator i = toclone.begin(); i != toclone.end(); ++i )
 	Register((**i).clone(), newName + (**i).name());
       return "";
     }
     if ( verb == "rebind" ) {
       // For all objects in the repository, replace any references to
       // the first object given with references to the second
       // object. The two objects will change names
      IBPtr ip1 = TraceObject(StringUtils::car(command));
      string newname = StringUtils::car(StringUtils::cdr(command));
      DirectoryAppend(newname);
      IBPtr ip2 = GetPointer(newname);
      if ( !ip2 ) {
        ip2 = ip1->fullclone();
        rename(ip2, newname);
      }
      TranslationMap trans;
      trans[ip1] = ip2;
      IVector objs = GetObjectsReferringTo(ip1);
      for ( int i = 0, N = objs.size(); i < N; ++i ) rebind(*objs[i], trans, IVector());
     }
     if ( verb == "doxygendump" ) {
       string spacename = StringUtils::car(command);
       command = StringUtils::cdr(command);
       string filename = StringUtils::car(command);
       ofstream os(filename.c_str());
       for ( TypeDocumentationMap::const_iterator it = documentations().begin();
 	    it != documentations().end(); ++it ) {
 	const ClassDescriptionBase & db = *(it->first);
 	string classname = db.name();
 	if ( classname.substr(0, spacename.length()) != spacename ) continue;
 	string briefname = classname.substr(spacename.length());
 	os << "/** \\page " << briefname << "Interfaces "
 	   << "Interfaces defined for the " << classname << " class.\n\n"
 	   << "\\par Brief class description:\n";
 	string doc = it->second->documentation();
 	if ( doc.substr(0,25) == "There is no documentation" )
 	  os << "See " << classname << "\n\n";
 	else
 	  os << doc << "<br>See also " << classname << "\n\n";
 	TypeInterfaceMap::const_iterator isit = interfaces().find(it->first);
 	if ( isit == interfaces().end() || isit->second.empty() ) {
 	  os << "There are no interfaces declared for this class.\n\n";
 	} else {
 	  const InterfaceSet & ints = isit->second;
 	  for ( InterfaceSet::const_iterator iit = ints.begin();
 		iit != ints.end(); ++iit )
 	    (**iit).doxygenDescription(os);
 	}
 	string baserefs = "";
 	int nbases = 0;
 	for ( int ib = 0, N = db.descriptions().size(); ib < N; ++ib ) {
 	  if ( documentations().find(db.descriptions()[ib]) ==
 	       documentations().end() ) continue;
 	  const ClassDescriptionBase & bdb = *db.descriptions()[ib];
 	  if ( nbases ) baserefs += " and ";
 	  string briefname = bdb.name().substr(bdb.name().rfind("::") + 2);
 	  baserefs += "\\ref " + briefname +
 	    "Interfaces \"" + bdb.name() + "\"";
 	  ++nbases;
 	}
 	if ( nbases == 1 )
 	  os << "<hr>There may be interfaces inherited from the "
 	     << baserefs << " class.";
 	else if ( nbases > 1 ) 
 	  os << "<hr>There may be interfaces inherited from the "
 	     << "following classes: " << baserefs << ".";
 	os << "\n\n*/\n\n";
       }
       return "";
     }
     if ( verb == "mset" || verb == "msetdef" || verb == "minsert" ||
 	 verb == "mdo" || verb == "mget" || verb == "mdef" || verb == "mmin" ||
 	 verb == "mmax" || verb == "merase" || verb == "msend"  ) {
       if ( verb == "msend" ) verb = "mdo";
       string dir = StringUtils::car(command);
       command = StringUtils::cdr(command);
       string className = StringUtils::car(command);
       command = StringUtils::cdr(command);
       string interface = StringUtils::car(command);
       string arguments = StringUtils::cdr(command);
       string::size_type bra = interface.find('[');
       if ( bra != string::npos ) {
 	string::size_type ket = interface.find(']');
 	arguments = interface.substr(bra + 1,ket - bra - 1) + " " + arguments;
 	interface = interface.substr(0, bra);
       }
       IVector ov = SearchDirectory(dir, className);
       if ( ov.empty() ) return "Error: no matching objects found.";
       string ret;
       verb = verb.substr(1);
       for ( IVector::size_type i = 0; i < ov.size(); ++i ) {
 	const InterfaceBase * ifb = FindInterface(ov[i], interface);
 	if ( !ifb ) continue;
 	string mess = ifb->exec(*ov[i], verb, arguments);
 	if ( !mess.empty() ) ret += ov[i]->fullName() + ": " + mess + "\n";
       }
       return ret.substr(0, ret.size() - 1);
     }
     if ( verb == "set" || verb == "setdef" || verb == "insert" ||
 	 verb == "do" || verb == "get" || verb == "def" || verb == "min" ||
 	 verb == "max" || verb == "describe" || verb == "fulldescribe" ||
 	 verb == "erase" || verb == "clear" || verb == "send" || verb == "newdef" ) {
       if ( verb == "send" ) verb = "do";
       if ( verb == "newdef" && !InterfaceBase::NoReadOnly )
 	return "Error: The default value of an interface is a read-only "
 	  "entity. Use the command 'DISABLEREADONLY' to override.";
       string noun = StringUtils::car(command);
       string arguments = getPosArgFromNoun(noun) + " "
 	+ StringUtils::cdr(command);
       IBPtr ip = getObjectFromNoun(noun);
       const InterfaceBase * ifb = FindInterface(ip, getInterfaceFromNoun(noun));
       if ( !ifb && verb != "describe" && verb != "fulldescribe" ) {
 	string ret = "Error: The interface '" + noun + "' was not found.\n";
 	ret += "Valid interfaces:\n";
 	InterfaceMap imap = getInterfaces(typeid(*ip));
 	for ( InterfaceMap::iterator it = imap.begin(); it != imap.end(); ++it )
 	  ret += "* " + it->second->name() + "\n";
 	return ret;
       }
       if ( verb == "describe" ) {
 	if ( ifb ) return ifb->description();
 	const ClassDescriptionBase * cd = DescriptionList::find(typeid(*ip));
 	string ret = "Object '" + ip->name() + "' of class '" +
 	  cd->name() + "':\n";
 	TypeDocumentationMap::const_iterator cdoc = documentations().find(cd);
 	if ( cdoc != documentations().end() )
 	  ret += cdoc->second->documentation() + "\n";
 	ret +="Interfaces:\n";
 	InterfaceMap imap = getInterfaces(typeid(*ip));
 	for ( InterfaceMap::iterator it = imap.begin(); it != imap.end(); ++it )
 	  ret += "* " + it->second->name() + "\n";
 	return ret;
       } else if ( verb == "fulldescribe" ) {
 	if ( ifb ) return ifb->fullDescription(*ip);
 	ostringstream ret;
 	const ClassDescriptionBase * cd = DescriptionList::find(typeid(*ip));
 	TypeDocumentationMap::const_iterator cdoc = documentations().find(cd);
 	ret << ip->fullName() << endl << cd->name() << endl;
 	if ( cdoc != documentations().end() )
 	  ret << cdoc->second->documentation() << endl;
 	ret << "Interfaces:" << endl;
 	InterfaceMap imap = getInterfaces(typeid(*ip));
 	typedef set<const InterfaceBase *, InterfaceOrder> InterfaceSet;
 	InterfaceSet iset;
 	for ( InterfaceMap::iterator it = imap.begin(); it != imap.end(); ++it )
 	  iset.insert(it->second);
 	double rank = 1.0;
 	for ( InterfaceSet::iterator it = iset.begin();
 	      it != iset.end(); ++it ) {
 	  if ( rank >= 0.0 && (**it).rank() < 0.0 ) ret << "0" << endl;
 	  rank = (**it).rank();
 	  ret << (**it).type() << " " << (**it).name() << endl;
 	}
 	return ret.str();
       }
       else
 	return ifb->exec(*ip, verb, arguments);
     }
     if ( verb == "baseclasses" ) {
       string className = StringUtils::car(command);
       const ClassDescriptionBase * cdb = 0;
       if ( className.size() ) {
 	cdb = DescriptionList::find(className);
 	if ( !cdb ) return "Error: no class '" + className + "' found.";
       }
       return GetInterfacedBaseClasses(cdb);
     }
     if ( verb == "describeclass" ) {
       string className = StringUtils::car(command);
       const ClassDescriptionBase * cdb = 0;
       if ( className.size() ) {
 	cdb = DescriptionList::find(className);
 	if ( !cdb ) return "Error: no class '" + className + "' found.";
       }
       TypeDocumentationMap::const_iterator cdoc = documentations().find(cdb);
       if ( cdoc != documentations().end() )
 	return cdoc->second->documentation() + "\n";
       else
 	return "";
     }
     if ( verb == "lsclass" ) {
       string className = StringUtils::car(command);
       const ClassDescriptionBase * cdb = 0;
       if ( className.size() ) {
 	cdb = DescriptionList::find(className);
 	if ( !cdb ) return "Error: no class '" + className + "' found.";
       }
       vector<const ClassDescriptionBase *> classes;
       if ( cdb && !cdb->abstract() ) classes.push_back(cdb);
       for ( DescriptionList::DescriptionMap::const_iterator
 	      it = DescriptionList::all().begin();
 	    it != DescriptionList::all().end(); ++it ) {
 	if ( it->second == cdb || it->second->abstract() ) continue;
 	if ( cdb && !it->second->isA(*cdb) ) continue;
 	classes.push_back(it->second);
       }
       if ( classes.empty() )  return "Error: no classes found.";
       string ret;
       for ( int i = 0, N = classes.size(); i < N; ++i ) 
 	ret += classes[i]->name() + "\n";
       return ret;
     }
     
   }
   catch (const Exception & e) {
     e.handle();
     return "Error: " + e.message();
   }
   return "Error: Unrecognized command '" + verb + "'.";
 }
 
 BadClassClone::BadClassClone(const InterfacedBase & o) {
   theMessage << "Could not clone the object '" << o.name()
 	     << "' of class '" << TypeInfo::name(o)
 	     << "' because the class does not"
 	     << " implement a working 'clone' method.";
   severity(abortnow);
 }
 
 BadClone::BadClone(const InterfacedBase & o) {
   theMessage << "Could not clone the object '" << o.name()
 	     << "' of class '" << TypeInfo::name(o)
 	     << "' because the clone method threw an unknown exception.";
   severity(abortnow);
 }
 
 RepoNameException::RepoNameException(string name) {
   theMessage << "The object '" << name << "' is present in the Repository but "
 	     << "under a different name. This means that the name of the "
 	     << "object has been illegally changed outside of the Repository.";
   severity(abortnow);
 }
 
 RepoNameExistsException::RepoNameExistsException(string name) {
   theMessage
     << "The object '" << name
     << "' was not created as another object with that name already exists.";
   severity(warning);
 }
 
 RepositoryNoDirectory::RepositoryNoDirectory(string name) {
   theMessage << "The directory '" << name << "' does not exist.";
   severity(warning);
 }
 
 RepositoryNotFound::RepositoryNotFound(string name) {
   theMessage << "There was no object named '" << name << "' in the repository.";
   severity(warning);
 }
 
 RepositoryClassMisMatch::
 RepositoryClassMisMatch(const InterfacedBase & o, string name) {
   theMessage << "The requested object '" << o.fullName() << "' was not of the "
 	     << "specified type (" << name << ").";
   severity(warning);
 }
 
diff --git a/Repository/EventGenerator.cc b/Repository/EventGenerator.cc
--- a/Repository/EventGenerator.cc
+++ b/Repository/EventGenerator.cc
@@ -1,1414 +1,1415 @@
 // -*- C++ -*-
 //
 // EventGenerator.cc is a part of ThePEG - Toolkit for HEP Event Generation
 // Copyright (C) 1999-2017 Leif Lonnblad
 //
 // ThePEG 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 EventGenerator class.
 //
 
 #include "EventGenerator.h"
 #include "EventGenerator.xh"
 #include "ThePEG/Handlers/EventHandler.h"
 #include "Repository.h"
 #include "ThePEG/Utilities/HoldFlag.h"
 #include "ThePEG/Utilities/Debug.h"
 #include "ThePEG/Utilities/DebugItem.h"
 #include "ThePEG/Interface/Interfaced.h"
 #include "ThePEG/Interface/Reference.h"
 #include "ThePEG/Interface/RefVector.h"
 #include "ThePEG/Interface/Parameter.h"
 #include "ThePEG/Interface/Switch.h"
 #include "ThePEG/Interface/Command.h"
 #include "ThePEG/Interface/ClassDocumentation.h"
 #include "ThePEG/PDT/ParticleData.h"
 #include "ThePEG/PDT/MatcherBase.h"
 #include "ThePEG/PDT/DecayMode.h"
 #include "ThePEG/StandardModel/StandardModelBase.h"
 #include "ThePEG/Repository/Strategy.h"
 #include "ThePEG/Repository/CurrentGenerator.h"
 #include "ThePEG/Handlers/AnalysisHandler.h"
 #include "ThePEG/Analysis/FactoryBase.h"
 #include "ThePEG/Handlers/EventManipulator.h"
 #include "ThePEG/Handlers/LuminosityFunction.h"
 #include "ThePEG/MatrixElement/MEBase.h"
 #include "ThePEG/EventRecord/Event.h"
 #include "ThePEG/Handlers/SubProcessHandler.h"
 #include "ThePEG/Handlers/CascadeHandler.h"
 #include "ThePEG/Handlers/HadronizationHandler.h"
 #include "ThePEG/Persistency/PersistentOStream.h"
 #include "ThePEG/Persistency/PersistentIStream.h"
 #include "ThePEG/Config/algorithm.h"
 #include "ThePEG/Utilities/DynamicLoader.h"
 #include <cstdlib>
 #include "ThePEG/Repository/Main.h"
 #include <csignal>
 
 #ifdef ThePEG_TEMPLATES_IN_CC_FILE
 #include "EventGenerator.tcc"
 #endif
 
 using namespace ThePEG;
 
 namespace {
   volatile sig_atomic_t THEPEG_SIGNAL_STATE = 0;
 }
 
 // signal handler function
 // very restricted in what it is allowed do
 // without causing undefined behaviour
 extern "C" {
   void thepegSignalHandler(int id) {
     THEPEG_SIGNAL_STATE=id;
     signal(id,SIG_DFL);
   }
 }
 
 void EventGenerator::checkSignalState() {
   if (THEPEG_SIGNAL_STATE) {
     log() << "Caught signal " << THEPEG_SIGNAL_STATE << ". Exiting ..." << std::endl;
     finalize();
     exit(0);
   }
 }
 
 EventGenerator::EventGenerator()
   : thePath("."), theNumberOfEvents(1000), theQuickSize(7000),
     preinitializing(false), ieve(0), weightSum(0.0),
     theDebugLevel(0), logNonDefault(-1), printEvent(0), dumpPeriod(0),
     keepAllDumps(false),
     debugEvent(0), maxWarnings(10), maxErrors(10), theCurrentRandom(0),
     theCurrentGenerator(0), useStdout(false), theIntermediateOutput(false) {}
 
 EventGenerator::EventGenerator(const EventGenerator & eg)
   : Interfaced(eg), theDefaultObjects(eg.theDefaultObjects),
     theLocalParticles(eg.theLocalParticles),
     theStandardModel(eg.theStandardModel),
     theStrategy(eg.theStrategy), theRandom(eg.theRandom),
     theEventHandler(eg.theEventHandler),
     theAnalysisHandlers(eg.theAnalysisHandlers),
     theHistogramFactory(eg.theHistogramFactory),
     theEventManipulator(eg.theEventManipulator),
     thePath(eg.thePath), theRunName(eg.theRunName),
     theNumberOfEvents(eg.theNumberOfEvents), theObjects(eg.theObjects),
     theObjectMap(eg.theObjectMap),
     theParticles(eg.theParticles), theQuickParticles(eg.theQuickParticles),
     theQuickSize(eg.theQuickSize), preinitializing(false),
     theMatchers(eg.theMatchers),
     usedObjects(eg.usedObjects), ieve(eg.ieve), weightSum(eg.weightSum),
     theDebugLevel(eg.theDebugLevel), logNonDefault(eg.logNonDefault),
     printEvent(eg.printEvent), dumpPeriod(eg.dumpPeriod),
     keepAllDumps(eg.keepAllDumps),
     debugEvent(eg.debugEvent),
     maxWarnings(eg.maxWarnings), maxErrors(eg.maxErrors), theCurrentRandom(0),
     theCurrentGenerator(0),
     theCurrentEventHandler(eg.theCurrentEventHandler),
     theCurrentStepHandler(eg.theCurrentStepHandler),
     useStdout(eg.useStdout),
     theIntermediateOutput(eg.theIntermediateOutput) {}
 
 EventGenerator::~EventGenerator() {
   if ( theCurrentRandom ) delete theCurrentRandom;
   if ( theCurrentGenerator ) delete theCurrentGenerator;
 }
 
 IBPtr EventGenerator::clone() const {
   return new_ptr(*this);
 }
 
 IBPtr EventGenerator::fullclone() const {
   return new_ptr(*this);
 }
 
 tcEventPtr EventGenerator::currentEvent() const {
   return eventHandler()->currentEvent();
 }
 
 CrossSection EventGenerator::histogramScale() const {
   return eventHandler()->histogramScale();
 }
 
 CrossSection EventGenerator::integratedXSec() const {
   return eventHandler()->integratedXSec();
 }
 
 CrossSection EventGenerator::integratedXSecErr() const {
   return eventHandler()->integratedXSecErr();
 }
 
 void EventGenerator::setSeed(long seed) {
   random().setSeed(seed);
   ostringstream s;
   s << seed;
   const InterfaceBase * ifb = BaseRepository::FindInterface(theRandom, "Seed");
   ifb->exec(*theRandom, "set", s.str());
 }
 
 void
 EventGenerator::setup(string newRunName,
 		      ObjectSet & newObjects,
 		      ParticleMap & newParticles,
 		      MatcherSet & newMatchers) {
   HoldFlag<int> debug(Debug::level, Debug::isset? Debug::level: theDebugLevel);
   theRunName = newRunName;
   theObjects.swap(newObjects);
   theParticles.swap(newParticles);
   theMatchers.swap(newMatchers);
   theObjectMap.clear();
   for ( ObjectSet::const_iterator it = objects().begin();
 	it != objects().end(); ++it ) theObjectMap[(**it).fullName()] = *it;
   UseRandom currentRandom(theRandom);
   CurrentGenerator currentGenerator(this);
 
   // Force update of all objects and then reset.
   touch();
   for_each(theObjects, mem_fun(&InterfacedBase::touch));
   update();
   for_each(theObjects, mem_fun(&InterfacedBase::update));
   clear();
   BaseRepository::clearAll(theObjects);
 
   init();
 
 }
 
 IBPtr EventGenerator::getPointer(string name) const {
   ObjectMap::const_iterator it = objectMap().find(name);
   if ( it == objectMap().end() ) return IBPtr();
   else return it->second;
 }
 
 void EventGenerator::openOutputFiles() {
   if ( !useStdout ) {
     logfile().open((filename() + ".log").c_str());
     theOutFileName = filename() + ".out";
     outfile().open(theOutFileName.c_str());
     outfile().close();
     theOutStream.str("");
   }
   out() << Repository::banner() << endl;
   log() << Repository::banner() << endl;
 }
 
 void EventGenerator::closeOutputFiles() {
   flushOutputFile();
   if ( !useStdout ) logfile().close();
 }
 
 void EventGenerator::flushOutputFile() {
   if ( !useStdout ) {
     outfile().open(theOutFileName.c_str(), ios::out|ios::app);
     outfile() << theOutStream.str();
     outfile().close();
   } else
     BaseRepository::cout() << theOutStream.str();
   theOutStream.str("");
 }
 
 void EventGenerator::doinit() {
 
   HoldFlag<int> debug(Debug::level, Debug::isset? Debug::level: theDebugLevel);
 
   // First initialize base class and random number generator.
   Interfaced::doinit();
   random().init();
 
   // Make random generator and this available in standard static
   // classes.
   UseRandom useRandom(theRandom);
   CurrentGenerator currentGenerator(this);
 
   // First initialize all objects which have requested this by
   // implementing a InterfacedBase::preInitialize() function which
   // returns true.
   while ( true ) {
     HoldFlag<bool> hold(preinitializing, true);
     ObjectSet preinits;
     for ( ObjectSet::iterator it = objects().begin();
 	  it != objects().end(); ++it )
       if ( (**it).preInitialize() &&
 	   (**it).state() == InterfacedBase::uninitialized )
 	preinits.insert(*it);
     if ( preinits.empty() ) break;
     for_each(preinits, mem_fun(&InterfacedBase::init));
   }
 
   // Initialize the quick access to particles.
   theQuickParticles.clear();
   theQuickParticles.resize(2*theQuickSize);
   for ( ParticleMap::const_iterator pit = theParticles.begin();
 	pit != theParticles.end(); ++pit )
     if ( abs(pit->second->id()) < theQuickSize )
       theQuickParticles[pit->second->id()+theQuickSize] = pit->second;
 
   // Then call the init method for all objects. Start with the
   // standard model and the strategy.
   standardModel()->init();
   if ( strategy() ) strategy()->init();
   eventHandler()->init();
 
   // initialize particles first
   for(ParticleMap::const_iterator pit = particles().begin();
       pit != particles().end(); ++pit) pit->second->init();
   
   for_each(objects(), mem_fun(&InterfacedBase::init));
 
   // Then initialize the Event Handler calculating initial cross
   // sections and stuff.
   eventHandler()->initialize();
 }
 
 void EventGenerator::doinitrun() {
 
   HoldFlag<int> debug(Debug::level, Debug::isset? Debug::level: theDebugLevel);
 
   signal(SIGHUP, thepegSignalHandler);
   signal(SIGINT, thepegSignalHandler);
   signal(SIGTERM,thepegSignalHandler);
 
   currentEventHandler(eventHandler());
 
   Interfaced::doinitrun();
   random().initrun();
 
   // Then call the init method for all objects. Start with the
   // standard model and the strategy.
   standardModel()->initrun();
   if ( strategy() ) { 
     strategy()->initrun();
     if ( ! strategy()->versionstring().empty() ) {
       out() << ">> " << strategy()->versionstring() << '\n' << endl;
       log() << ">> " << strategy()->versionstring() << '\n' << endl;
     }
   }
   // initialize particles first
   for(ParticleMap::const_iterator pit = particles().begin();
       pit != particles().end(); ++pit) {
     pit->second->initrun();
   }
   eventHandler()->initrun();
 
   
   for_each(objects(), mem_fun(&InterfacedBase::initrun));
 
   if ( logNonDefault > 0 || ( ThePEG_DEBUG_LEVEL && logNonDefault == 0 ) ) {
     vector< pair<IBPtr, const InterfaceBase *> > changed =
       Repository::getNonDefaultInterfaces(objects());
     if ( changed.size() ) {
       log() << string(78, '=') << endl
 	    << "The following interfaces have non-default values (default):"
 	    << endl << string(78, '-') << endl;
       for ( int i = 0, N = changed.size(); i < N; ++i ) {
 	log() << changed[i].first->fullName() << ":"
 	      << changed[i].second->name() << " = "
 	      << changed[i].second->exec(*changed[i].first, "notdef", "")
 	      << endl;
       }
       log() << string(78,'=') << endl;
     }
   }
 
   weightSum = 0.0;
 
 }
 
 PDPtr EventGenerator::getParticleData(PID id) const {
   long newId = id;
   if ( abs(newId) < theQuickSize && theQuickParticles.size() )
     return theQuickParticles[newId+theQuickSize];
   ParticleMap::const_iterator it = theParticles.find(newId);
   if ( it == theParticles.end() ) return PDPtr();
   return it->second;
 }
 
 PPtr EventGenerator::getParticle(PID newId) const {
   tcPDPtr pd = getParticleData(newId);
   if ( !pd ) return PPtr();
   return pd->produceParticle();
 }
 
 void EventGenerator::finalize() {
   UseRandom currentRandom(theRandom);
   CurrentGenerator currentGenerator(this);
   finish();
   finally();
 }
 
 void EventGenerator::dofinish() {
 
   HoldFlag<int> debug(Debug::level, Debug::isset? Debug::level: theDebugLevel);
 
   // first write out statistics from the event handler.
   eventHandler()->statistics(out());
 
   // Call the finish method for all other objects.
   for_each(objects(), mem_fun(&InterfacedBase::finish));
 
   if ( theExceptions.empty() ) {
     log() << "No exceptions reported in this run.\n";
   } else {
 
     log() << "\nThe following exception classes were reported in this run:\n";
 
     for ( ExceptionMap::iterator it = theExceptions.begin();
 	  it != theExceptions.end(); ++it ) {
       string severity;
       switch ( it->first.second ) {
       case Exception::info       : severity="info"; break;
       case Exception::warning    : severity="warning"; break;
       case Exception::setuperror : severity="setuperror"; break;
       case Exception::eventerror : severity="eventerror"; break;
       case Exception::runerror   : severity="runerror"; break;
       case Exception::maybeabort : severity="maybeabort"; break;
       case Exception::abortnow   : severity="abortnow"; break;
       default                    : severity="unknown";
       }
       log() << it->first.first << ' ' << severity
 	    << " (" << it->second << " times)\n";
     }
   }
 
   theExceptions.clear();
 
   const string & msg = theMiscStream.str();
   if ( ! msg.empty() ) {
     log() << endl 
 	  << "Miscellaneous output from modules to the standard output:\n\n"
 	  << msg;
     theMiscStream.str("");
   }
 
   flushOutputFile();
 
 }
 
 void EventGenerator::finally() {
 
   generateReferences();
 
   closeOutputFiles();
 
   if ( theCurrentRandom ) delete theCurrentRandom;
   if ( theCurrentGenerator ) delete theCurrentGenerator;
   theCurrentRandom = 0;
   theCurrentGenerator = 0;
 
 }
 
 void EventGenerator::initialize(bool initOnly) {
   UseRandom currentRandom(theRandom);
   CurrentGenerator currentGenerator(this);
   doInitialize(initOnly);
 }
 
 bool EventGenerator::loadMain(string file) {
   initialize();
   UseRandom currentRandom(theRandom);
   CurrentGenerator currentGenerator(this);
   Main::eventGenerator(this);
   bool ok = DynamicLoader::load(file);
   finish();
   finally();
   return ok;
 }
 
 
 void EventGenerator::go(long next, long maxevent, bool tics) {
   UseRandom currentRandom(theRandom);
   CurrentGenerator currentGenerator(this);
   doGo(next, maxevent, tics);
 }
 
 EventPtr EventGenerator::shoot() {
   static DebugItem debugfpu("ThePEG::FPU", 1);
   if ( debugfpu ) Debug::unmaskFpuErrors();
   UseRandom currentRandom(theRandom);
   CurrentGenerator currentGenerator(this);
   checkSignalState();
   EventPtr event = doShoot();
   if ( event ) weightSum += event->weight();
   DebugItem::tic();
   return event;
 }
 
 EventPtr EventGenerator::doShoot() {
   EventPtr event;
   if ( N() >= 0 && ++ieve > N() ) return event;
   HoldFlag<int> debug(Debug::level, Debug::isset? Debug::level: theDebugLevel);
   do { 
     int state = 0;
     int loop = 1;
     eventHandler()->clearEvent();
     try {
       do {
 	// Generate a full event or part of an event
 	if ( eventHandler()->empty() ) event = eventHandler()->generateEvent();
 	else event = eventHandler()->continueEvent();
 
 	if ( eventHandler()->empty() ) loop = -loop;
 	
 	// Analyze the possibly uncomplete event
 	for ( AnalysisVector::iterator it = analysisHandlers().begin();
 	      it != analysisHandlers().end(); ++it )
 	  (**it).analyze(event, ieve, loop, state);
 	
 	// Manipulate the current event, possibly deleting some steps
 	// and telling the event handler to redo them.
 	if ( manipulator() )
 	  state = manipulator()->manipulate(eventHandler(), event);
 	
 	// If the event was not completed, continue generation and continue.
 	loop = abs(loop) + 1;
       } while ( !eventHandler()->empty() );
     }
     catch (Exception & ex) {
       if ( logException(ex, eventHandler()->currentEvent()) ) throw;
     }
     catch (...) {
       event = eventHandler()->currentEvent();
       if ( event )
 	log() << *event;
       else
 	log() << "An exception occurred before any event object was created!";
       log() << endl;
       dump();
       throw;
     }
     if ( ThePEG_DEBUG_LEVEL ) {
       if ( ( ThePEG_DEBUG_LEVEL == Debug::printEveryEvent ||
 	     ieve < printEvent ) && event ) log() << *event;
       if ( debugEvent > 0 && ieve + 1 >= debugEvent )
 	Debug::level = Debug::full;
     }
   } while ( !event );
 
   // If scheduled, dump a clean state between events
   if ( ThePEG_DEBUG_LEVEL && dumpPeriod > 0 && ieve%dumpPeriod == 0 ) {
     eventHandler()->clearEvent();
     eventHandler()->clean();
     dump();
   }
 
   return event;
 }
 
 EventPtr EventGenerator::doGenerateEvent(tEventPtr e) {
   if ( N() >= 0 && ++ieve > N() ) return EventPtr();
   EventPtr event = e;
   try {
     event = eventHandler()->generateEvent(e);
   }
   catch (Exception & ex) {
     if ( logException(ex, eventHandler()->currentEvent()) ) throw;
   }
   catch (...) {
     event = eventHandler()->currentEvent();
     if ( !event ) event = e;
     log() << *event << endl;
     dump();
     throw;
   }
   return event;
 }
 
 EventPtr EventGenerator::doGenerateEvent(tStepPtr s) {
   if ( N() >= 0 && ++ieve > N() ) return EventPtr();
   EventPtr event;
   try {
     event = eventHandler()->generateEvent(s);
   }
   catch (Exception & ex) {
     if ( logException(ex, eventHandler()->currentEvent()) ) throw;
   }
   catch (...) {
     event = eventHandler()->currentEvent();
     if ( event ) log() << *event << endl;
     dump();
     throw;
   }
   return event;
 }
 
 EventPtr EventGenerator::generateEvent(Event & e) {
   UseRandom currentRandom(theRandom);
   CurrentGenerator currentGenerator(this);
   EventPtr event = doGenerateEvent(tEventPtr(&e));
   if ( event ) weightSum += event->weight();
   return event;
 }
 
 EventPtr EventGenerator::generateEvent(Step & s) {
   UseRandom currentRandom(theRandom);
   CurrentGenerator currentGenerator(this);
   EventPtr event = doGenerateEvent(tStepPtr(&s));
   if ( event ) weightSum += event->weight();
   return event;
 }
 
 Energy EventGenerator::maximumCMEnergy() const {
   tcEHPtr eh = eventHandler();
   return eh->lumiFnPtr()? eh->lumiFn().maximumCMEnergy(): ZERO;
 }
 
 void EventGenerator::doInitialize(bool initOnly) {
 
   if ( !initOnly )
     openOutputFiles();
 
   init();
 
   if ( !initOnly )
     initrun();
 
   if ( !ThePEG_DEBUG_LEVEL ) Exception::noabort = true;
 
 }
 
 void EventGenerator::doGo(long next, long maxevent, bool tics) {
 
   if ( maxevent >= 0 ) N(maxevent);
 
   if ( next >= 0 ) {
     if ( tics ) 
       cerr << "event> " << setw(9) << "init\r" << flush;
     initialize();
     ieve = next-1;
   } else {
     openOutputFiles();
   }
 
   if ( tics ) tic();
   try {
     while ( shoot() ) {
       if ( tics ) tic();
     }
   }
   catch ( ... ) {
     finish();
     throw;
   }
 
   finish();
 
   finally();
 
 }
 
 void EventGenerator::tic(long currev, long totev) const {
   if ( !currev ) currev = ieve;
   if ( !totev ) totev = N();
   long i = currev;
   long n = totev;
   bool skip = currev%(max(totev/100, 1L));
   if ( i > n/2 ) i = n-i;
   while ( skip && i >= 10 && !(i%10) ) i /= 10;
   if ( i == 1 || i == 2 || i == 5 ) skip = false;
   if (!theIntermediateOutput) { //default
     if ( skip ) return;
     cerr << "event> " << setw(8) << currev << " " << setw(8) << totev << "\r";
   }
   else if (theIntermediateOutput) {
     if ( skip && currev%10000!=0) return;
     cerr <<  "event> " << setw(9) << right << currev << "/" << totev 
          << "; xs = " << integratedXSec()/picobarn << " pb +- " 
          << integratedXSecErr()/picobarn << " pb" << endl;
   }
   cerr.flush();
   if ( currev == totev ) cerr << endl;
 }
   
 
 void EventGenerator::dump() const {
   if ( dumpPeriod > -1 ) {
     string dumpfile;
     if ( keepAllDumps ) {
       ostringstream number;
       number << ieve;
       dumpfile = filename() + "-" + number.str() + ".dump";
     }
     else
       dumpfile = filename() + ".dump";
     PersistentOStream file(dumpfile, globalLibraries());
     file << tcEGPtr(this);
   }
 }
 
 void EventGenerator::use(const Interfaced & i) {
   IBPtr ip = getPtr(i);
   if ( ip ) usedObjects.insert(ip);
 }
 
 void EventGenerator::generateReferences() {
   typedef map<string,string> StringMap;
   StringMap references;
 
   // First get all model descriptions and model references from the
   // used objects. Put them in a map indexed by the description to
   // avoid duplicates.
   for ( ObjectSet::iterator it = usedObjects.begin();
 	it != usedObjects.end(); ++it ) {
     if ( *it == strategy() ) continue;
     string desc = Repository::getModelDescription(*it);
     if ( desc.empty() ) continue;
     if ( dynamic_ptr_cast<cEHPtr>(*it) ) desc = "A " + desc;
     else if ( dynamic_ptr_cast<cSMPtr>(*it) ) desc = "B " + desc;
     else if ( dynamic_ptr_cast<cMEPtr>(*it) ) desc = "C " + desc;
     else if ( dynamic_ptr_cast<cCascHdlPtr>(*it) ) desc = "D " + desc;
     else if ( dynamic_ptr_cast<cHadrHdlPtr>(*it) ) desc = "E " + desc;
     else if ( dynamic_ptr_cast<cStepHdlPtr>(*it) ) desc = "F " + desc;
     else if ( dynamic_ptr_cast<cDecayerPtr>(*it) ) desc = "Y " + desc;
     else if ( dynamic_ptr_cast<cAnalysisHdlPtr>(*it) ) desc = "Z " + desc;
     else if ( dynamic_ptr_cast<Ptr<HandlerBase>::const_pointer>(*it) )
       desc = "G " + desc;
     else  desc = "H " + desc;
     references[desc] = Repository::getModelReferences(*it);
   }
 
   // Now get the main strategy description which should put first and
   // remove it from the map.
   string stratdesc;
   string stratref;
   if ( strategy() ) {
     stratdesc = Repository::getModelDescription(strategy());
     stratref = Repository::getModelReferences(strategy());
     references.erase(stratdesc);
   }
 
   // Open the file and write out an appendix header
   if ( !useStdout )
     reffile().open((filename() + ".tex").c_str());
   ref() << "\\documentclass{article}\n"
 	<< "\\usepackage{graphics}\n"
 	<< "\\begin{document}\n"
 	<< "\\appendix\n"
 	<< "\\section[xxx]{\\textsc{ThePEG} version " << Repository::version()
 	<< " \\cite{ThePEG} Run Information}\n"
 	<< "Run name: \\textbf{" << runName()
 	<< "}:\\\\\n";
   if ( !stratdesc.empty() )
     ref() << "This run was generated using " << stratdesc 
 	  << " and the following models:\n";
   else
     ref() << "The following models were used:\n";
 
   ref() << "\\begin{itemize}\n";
 
   // Write out all descriptions.
   for ( StringMap::iterator it = references.begin();
 	it != references.end(); ++it )
     ref() << "\\item " << it->first.substr(2) << endl;
 
   // Write out thebibliography header and all references.
   ref() << "\\end{itemize}\n\n"
 	    << "\\begin{thebibliography}{99}\n"
 	    << "\\bibitem{ThePEG} L.~L\\\"onnblad, "
 	    << "Comput.~Phys.~Commun.\\ {\\bf 118} (1999) 213.\n";
   if ( !stratref.empty() ) ref() << stratref << '\n';
   for ( StringMap::iterator it = references.begin();
 	it != references.end(); ++it )
     ref() << it->second << '\n';
   ref() << "\\end{thebibliography}\n"
 	    << "\\end{document}" << endl;
   if ( !useStdout )
     reffile().close();
 }
 
 void EventGenerator::strategy(StrategyPtr s) {
   theStrategy = s;
 }
 
 int EventGenerator::count(const Exception & ex) {
   return ++theExceptions[make_pair(StringUtils::typeName(typeid(ex)),
 				   ex.severity())];
 }
 
 void EventGenerator::printException(const Exception & ex) {
   switch ( ex.severity() ) {
   case Exception::info:
     log() << "* An information";
         break;
   case Exception::warning:
     log() << "* A warning";
     break;
   case Exception::setuperror:
     log() << "** A setup";
     break;
   case Exception::eventerror:
     log() << "** An event";
     break;
   case Exception::runerror:
     log() << "*** An run";
     break;
   case Exception::maybeabort:
   case Exception::abortnow:
     log() << "**** A serious";
     break;
   default:
     log() << "**** An unknown";
     break;
   }
   if ( ieve > 0 )
     log() << " exception of type " << StringUtils::typeName(typeid(ex))
 	  << " occurred while generating event number "
 	  << ieve << ": \n" << ex.message() << endl;
   else
     log() << " exception occurred in the initialization of "
 	  << name() << ": \n" << ex.message() << endl;
   if ( ex.severity() == Exception::eventerror )
     log() << "The event will be discarded." << endl;
 }
 
 void EventGenerator::logWarning(const Exception & ex) {
   if ( ex.severity() != Exception::info &&
        ex.severity() != Exception::warning ) throw ex;
   ex.handle();  
   int c = count(ex);
   if ( c > maxWarnings ) return;
   printException(ex);
   if ( c == maxWarnings )
     log() << "No more warnings of this kind will be reported." << endl;
 }
  
 bool EventGenerator::
 logException(const Exception & ex, tcEventPtr event) {
   bool noEvent = !event;
   ex.handle();
   int c = count(ex);
   if ( c <= maxWarnings ) {
     printException(ex);
     if ( c == maxWarnings )
       log() << "No more warnings of this kind will be reported." << endl;
   }
   if ( ex.severity() == Exception::info ||
        ex.severity() == Exception::warning ) {
     ex.handle();
     return false;
   }
   if ( ex.severity() == Exception::eventerror ) {
     if ( c < maxErrors || maxErrors <= 0 ) {
       ex.handle();
       if ( ThePEG_DEBUG_LEVEL > 0 && !noEvent ) log() << *event;
       return false;
     }
     if ( c > maxErrors ) printException(ex);
     log() << "Too many (" << c << ") exceptions of this kind has occurred. "
       "Execution will be stopped.\n";
   } else {
     log() << "This exception is too serious. Execution will be stopped.\n";
   }
   if ( !noEvent ) log() << *event;
   else log()
     << "An exception occurred before any event object was created!\n";
   dump();
   return true;
 }
 
 struct MatcherOrdering {
   bool operator()(tcPMPtr m1, tcPMPtr m2) {
     return m1->name() < m2->name() ||
       ( m1->name() == m2->name() && m1->fullName() < m2->fullName() );
   }
 };
 
 struct ObjectOrdering {
   bool operator()(tcIBPtr i1, tcIBPtr i2) {
     return i1->fullName() < i2->fullName();
   }
 };
 
 void EventGenerator::persistentOutput(PersistentOStream & os) const {
   set<tcPMPtr,MatcherOrdering> match(theMatchers.begin(), theMatchers.end());
   set<tcIBPtr,ObjectOrdering> usedset(usedObjects.begin(), usedObjects.end());
   os << theDefaultObjects << theLocalParticles << theStandardModel
      << theStrategy << theRandom << theEventHandler << theAnalysisHandlers
      << theHistogramFactory << theEventManipulator << thePath << theRunName
      << theNumberOfEvents << theObjectMap << theParticles
      << theQuickParticles << theQuickSize << match << usedset
      << ieve << weightSum << theDebugLevel << logNonDefault << printEvent
      << dumpPeriod << keepAllDumps << debugEvent
      << maxWarnings << maxErrors << theCurrentEventHandler
      << theCurrentStepHandler << useStdout << theIntermediateOutput << theMiscStream.str()
      << Repository::listReadDirs();
 }
 
 void EventGenerator::persistentInput(PersistentIStream & is, int) {
   string dummy;
   vector<string> readdirs;
   theGlobalLibraries = is.globalLibraries();
   is >> theDefaultObjects >> theLocalParticles >> theStandardModel
      >> theStrategy >> theRandom >> theEventHandler >> theAnalysisHandlers
      >> theHistogramFactory >> theEventManipulator >> thePath >> theRunName
      >> theNumberOfEvents >> theObjectMap >> theParticles
      >> theQuickParticles >> theQuickSize >> theMatchers >> usedObjects
      >> ieve >> weightSum >> theDebugLevel >> logNonDefault >> printEvent
      >> dumpPeriod >> keepAllDumps >> debugEvent
      >> maxWarnings >> maxErrors >> theCurrentEventHandler
      >> theCurrentStepHandler >> useStdout >> theIntermediateOutput >> dummy
      >> readdirs;
   theMiscStream.str(dummy);
   theMiscStream.seekp(0, std::ios::end);
   theObjects.clear();
   for ( ObjectMap::iterator it = theObjectMap.begin();
 	it != theObjectMap.end(); ++it ) theObjects.insert(it->second);
   Repository::appendReadDir(readdirs);
 }
 
 void EventGenerator::setLocalParticles(PDPtr pd, int) {
   localParticles()[pd->id()] = pd;
 }
   
 void EventGenerator::insLocalParticles(PDPtr pd, int) {
   localParticles()[pd->id()] = pd;
 }
   
 void EventGenerator::delLocalParticles(int place) {
   ParticleMap::iterator it = localParticles().begin();
   while ( place-- && it != localParticles().end() ) ++it;
   if ( it != localParticles().end() ) localParticles().erase(it);
 }
 
 vector<PDPtr> EventGenerator::getLocalParticles() const {
   vector<PDPtr> ret;
   for ( ParticleMap::const_iterator it = localParticles().begin();
  	it != localParticles().end(); ++it ) ret.push_back(it->second);
   return ret;
 }
 
 void EventGenerator::setPath(string newPath) {
   if ( std::system(("mkdir -p " + newPath).c_str()) ) throw EGNoPath(newPath);
   if ( std::system(("touch " + newPath + "/.ThePEG").c_str()) )
     throw EGNoPath(newPath);
   if ( std::system(("rm -f " + newPath + "/.ThePEG").c_str()) )
     throw EGNoPath(newPath);
   thePath = newPath;
 }
 
 string EventGenerator::defPath() const {
   char * env = std::getenv("ThePEG_RUN_DIR");
   if ( env ) return string(env);
   return string(".");
 }
 
 ostream & EventGenerator::out() {
   return theOutStream;
 }
 
 ostream & EventGenerator::log() {
   return logfile().is_open()? logfile(): BaseRepository::cout();
 }
 
 ostream & EventGenerator::ref() {
   return reffile().is_open()? reffile(): BaseRepository::cout();
 }
 
 string EventGenerator::doSaveRun(string runname) {
   runname = StringUtils::car(runname);
   if ( runname.empty() ) runname = theRunName;
   if ( runname.empty() ) runname = name();
   EGPtr eg = Repository::makeRun(this, runname);
   string file =  eg->filename() + ".run";
   PersistentOStream os(file);
   os << eg;
   if ( !os ) return "Error: Save failed! (I/O error)";
   return "";
 }
 
 string EventGenerator::doMakeRun(string runname) {
   runname = StringUtils::car(runname);
   if ( runname.empty() ) runname = theRunName;
   if ( runname.empty() ) runname = name();
   Repository::makeRun(this, runname);
   return "";
 }
 
 bool EventGenerator::preinitRegister(IPtr obj, string fullname) {
   if ( !preinitializing ) throw InitException()
     << "Tried to register a new object in the initialization of an "
     << "EventGenerator outside of the pre-initialization face. "
     << "The preinitRegister() can only be called from a doinit() function "
     << "in an object for which preInitialize() returns true.";
   if ( objectMap().find(fullname) != objectMap().end() ) return false;
   obj->name(fullname);
   objectMap()[fullname] = obj;
   objects().insert(obj);
   obj->theGenerator = this;
   PDPtr pd = dynamic_ptr_cast<PDPtr>(obj);
   if ( pd ) theParticles[pd->id()] = pd;
   PMPtr pm = dynamic_ptr_cast<PMPtr>(obj);
   if ( pm ) theMatchers.insert(pm);
   return true;
 }
 
 bool EventGenerator::preinitRemove(IPtr obj) {
   bool deleted=true;
   if(theObjects.find(obj)!=theObjects.end()) {
     theObjects.erase(obj);
   }
   else
     deleted = false;
   if(theObjectMap.find(obj->fullName())!=theObjectMap.end())
     theObjectMap.erase(obj->fullName());
   else
     deleted = false;
   return deleted;
 }
 
 IPtr EventGenerator::
 preinitCreate(string classname, string fullname, string libraries) {
   if ( !preinitializing ) throw InitException()
     << "Tried to create a new object in the initialization of an "
     << "EventGenerator outside of the pre-initialization face. "
     << "The preinitCreate() can only be called from a doinit() function "
     << "in an object for which preInitialize() returns true.";
   if ( objectMap().find(fullname) != objectMap().end() ) return IPtr();
   const ClassDescriptionBase * db = DescriptionList::find(classname);
   while ( !db && libraries.length() ) {
     string library = StringUtils::car(libraries);
     libraries = StringUtils::cdr(libraries);
     DynamicLoader::load(library);
     db = DescriptionList::find(classname);
   }
   if ( !db ) return IPtr();
   IPtr obj = dynamic_ptr_cast<IPtr>(db->create());
   if ( !obj ) return IPtr();
   if ( !preinitRegister(obj, fullname) ) return IPtr();
   return obj;
 }
 
 string EventGenerator::
 preinitInterface(IPtr obj, string ifcname, string cmd, string value) {
   if ( !preinitializing ) throw InitException()
     << "Tried to manipulate an external object in the initialization of an "
     << "EventGenerator outside of the pre-initialization face. "
     << "The preinitSet() can only be called from a doinit() function "
     << "in an object for which preInitialize() returns true.";
   if ( !obj ) return "Error: No object found.";
   const InterfaceBase * ifc = Repository::FindInterface(obj, ifcname);
   if ( !ifc ) return "Error: No such interface found.";
   try {
     return ifc->exec(*obj, cmd, value);
   }
   catch ( const InterfaceException & ex) {
     ex.handle();
     return "Error: " + ex.message();
   }
 }
 
 string EventGenerator::
 preinitInterface(IPtr obj, string ifcname, int index,
 		 string cmd, string value) {
   ostringstream os;
   os << index;
   return preinitInterface(obj, ifcname, cmd, os.str() + " " + value);
 }
 
 string EventGenerator::
 preinitInterface(string fullname, string ifcname, string cmd, string value) {
   return preinitInterface(getObject<Interfaced>(fullname), ifcname, cmd, value);
 }
 
 string EventGenerator::
 preinitInterface(string fullname, string ifcname, int index,
 		 string cmd, string value) {
   return preinitInterface(getObject<Interfaced>(fullname), ifcname, index,
 			  cmd, value);
 }
 
 tDMPtr EventGenerator::findDecayMode(string tag) const {
   for ( ObjectSet::const_iterator it = objects().begin();
 	it != objects().end(); ++it ) {
     tDMPtr dm = dynamic_ptr_cast<tDMPtr>(*it);
     if ( dm && dm->tag() == tag ) return dm;
   }
   return tDMPtr();
 }
 
 tDMPtr EventGenerator::preinitCreateDecayMode(string tag) {
   return constructDecayMode(tag);
 }
 
 DMPtr EventGenerator::constructDecayMode(string & tag) {
   DMPtr rdm;
   DMPtr adm;
   int level = 0;
   string::size_type end = 0;
   while ( end < tag.size() && ( tag[end] != ']' || level ) ) {
     switch ( tag[end++] ) {
     case '[':
       ++level;
       break;
     case ']':
       --level;
       break;
     }
   }
   rdm = findDecayMode(tag.substr(0,end));
   if ( rdm ) return rdm;
 
   string::size_type next = tag.find("->");
   if ( next == string::npos ) return rdm;
   if ( tag.find(';') == string::npos ) return rdm;
   tPDPtr pd = getObject<ParticleData>(tag.substr(0,next));
   if ( !pd ) pd = findParticle(tag.substr(0,next));
   if ( !pd ) return rdm;
   rdm = ptr_new<DMPtr>();
   rdm->parent(pd);
   if ( pd->CC() ) {
     adm = ptr_new<DMPtr>();
     adm->parent(pd->CC());
     rdm->theAntiPartner = adm;
     adm->theAntiPartner = rdm;
   }
   bool error = false;
   tag = tag.substr(next+2);
   tPDPtr lastprod;
   bool dolink = false;
   do {
     switch ( tag[0] ) {
     case '[':
       {
 	tag = tag.substr(1);
 	tDMPtr cdm = constructDecayMode(tag);
 	if ( cdm ) rdm->addCascadeProduct(cdm);
 	else error = true;
       } break;
     case '=':
       dolink = true;
+      [[fallthrough]];
     case ',':
     case ']':
       tag = tag.substr(1);
       break;
     case '?':
       {
 	next = min(tag.find(','), tag.find(';'));
 	tPMPtr pm = findMatcher(tag.substr(1,next-1));
 	if ( pm ) rdm->addProductMatcher(pm);
 	else error = true;
 	tag = tag.substr(next);
       } break;
     case '!':
       {
 	next = min(tag.find(','), tag.find(';'));
 	tPDPtr pd = findParticle(tag.substr(1,next-1));
 	if ( pd ) rdm->addExcluded(pd);
 	else error = true;
 	tag = tag.substr(next);
       } break;
     case '*':
       {
 	next = min(tag.find(','), tag.find(';'));
 	tPMPtr pm = findMatcher(tag.substr(1,next-1));
 	if ( pm ) rdm->setWildMatcher(pm);
 	else error = true;
 	tag = tag.substr(next);
       } break;
     default:
       {
 	next = min(tag.find('='), min(tag.find(','), tag.find(';')));
 	tPDPtr pdp = findParticle(tag.substr(0,next));
 	if ( pdp ) rdm->addProduct(pdp);
 	else error = true;
 	tag = tag.substr(next);
 	if ( dolink && lastprod ) {
 	  rdm->addLink(lastprod, pdp);
 	  dolink = false;
 	}
 	lastprod = pdp;
       } break;
     }
   } while ( tag[0] != ';' && tag.size() );
   if ( tag[0] != ';' || error ) {
     return DMPtr();
   }
 
   tag = tag.substr(1);
   
   DMPtr ndm = findDecayMode(rdm->tag());
   if ( ndm ) return ndm;
   pd->addDecayMode(rdm);
   if ( !preinitRegister(rdm, pd->fullName() + "/" + rdm->tag()) )
     return DMPtr();
   if ( adm ) {
     preinitRegister(adm, pd->CC()->fullName() + "/" + adm->tag());
     rdm->CC(adm);
     adm->CC(rdm);
   }
 
   return rdm;
 }
 
 tPDPtr EventGenerator::findParticle(string pdgname) const {
   for ( ParticleMap::const_iterator it = particles().begin();
 	it != particles().end(); ++it )
     if ( it->second->PDGName() == pdgname ) return it->second;
   return tPDPtr();
 }
 
 tPMPtr EventGenerator::findMatcher(string name) const {
   for ( MatcherSet::const_iterator it = matchers().begin();
 	it != matchers().end(); ++it )
     if ( (**it).name() == name ) return *it;
   return tPMPtr();
 }
 
 ClassDescription<EventGenerator> EventGenerator::initEventGenerator;
 
 void EventGenerator::Init() {
   
   static ClassDocumentation<EventGenerator> documentation
     ("This is the main class used to administer an event generation run. "
      "The actual generation of each event is handled by the assigned "
      "<interface>EventHandler</interface> object. When the event generator"
      "is properly set up it can be initialized with the command "
      "<interface>MakeRun</interface> and/or saved to a file with the command "
      "<interface>SaveRun</interface>. If saved to a file, the event generator "
      "can be read into another program to produce events. The file can also "
      "be read into the <tt>runThePEG</tt> program where a number of events "
      "determined by the parameter <interface>NumberOfEvents</interface> is "
      "generated with each event analysed by the list of assigned "
      "<interface>AnalysisHandlers</interface>.");
 
   static Reference<EventGenerator,StandardModelBase> interfaceStandardModel
     ("StandardModelParameters",
      "The ThePEG::StandardModelBase object to be used to access standard "
      "model parameters in this run.",
      &EventGenerator::theStandardModel, false, false, true, false);
 
   static Reference<EventGenerator,EventHandler> interfaceEventHandler
     ("EventHandler",
      "The ThePEG::EventHandler object to be used to generate the "
      "individual events in this run.",
      &EventGenerator::theEventHandler, false, false, true, false);
 
   static RefVector<EventGenerator,AnalysisHandler> interfaceAnalysisHandlers
     ("AnalysisHandlers",
      "ThePEG::AnalysisHandler objects to be used to analyze the produced "
      "events in this run.",
      &EventGenerator::theAnalysisHandlers, 0, true, false, true, false);
 
   static Reference<EventGenerator,FactoryBase> interfaceHistogramFactory
     ("HistogramFactory",
      "An associated factory object for handling histograms to be used by "
      "<interface>AnalysisHandlers</interface>.",
      &EventGenerator::theHistogramFactory, true, false, true, true, true);
 
   static Reference<EventGenerator,EventManipulator> interfaceEventManip
     ("EventManipulator",
      "An ThePEG::EventManipulator called each time the generation of an "
      "event is stopped. The ThePEG::EventManipulator object is able to "
      "manipulate the generated event, as opposed to an "
      "ThePEG::AnalysisHandler which may only look at the event.",
      &EventGenerator::theEventManipulator, true, false, true, true);
 
   static RefVector<EventGenerator,ParticleData> interfaceLocalParticles
     ("LocalParticles",
      "Special versions of ThePEG::ParticleData objects to be used "
      "in this run. Note that to delete an object, its number in the list "
      "should be given, rather than its id number.",
      0, 0, false, false, true, false,
      &EventGenerator::setLocalParticles, &EventGenerator::insLocalParticles,
      &EventGenerator::delLocalParticles, &EventGenerator::getLocalParticles);
 
   static RefVector<EventGenerator,Interfaced> interfaceDefaultObjects
     ("DefaultObjects",
      "A vector of pointers to default objects. In a ThePEG::Reference or "
      "ThePEG::RefVector interface with the defaultIfNull() flag set, if a "
      "null pointer is encountered this vector is gone through until an "
      "acceptable object is found in which case the null pointer is replaced "
      "by a pointer to this object.",
      &EventGenerator::theDefaultObjects, 0, true, false, true, false, false);
 
   static Reference<EventGenerator,Strategy> interfaceStrategy
     ("Strategy",
      "An ThePEG::Strategy with additional ThePEG::ParticleData objects to "
      "be used in this run.",
      &EventGenerator::theStrategy, false, false, true, true);
 
   static Reference<EventGenerator,RandomGenerator> interfaceRandomGenerator
     ("RandomNumberGenerator",
      "An ThePEG::RandomGenerator object which should typically interaface to "
      "a CLHEP Random object. This will be the default random number generator "
      "for the run, but individual objects may use their own random generator "
      "if they wish.",
      &EventGenerator::theRandom, true, false, true, false);
 
   static Parameter<EventGenerator,string> interfacePath
     ("Path",
      "The directory where the output files are put.",
      &EventGenerator::thePath, ".", true, false,
       &EventGenerator::setPath, 0, &EventGenerator::defPath);
   interfacePath.directoryType();
 
   static Parameter<EventGenerator,string> interfaceRunName
     ("RunName",
      "The name of this run. This name will be used in the output filenames. "
      "The files wil be placed in the directory specified by the "
      "<interface>Path</interface> parameter"
      "If empty the name of the event generator will be used instead.",
      &EventGenerator::theRunName, "", true, false,
      0, 0, &EventGenerator::name);
 
   static Parameter<EventGenerator,long> interfaceNumberOfEvents
     ("NumberOfEvents",
      "The number of events to be generated in this run. If less than zero, "
      "the number of events is unlimited",
      &EventGenerator::theNumberOfEvents, 1000, -1, Constants::MaxInt,
      true, false, Interface::lowerlim);
 
   static Parameter<EventGenerator,int> interfaceDebugLevel
     ("DebugLevel",
      "The level of debug information sent out to the log file in the run. "
      "Level 0 only gives a limited ammount of warnings and error messages. "
      "Level 1 will print the first few events. "
      "Level 5 will print every event. "
      "Level 9 will print every step in every event.",
      &EventGenerator::theDebugLevel, 0, 0, 9, true, false, true);
 
   static Parameter<EventGenerator,int> interfacePrintEvent
     ("PrintEvent",
      "If the debug level is above zero, print the first 'PrintEvent' events.",
      &EventGenerator::printEvent, 0, 0, 1000, true, false, Interface::lowerlim);
 
   static Parameter<EventGenerator,long> interfaceDumpPeriod
     ("DumpPeriod",
      "If the debug level is above zero, dump the full state of the run every "
      "'DumpPeriod' events. Set it to -1 to disable dumping even in the case of errors.",
      &EventGenerator::dumpPeriod, 0, -1, Constants::MaxInt,
      true, false, Interface::lowerlim);
 
   static Switch<EventGenerator,bool> interfaceKeepAllDumps
     ("KeepAllDumps",
      "Whether all dump files should be kept, labelled by event number.",
      &EventGenerator::keepAllDumps, false, true, false);
   static SwitchOption interfaceKeepAllDumpsYes
     (interfaceKeepAllDumps,
      "Yes",
      "Keep all dump files, labelled by event number.",
      true);
   static SwitchOption interfaceKeepAllDumpsNo
     (interfaceKeepAllDumps,
      "No",
      "Keep only the latest dump file.",
      false);
 
   static Parameter<EventGenerator,long> interfaceDebugEvent
     ("DebugEvent",
      "If the debug level is above zero, step up to the highest debug level "
      "befor event number 'DebugEvent'.",
      &EventGenerator::debugEvent, 0, 0, Constants::MaxInt,
      true, false, Interface::lowerlim);
 
   static Parameter<EventGenerator,int> interfaceMaxWarnings
     ("MaxWarnings",
      "The maximum number of warnings of each type which will be printed.",
      &EventGenerator::maxWarnings,
      10, 1, 100, true, false, Interface::lowerlim);
 
   static Parameter<EventGenerator,int> interfaceMaxErrors
     ("MaxErrors",
      "The maximum number of errors of each type which will be tolerated. "
      "If more errors are reported, the run will be aborted.",
      &EventGenerator::maxErrors,
      10, -1, 100000, true, false, Interface::lowerlim);
 
   static Parameter<EventGenerator,long> interfaceQuickSize
     ("QuickSize",
      "The max absolute id number of particle data objects which are accessed "
      "quickly through a vector indexed by the id number.",
      &EventGenerator::theQuickSize,
      7000, 0, 50000, true, false, Interface::lowerlim);
 
 
   static Command<EventGenerator> interfaceSaveRun
     ("SaveRun",
      "Isolate, initialize and save this event generator to a file, from which "
      "it can be read in and run in another program. If an agument is given "
      "this is used as the run name, otherwise the run name is taken from the "
      "<interface>RunName</interface> parameter.",
      &EventGenerator::doSaveRun, true);
 
 
   static Command<EventGenerator> interfaceMakeRun
     ("MakeRun",
      "Isolate and initialize this event generator and give it a run name. "
      "If no argument is given, the run name is taken from the "
      "<interface>RunName</interface> parameter.",
      &EventGenerator::doMakeRun, true);
 
   interfaceEventHandler.rank(11.0);
   interfaceSaveRun.rank(10.0);
   interfaceMakeRun.rank(9.0);
   interfaceRunName.rank(8.0);
   interfaceNumberOfEvents.rank(7.0);
   interfaceAnalysisHandlers.rank(6.0);
 
 
   static Switch<EventGenerator,bool> interfaceUseStdout
     ("UseStdout",
      "Redirect the logging and output to stdout instead of files.",
      &EventGenerator::useStdout, false, true, false);
   static SwitchOption interfaceUseStdoutYes
     (interfaceUseStdout,
      "Yes",
      "Use stdout instead of log files.",
      true);
   static SwitchOption interfaceUseStdoutNo
     (interfaceUseStdout,
      "No",
      "Use log files.",
      false);
   
 
   static Switch<EventGenerator,int> interfaceLogNonDefault
     ("LogNonDefault",
      "Controls the printout of important interfaces which has been changed from their default values.",
      &EventGenerator::logNonDefault, -1, true, false);
   static SwitchOption interfaceLogNonDefaultYes
     (interfaceLogNonDefault,
      "Yes",
      "Always print changed interfaces.",
      1);
   static SwitchOption interfaceLogNonDefaultOnDebug
     (interfaceLogNonDefault,
      "OnDebug",
      "Only print changed interfaces if debugging is turned on.",
      0);
   static SwitchOption interfaceLogNonDefaultNo
     (interfaceLogNonDefault,
      "No",
      "Don't print changed interfaces.",
      -1);
   interfaceLogNonDefault.setHasDefault(false);
 
   static Switch<EventGenerator,bool> interfaceIntermediateOutput
     ("IntermediateOutput",
      "Modified event number count with the number of events processed so far, "
      "which updates at least every 10000 events, together with the corresponding "
      "intermediate estimate for the cross section plus the integration error.",
      &EventGenerator::theIntermediateOutput, false, true, false);
   static SwitchOption interfaceIntermediateOutputYes
     (interfaceIntermediateOutput,
      "Yes",
      "Show the modified event number count with the number of events processed so far, "
      "plus further information on the intermediate cross section estimate.",
      true);
   static SwitchOption interfaceIntermediateOutputNo
     (interfaceIntermediateOutput,
      "No",
      "Show the usual event number count with the number of events processed so far, "
      "but no further information on the intermediate cross section estimate.",
      false);
 
 }
 
 EGNoPath::EGNoPath(string path) {
   theMessage << "Cannot set the directory path for output files to '" << path
 	     << "' because the directory did not exist and could not be "
 	     << "created.";
   severity(warning);
 }