diff --git a/Hadronization/ClusterFissioner.cc b/Hadronization/ClusterFissioner.cc
--- a/Hadronization/ClusterFissioner.cc
+++ b/Hadronization/ClusterFissioner.cc
@@ -1,2644 +1,2642 @@
 // -*- C++ -*-
 //
 // ClusterFissioner.cc is a part of Herwig - A multi-purpose Monte Carlo event generator
 // Copyright (C) 2002-2019 The Herwig Collaboration
 //
 // Herwig is licenced under version 3 of the GPL, see COPYING for details.
 // Please respect the MCnet academic guidelines, see GUIDELINES for details.
 //
 //
 // Thisk is the implementation of the non-inlined, non-templated member
 // functions of the ClusterFissioner class.
 //
 
 #include "ClusterFissioner.h"
 #include <ThePEG/Interface/ClassDocumentation.h>
 #include <ThePEG/Interface/Reference.h>
 #include <ThePEG/Interface/Parameter.h>
 #include <ThePEG/Interface/Switch.h>
 #include <ThePEG/Persistency/PersistentOStream.h>
 #include <ThePEG/Persistency/PersistentIStream.h>
 #include <ThePEG/PDT/EnumParticles.h>
 #include "Herwig/Utilities/Kinematics.h"
 #include "Cluster.h"
 #include "ThePEG/Repository/UseRandom.h"
 #include "ThePEG/Repository/EventGenerator.h"
 #include <ThePEG/Utilities/DescribeClass.h>
 #include "ThePEG/Interface/ParMap.h"
 
 #include <boost/numeric/ublas/matrix.hpp>
 #include <boost/numeric/ublas/io.hpp>
 #include <boost/numeric/ublas/lu.hpp>
 using namespace Herwig;
 
 DescribeClass<ClusterFissioner,Interfaced>
 describeClusterFissioner("Herwig::ClusterFissioner","Herwig.so");
 
 ClusterFissioner::ClusterFissioner() :
   _clMaxLight(3.35*GeV),
   _clMaxExotic(3.35*GeV),
   _clPowLight(2.0),
   _clPowExotic(2.0),
   _pSplitLight(1.0),
   _pSplitExotic(1.0),
   _phaseSpaceWeights(false),
   _dim(4),
   _fissionCluster(0),
   _kinematicThresholdChoice(0),
   _pwtDIquark(0.0),
   _diquarkClusterFission(0),
   _btClM(1.0*GeV),
   _iopRem(1),
   _kappa(1.0e15*GeV/meter),
   _enhanceSProb(0),
   _m0Fission(2.*GeV),
   _massMeasure(0),
   _probPowFactor(4.0),
   _probShift(0.0),
   _kinThresholdShift(1.0*sqr(GeV)),
   _strictDiquarkKinematics(0),
   _covariantBoost(false),
   _allowHadronFinalStates(2),
   _massSampler(0),
   _phaseSpaceSampler(0),
   _matrixElement(0),
 	_fissionApproach(0)
 {}
 IBPtr ClusterFissioner::clone() const {
   return new_ptr(*this);
 }
 
 IBPtr ClusterFissioner::fullclone() const {
   return new_ptr(*this);
 }
 
 void ClusterFissioner::persistentOutput(PersistentOStream & os) const {
   os << ounit(_clMaxLight,GeV)
      << ounit(_clMaxHeavy,GeV) << ounit(_clMaxExotic,GeV) << _clPowLight << _clPowHeavy
      << _clPowExotic << _pSplitLight
      << _pSplitHeavy << _pSplitExotic
      << _fissionCluster << _fissionPwt
 	 << _pwtDIquark
 	 << _diquarkClusterFission
 	 << ounit(_btClM,GeV)
      << _iopRem  << ounit(_kappa, GeV/meter)
      << _enhanceSProb << ounit(_m0Fission,GeV) << _massMeasure
 		 << _dim << _phaseSpaceWeights
      << _hadronSpectrum << _kinematicThresholdChoice
      << _probPowFactor << _probShift << ounit(_kinThresholdShift,sqr(GeV))
 	 << _strictDiquarkKinematics
 	 << _covariantBoost
 	 << _allowHadronFinalStates
 	 << _massSampler
 	 << _phaseSpaceSampler
 	 << _matrixElement
 	 << _fissionApproach;
 }
 
 void ClusterFissioner::persistentInput(PersistentIStream & is, int) {
   is >> iunit(_clMaxLight,GeV)
      >> iunit(_clMaxHeavy,GeV) >> iunit(_clMaxExotic,GeV) >> _clPowLight >> _clPowHeavy
      >> _clPowExotic >> _pSplitLight
      >> _pSplitHeavy >> _pSplitExotic
      >> _fissionCluster >> _fissionPwt
 	 >> _pwtDIquark
 	 >> _diquarkClusterFission
      >> iunit(_btClM,GeV)
 	 >> _iopRem >> iunit(_kappa, GeV/meter)
      >> _enhanceSProb >> iunit(_m0Fission,GeV) >> _massMeasure
 		 >> _dim >> _phaseSpaceWeights
      >> _hadronSpectrum >> _kinematicThresholdChoice
      >> _probPowFactor >> _probShift >> iunit(_kinThresholdShift,sqr(GeV))
 	 >> _strictDiquarkKinematics
 	 >> _covariantBoost
 	 >> _allowHadronFinalStates
 	 >> _massSampler
 	 >> _phaseSpaceSampler
 	 >> _matrixElement
 	 >> _fissionApproach;
 }
 
 void ClusterFissioner::doinit() {
   Interfaced::doinit();
   for ( const long& id : spectrum()->heavyHadronizingQuarks() ) {
     if ( _pSplitHeavy.find(id) == _pSplitHeavy.end() ||
 	 _clPowHeavy.find(id) == _clPowHeavy.end() ||
 	 _clMaxHeavy.find(id) == _clMaxHeavy.end() )
       throw InitException() << "not all parameters have been set for heavy quark cluster fission";
   }
   // for default Pwts not needed to initialize
   if (_fissionCluster==0) return;  
   for ( const long& id : spectrum()->lightHadronizingQuarks() ) {
 	  if ( _fissionPwt.find(id) == _fissionPwt.end() )
 		  // check that all relevant weights are set
 		  throw InitException() << "fission weights for light quarks have not been set";
   }
   /*
   // Not needed since we set Diquark weights from quark weights
   for ( const long& id : spectrum()->lightHadronizingDiquarks() ) {
 	  if ( _fissionPwt.find(id) == _fissionPwt.end() )
 		  throw InitException() << "fission weights for light diquarks have not been set";
   }*/
   double pwtDquark=_fissionPwt.find(ParticleID::d)->second;
   double pwtUquark=_fissionPwt.find(ParticleID::u)->second;
   double pwtSquark=_fissionPwt.find(ParticleID::s)->second;
   // ERROR: TODO makeDiquarkID is protected function ?
   // _fissionPwt[spectrum()->makeDiquarkID(ParticleID::d,ParticleID::d,3)] =       _pwtDIquark * pwtDquark * pwtDquark;
   // _fissionPwt[spectrum()->makeDiquarkID(ParticleID::u,ParticleID::d,1)] = 0.5 * _pwtDIquark * pwtUquark * pwtDquark;
   // _fissionPwt[spectrum()->makeDiquarkID(ParticleID::u,ParticleID::u,3)] =       _pwtDIquark * pwtUquark * pwtUquark;
   // _fissionPwt[spectrum()->makeDiquarkID(ParticleID::s,ParticleID::d,1)] = 0.5 * _pwtDIquark * pwtSquark * pwtDquark;
   // _fissionPwt[spectrum()->makeDiquarkID(ParticleID::s,ParticleID::u,1)] = 0.5 * _pwtDIquark * pwtSquark * pwtUquark;
   // _fissionPwt[spectrum()->makeDiquarkID(ParticleID::s,ParticleID::s,3)] =       _pwtDIquark * pwtSquark * pwtSquark;
   // TODO better solution for this magic  number alternative
   _fissionPwt[1103] =       _pwtDIquark * pwtDquark * pwtDquark;
   _fissionPwt[2101] = 0.5 * _pwtDIquark * pwtUquark * pwtDquark;
   _fissionPwt[2203] =       _pwtDIquark * pwtUquark * pwtUquark;
   _fissionPwt[3101] = 0.5 * _pwtDIquark * pwtSquark * pwtDquark;
   _fissionPwt[3201] = 0.5 * _pwtDIquark * pwtSquark * pwtUquark;
   _fissionPwt[3303] =       _pwtDIquark * pwtSquark * pwtSquark;
 }
 
 void ClusterFissioner::Init() {
 
   static ClassDocumentation<ClusterFissioner> documentation
     ("Class responsibles for chopping up the clusters");
 
   static Reference<ClusterFissioner,HadronSpectrum> interfaceHadronSpectrum
     ("HadronSpectrum",
      "Set the Hadron spectrum for this cluster fissioner.",
      &ClusterFissioner::_hadronSpectrum, false, false, true, false);
 
   // ClMax for light, Bottom, Charm and exotic (e.g. Susy) quarks
   static Parameter<ClusterFissioner,Energy>
     interfaceClMaxLight ("ClMaxLight","cluster max mass for light quarks (unit [GeV])",
                     &ClusterFissioner::_clMaxLight, GeV, 3.35*GeV, ZERO, 10.0*GeV,
 		    false,false,false);  
   static ParMap<ClusterFissioner,Energy> interfaceClMaxHeavy
     ("ClMaxHeavy",
      "ClMax for heavy quarkls",
      &ClusterFissioner::_clMaxHeavy, GeV, -1, 3.35*GeV, ZERO, 10.0*GeV,
      false, false, Interface::upperlim);
   static Parameter<ClusterFissioner,Energy>
     interfaceClMaxExotic ("ClMaxExotic","cluster max mass  for exotic quarks (unit [GeV])",
                     &ClusterFissioner::_clMaxExotic, GeV, 3.35*GeV, ZERO, 10.0*GeV,
 		    false,false,false);
 
  // ClPow for light, Bottom, Charm and exotic (e.g. Susy) quarks
  static Parameter<ClusterFissioner,double>
     interfaceClPowLight ("ClPowLight","cluster mass exponent for light quarks",
                     &ClusterFissioner::_clPowLight, 0, 2.0, 0.0, 10.0,false,false,false); 
   static ParMap<ClusterFissioner,double> interfaceClPowHeavy
     ("ClPowHeavy",
      "ClPow for heavy quarks",
      &ClusterFissioner::_clPowHeavy, -1, 1.0, 0.0, 10.0,
      false, false, Interface::upperlim); 
  static Parameter<ClusterFissioner,double>
     interfaceClPowExotic ("ClPowExotic","cluster mass exponent for exotic quarks",
                     &ClusterFissioner::_clPowExotic, 0, 2.0, 0.0, 10.0,false,false,false);
 
  // PSplit for light, Bottom, Charm and exotic (e.g. Susy) quarks
   static Parameter<ClusterFissioner,double>
     interfacePSplitLight ("PSplitLight","cluster mass splitting param for light quarks",
                     &ClusterFissioner::_pSplitLight, 0, 1.0, 0.0, 10.0,false,false,false);
   static ParMap<ClusterFissioner,double> interfacePSplitHeavy
     ("PSplitHeavy",
      "PSplit for heavy quarks",
      &ClusterFissioner::_pSplitHeavy, -1, 1.0, 0.0, 10.0,
      false, false, Interface::upperlim);
  static Parameter<ClusterFissioner,double>
     interfacePSplitExotic ("PSplitExotic","cluster mass splitting param for exotic quarks",
                     &ClusterFissioner::_pSplitExotic, 0, 1.0, 0.0, 10.0,false,false,false);
 
+
   static Switch<ClusterFissioner,int> interfaceFission
     ("Fission",
      "Option for different Fission options",
-     &ClusterFissioner::_fissionCluster, 0, false, false);
+     &ClusterFissioner::_fissionCluster, 1, false, false);
   static SwitchOption interfaceFissionDefault
     (interfaceFission,
      "Default",
      "Normal cluster fission which depends on the hadron spectrum class.",
      0);
   static SwitchOption interfaceFissionNew
     (interfaceFission,
      "New",
      "Alternative cluster fission which does not depend on the hadron spectrum class",
      1);
 
   static Switch<ClusterFissioner,int> interfaceFissionApproach
     ("FissionApproach",
      "Option for different Cluster Fission approaches",
      &ClusterFissioner::_fissionApproach, 0, false, false);
   static SwitchOption interfaceFissionApproachDefault
     (interfaceFissionApproach,
      "Default",
      "Default Herwig-7.3.0 cluster fission without restructuring",
      0);
   static SwitchOption interfaceFissionApproachNew
     (interfaceFissionApproach,
      "New",
      "New cluster fission which allows to choose MassSampler"
 		 ", PhaseSpaceSampler and MatrixElement",
      1);
 
   // Switch C->H1,C2 C->H1,H2 on or off
   static Switch<ClusterFissioner,int> interfaceAllowHadronFinalStates
     ("AllowHadronFinalStates",
      "Option for allowing hadron final states of cluster fission",
      &ClusterFissioner::_allowHadronFinalStates, 0, false, false);
   static SwitchOption interfaceAllowHadronFinalStatesNone
     (interfaceAllowHadronFinalStates,
      "None",
      "Option for disabling hadron final states of cluster fission",
      0);
   static SwitchOption interfaceAllowHadronFinalStatesSemiHadronicOnly
     (interfaceAllowHadronFinalStates,
      "SemiHadronicOnly",
      "Option for allowing hadron final states of cluster fission of type C->H1,C2 "
 		 "(NOT YET USABLE WITH MatrixElement only use option None)",
      1);
   static SwitchOption interfaceAllowHadronFinalStatesAll
     (interfaceAllowHadronFinalStates,
      "All",
      "Option for allowing hadron final states of cluster fission "
 		 "of type C->H1,C2 or C->H1,H2 "
 		 "(NOT YET USABLE WITH MatrixElement only use option None)",
      2);
 
   // Mass Sampler Switch
   static Switch<ClusterFissioner,int> interfaceMassSampler
     ("MassSampler",
      "Option for different Mass sampling options",
      &ClusterFissioner::_massSampler, 0, false, false);
   static SwitchOption interfaceMassSamplerDefault
     (interfaceMassSampler,
      "Default",
      "Choose H7.2.3 default mass sampling using PSplitX",
      0);
   static SwitchOption interfaceMassSamplerUniform
     (interfaceMassSampler,
      "Uniform",
      "Choose Uniform Mass sampling in M1,M2 space",
      1);
   static SwitchOption interfaceMassSamplerFlatPhaseSpace
     (interfaceMassSampler,
      "FlatPhaseSpace",
      "Choose Flat Phase Space sampling of Mass in M1,M2 space",
      2);
   static SwitchOption interfaceMassSampleSoftMEPheno
     (interfaceMassSampler,
      "SoftMEPheno",
      "Choose skewed Phase Space sampling of Masses in M1,M2 space "
 	 "for greater efficiency in soft matrix element sampling",
      3);
 
   // Phase Space Sampler Switch
   static Switch<ClusterFissioner,int> interfacePhaseSpaceSampler
     ("PhaseSpaceSampler",
      "Option for different phase space sampling options",
      &ClusterFissioner::_phaseSpaceSampler, 0, false, false);
   static SwitchOption interfacePhaseSpaceSamplerDefault
     (interfacePhaseSpaceSampler,
      "FullyAligned",
      "Herwig H7.2.3 default Cluster fission of all partons "
 	 "aligned to the relative momentum of the mother cluster",
      0);
   static SwitchOption interfacePhaseSpaceSamplerAlignedIsotropic
     (interfacePhaseSpaceSampler,
      "AlignedIsotropic",
      "Aligned Clusters but isotropic partons in their respective rest frame",
      1);
   static SwitchOption interfacePhaseSpaceSamplerFullyIsotropic
     (interfacePhaseSpaceSampler,
      "FullyIsotropic",
      "Isotropic Clusters and isotropic partons in their respective rest frame "
 	 "NOTE: Testing only!!",
      2);
 
   // Matrix Element Choice Switch
   static Switch<ClusterFissioner,int> interfaceMatrixElement
     ("MatrixElement",
      "Option for different Matrix Element options",
      &ClusterFissioner::_matrixElement, 0, false, false);
   static SwitchOption interfaceMatrixElementDefault
     (interfaceMatrixElement,
      "Default",
      "Choose trivial matrix element i.e. whatever comes from the mass and "
 	 "phase space sampling",
      0);
   static SwitchOption interfaceMatrixElementSoftQQbar
     (interfaceMatrixElement,
      "SoftQQbar",
 	 "Choose Soft q1,q2->q1,q2,g*->q1,q2,q,qbar matrix element",
      1);
 
   static Switch<ClusterFissioner,int> interfaceDiquarkClusterFission
     ("DiquarkClusterFission",
      "Allow clusters to fission to 1 or 2 diquark Clusters",
      &ClusterFissioner::_diquarkClusterFission, 0, false, false);
   static SwitchOption interfaceDiquarkClusterFissionAll
 	(interfaceDiquarkClusterFission,
      "All",
      "Allow diquark clusters and baryon clusters to fission to new diquark Clusters",
      2);
   static SwitchOption interfaceDiquarkClusterFissionOnlyBaryonClusters
 	(interfaceDiquarkClusterFission,
      "OnlyBaryonClusters",
      "Allow only baryon clusters to fission to new diquark Clusters",
      1);
   static SwitchOption interfaceDiquarkClusterFissionNo
     (interfaceDiquarkClusterFission,
      "No",
      "Don't allow clusters to fission to new diquark Clusters",
      0);
 
   static ParMap<ClusterFissioner,double> interfaceFissionPwt
     ("FissionPwt",
      "The weights for quarks in the fission process.",
      &ClusterFissioner::_fissionPwt, -1, 1.0, 0.0, 10.0,
      false, false, Interface::upperlim);
 
-
   static Switch<ClusterFissioner,int> interfaceRemnantOption
     ("RemnantOption",
      "Option for the treatment of remnant clusters",
      &ClusterFissioner::_iopRem, 1, false, false);
   static SwitchOption interfaceRemnantOptionSoft
     (interfaceRemnantOption,
      "Soft",
      "Both clusters produced in the fission of the beam cluster"
      " are treated as soft clusters.",
      0);
   static SwitchOption interfaceRemnantOptionHard
     (interfaceRemnantOption,
      "Hard",
      "Only the cluster containing the remnant is treated as a soft cluster.",
      1);
   static SwitchOption interfaceRemnantOptionVeryHard
     (interfaceRemnantOption,
      "VeryHard",
      "Even remnant clusters are treated as hard, i.e. all clusters the same",
      2);
 
   static Parameter<ClusterFissioner,Energy> interfaceBTCLM
     ("SoftClusterFactor",
      "Parameter for the mass spectrum of remnant clusters",
      &ClusterFissioner::_btClM, GeV, 1.*GeV, 0.1*GeV, 10.0*GeV,
      false, false, Interface::limited);
 
 
   static Parameter<ClusterFissioner,Tension> interfaceStringTension
     ("StringTension",
      "String tension used in vertex displacement calculation",
      &ClusterFissioner::_kappa, GeV/meter,
      1.0e15*GeV/meter, ZERO, ZERO,
      false, false, Interface::lowerlim);
 
   static Switch<ClusterFissioner,int> interfaceEnhanceSProb
     ("EnhanceSProb",
      "Option for enhancing strangeness",
      &ClusterFissioner::_enhanceSProb, 0, false, false);
   static SwitchOption interfaceEnhanceSProbNo
     (interfaceEnhanceSProb,
      "No",
      "No strangeness enhancement.",
      0);
   static SwitchOption interfaceEnhanceSProbScaled
     (interfaceEnhanceSProb,
      "Scaled",
      "Scaled strangeness enhancement",
      1);
   static SwitchOption interfaceEnhanceSProbExponential
     (interfaceEnhanceSProb,
      "Exponential",
      "Exponential strangeness enhancement",
      2);
 
    static Switch<ClusterFissioner,int> interfaceMassMeasure
      ("MassMeasure",
       "Option to use different mass measures",
       &ClusterFissioner::_massMeasure,0,false,false);
    static SwitchOption interfaceMassMeasureMass
      (interfaceMassMeasure,
       "Mass",
       "Mass Measure",
       0);
    static SwitchOption interfaceMassMeasureLambda
      (interfaceMassMeasure,
       "Lambda",
       "Lambda Measure",
       1);
 
   static Parameter<ClusterFissioner,Energy> interfaceFissionMassScale
     ("FissionMassScale",
      "Cluster fission mass scale",
      &ClusterFissioner::_m0Fission, GeV, 2.0*GeV, 0.1*GeV, 50.*GeV,
      false, false, Interface::limited);
 
   static Parameter<ClusterFissioner,double> interfaceProbPowFactor
      ("ProbablityPowerFactor",
       "Power factor in ClausterFissioner bell probablity function",
       &ClusterFissioner::_probPowFactor, 2.0, 1.0, 20.0,
       false, false, Interface::limited);
 
   static Parameter<ClusterFissioner,double> interfaceProbShift
      ("ProbablityShift",
       "Shifts from the center in ClausterFissioner bell probablity function",
       &ClusterFissioner::_probShift, 0.0, -10.0, 10.0,
       false, false, Interface::limited);
 
   static Parameter<ClusterFissioner,Energy2> interfaceKineticThresholdShift
      ("KineticThresholdShift",
       "Shifts from the kinetic threshold in ClausterFissioner",
       &ClusterFissioner::_kinThresholdShift, sqr(GeV), 0.*sqr(GeV), -10.0*sqr(GeV), 10.0*sqr(GeV),
       false, false, Interface::limited);
 
   static Switch<ClusterFissioner,int> interfaceKinematicThreshold
     ("KinematicThreshold",
      "Option for using static or dynamic kinematic thresholds in cluster splittings",
      &ClusterFissioner::_kinematicThresholdChoice, 0, false, false);
   static SwitchOption interfaceKinematicThresholdStatic
     (interfaceKinematicThreshold,
      "Static",
      "Set static kinematic thresholds for cluster splittings.",
      0);
   static SwitchOption interfaceKinematicThresholdDynamic
     (interfaceKinematicThreshold,
      "Dynamic",
      "Set dynamic kinematic thresholds for cluster splittings.",
      1);
 
 
   static Switch<ClusterFissioner,bool> interfaceCovariantBoost
     ("CovariantBoost",
      "Use single Covariant Boost for Cluster Fission",
      &ClusterFissioner::_covariantBoost, false, false, false);
   static SwitchOption interfaceCovariantBoostYes
     (interfaceCovariantBoost,
      "Yes",
      "Use Covariant boost",
      true);
   static SwitchOption interfaceCovariantBoostNo
     (interfaceCovariantBoost,
      "No",
      "Do NOT use Covariant boost",
      false);
   
 
   static Switch<ClusterFissioner,int> interfaceStrictDiquarkKinematics
     ("StrictDiquarkKinematics",
      "Option for selecting different selection criterions of diquarks for ClusterFission",
      &ClusterFissioner::_strictDiquarkKinematics, 0, false, false);
   static SwitchOption interfaceStrictDiquarkKinematicsLoose
     (interfaceStrictDiquarkKinematics,
      "Loose",
      "No kinematic threshold for diquark selection except for Mass bigger than 2 baryons",
      0);
   static SwitchOption interfaceStrictDiquarkKinematicsStrict
     (interfaceStrictDiquarkKinematics,
      "Strict",
      "Resulting clusters are at least as heavy as 2 lightest baryons",
      1);
 
   static Parameter<ClusterFissioner,double> interfacePwtDIquark
      ("PwtDIquark",
       "specific probability for choosing a d diquark",
       &ClusterFissioner::_pwtDIquark, 0.0, 0.0, 10.0,
       false, false, Interface::limited);
 
   static Switch<ClusterFissioner,bool> interfacePhaseSpaceWeights
     ("PhaseSpaceWeights",
      "Include phase space weights.",
      &ClusterFissioner::_phaseSpaceWeights, false, false, false);
   static SwitchOption interfacePhaseSpaceWeightsYes
     (interfacePhaseSpaceWeights,
      "Yes",
      "Do include the effect of cluster fission phase space",
      true);
   static SwitchOption interfacePhaseSpaceWeightsNo
     (interfacePhaseSpaceWeights,
      "No",
      "Do not include the effect of cluster phase space",
      false);
 
   static Parameter<ClusterFissioner,double>
     interfaceDim ("Dimension","Dimension in which phase space weights are calculated",
 		  &ClusterFissioner::_dim, 0, 4.0, 0.0, 10.0,false,false,false);
 
 }
 
 tPVector ClusterFissioner::fission(ClusterVector & clusters, bool softUEisOn) {
   // return if no clusters
   if (clusters.empty()) return tPVector();
 
   /*****************
    * Loop over the (input) collection of cluster pointers, and store in
    * the vector  splitClusters  all the clusters that need to be split
    * (these are beam clusters, if soft underlying event is off, and
    *  heavy non-beam clusters).
    ********************/
 
   stack<ClusterPtr> splitClusters;
   for(ClusterVector::iterator it = clusters.begin() ;
       it != clusters.end() ; ++it) {
     /**************
      * Skip 3-component clusters that have been redefined (as 2-component
      * clusters) or not available clusters. The latter check is indeed
      * redundant now, but it is used for possible future extensions in which,
      * for some reasons, some of the clusters found by ClusterFinder are tagged
      * straight away as not available.
      **************/
     if((*it)->isRedefined() || !(*it)->isAvailable()) continue;
     // if the cluster is a beam cluster add it to the vector of clusters
     // to be split or if it is heavy
-		// TODO maybe BeamClusters must not necessarily be split since can be very light
-		// 			i.e. also lighter than the lightest constituents one can make of those
     if((*it)->isBeamCluster() || isHeavy(*it)) splitClusters.push(*it);
   }
   tPVector finalhadrons;
   cut(splitClusters, clusters, finalhadrons, softUEisOn);
   return finalhadrons;
 }
 
 void ClusterFissioner::cut(stack<ClusterPtr> & clusterStack,
    			   ClusterVector &clusters, tPVector & finalhadrons,
 			   bool softUEisOn) {
   /**************************************************
    * This method does the splitting of the cluster pointed by  cluPtr
    * and "recursively" by all of its cluster children, if heavy. All of these
    * new children clusters are added (indeed the pointers to them) to the
    * collection of cluster pointers  collecCluPtr. The method works as follows.
    * Initially the vector vecCluPtr contains just the input pointer to the
    * cluster to be split. Then it will be filled "recursively" by all
    * of the cluster's children that are heavy enough to require, in their turn,
    * to be split. In each loop, the last element of the vector vecCluPtr is
    * considered (only once because it is then removed from the vector).
    * This approach is conceptually recursive, but avoid the overhead of
    * a concrete recursive function. Furthermore it requires minimal changes
    * in the case that the fission of an heavy cluster could produce more
    * than two cluster children as assumed now.
    *
    * Draw the masses: for normal, non-beam clusters a power-like mass dist
    * is used, whereas for beam clusters a fast-decreasing exponential mass
    * dist is used instead (to avoid many iterative splitting which could
    * produce an unphysical large transverse energy from a supposed soft beam
    * remnant process).
    ****************************************/
   // Here we recursively loop over clusters in the stack and cut them
   while (!clusterStack.empty()) {
     // take the last element of the vector
     ClusterPtr iCluster = clusterStack.top(); clusterStack.pop();
     // split it
     cutType ct = iCluster->numComponents() == 2 ?
       cutTwo(iCluster, finalhadrons, softUEisOn) :
       cutThree(iCluster, finalhadrons, softUEisOn);
 
     // There are cases when we don't want to split, even if it fails mass test
     if(!ct.first.first || !ct.second.first) {
       // if an unsplit beam cluster leave if for the underlying event
       if(iCluster->isBeamCluster() && softUEisOn)
 	iCluster->isAvailable(false);
       continue;
     }
     // check if clusters
     ClusterPtr one = dynamic_ptr_cast<ClusterPtr>(ct.first.first);
     ClusterPtr two = dynamic_ptr_cast<ClusterPtr>(ct.second.first);
     // is a beam cluster must be split into two clusters
     if(iCluster->isBeamCluster() && (!one||!two) && softUEisOn) {
       iCluster->isAvailable(false);
       continue;
     }
 
     // There should always be a intermediate quark(s) from the splitting
     assert(ct.first.second && ct.second.second);
     /// \todo sort out motherless quark pairs here. Watch out for 'quark in final state' errors
     iCluster->addChild(ct.first.first);
     //    iCluster->addChild(ct.first.second);
     //    ct.first.second->addChild(ct.first.first);
 
     iCluster->addChild(ct.second.first);
     //    iCluster->addChild(ct.second.second);
     //    ct.second.second->addChild(ct.second.first);
 
     // Sometimes the clusters decay C -> H + C' or C -> H + H' rather then C -> C' + C''
     if(one) {
       clusters.push_back(one);
       if(one->isBeamCluster() && softUEisOn)
 	one->isAvailable(false);
       if(isHeavy(one) && one->isAvailable())
 	clusterStack.push(one);
     }
     if(two) {
       clusters.push_back(two);
       if(two->isBeamCluster() && softUEisOn)
 	two->isAvailable(false);
       if(isHeavy(two) && two->isAvailable())
 	clusterStack.push(two);
     }
   }
 }
 ClusterFissioner::cutType
 ClusterFissioner::cutTwo(ClusterPtr & cluster, tPVector & finalhadrons,
 			 bool softUEisOn) {
 	switch (_fissionApproach)
 	{
 		case 0:
 			return cutTwoDefault(cluster, finalhadrons, softUEisOn);
 			break;
 		case 1:
 			return cutTwoNew(cluster, finalhadrons, softUEisOn);
 			break;
 		default:
 			assert(false);
 	}
 }
 
 ClusterFissioner::cutType
 ClusterFissioner::cutTwoDefault(ClusterPtr & cluster, tPVector & finalhadrons,
 			 bool softUEisOn) {
   // need to make sure only 2-cpt clusters get here
   assert(cluster->numComponents() == 2);
   tPPtr ptrQ1 = cluster->particle(0);
   tPPtr ptrQ2 = cluster->particle(1);
   Energy Mc = cluster->mass();
   assert(ptrQ1);
   assert(ptrQ2);
 
   // And check if those particles are from a beam remnant
   bool rem1 = cluster->isBeamRemnant(0);
   bool rem2 = cluster->isBeamRemnant(1);
   // workout which distribution to use
   bool soft1(false),soft2(false);
   switch (_iopRem) {
   case 0:
     soft1 = rem1 || rem2;
     soft2 = rem2 || rem1;
     break;
   case 1:
     soft1 = rem1;
     soft2 = rem2;
     break;
   }
   // Initialization for the exponential ("soft") mass distribution.
   static const int max_loop = 1000;
   int counter = 0;
   Energy Mc1 = ZERO, Mc2 = ZERO,m1=ZERO,m2=ZERO,m=ZERO;
   tcPDPtr toHadron1, toHadron2;
   PPtr newPtr1 = PPtr ();
   PPtr newPtr2 = PPtr ();
   bool succeeded = false;
   Lorentz5Momentum pClu1, pClu2, pQ1, pQone, pQtwo, pQ2;
   do
     {
       succeeded = false;
       ++counter;
       // get a flavour for the qqbar pair
       drawNewFlavour(newPtr1,newPtr2,cluster);
       // check for right ordering
       assert (ptrQ2);
       assert (newPtr2);
       assert (ptrQ2->dataPtr());
       assert (newPtr2->dataPtr());
       if(cantMakeHadron(ptrQ1, newPtr1) || cantMakeHadron(ptrQ2, newPtr2)) {
 	swap(newPtr1, newPtr2);
 	// check again
 	if(cantMakeHadron(ptrQ1, newPtr1) || cantMakeHadron(ptrQ2, newPtr2)) {
 	  throw Exception()
 	    << "ClusterFissioner cannot split the cluster ("
 	    << ptrQ1->PDGName() << ' ' << ptrQ2->PDGName()
 	    << ") into hadrons.\n" << Exception::runerror;
 	}
       }
       // Check that new clusters can produce particles and there is enough
       // phase space to choose the drawn flavour
       m1 = ptrQ1->data().constituentMass();
       m2 = ptrQ2->data().constituentMass();
       m  = newPtr1->data().constituentMass();
       // Do not split in the case there is no phase space available
       if(Mc <  m1+m + m2+m) continue;
 
       pQ1.setMass(m1);
       pQone.setMass(m);
       pQtwo.setMass(m);
       pQ2.setMass(m2);
 
-      // pair<Energy,Energy> res = drawNewMasses(Mc, soft1, soft2, pClu1, pClu2,
-								// ptrQ1, pQ1, newPtr1, pQone,
-								// newPtr2, pQtwo, ptrQ2, pQ2);
-      drawNewMasses(Mc, soft1, soft2, pClu1, pClu2,
-					      ptrQ1, pQ1, newPtr1, pQone,
-					      newPtr2, pQtwo, ptrQ2, pQ2);
+      //  pair<Energy,Energy> res = drawNewMasses(Mc, soft1, soft2, pClu1, pClu2,
+	  //				      ptrQ1, pQ1, newPtr1, pQone,
+	  //				      newPtr2, pQtwo, ptrQ2, pQ2);
+      drawNewMasses(Mc, soft1, soft2, pClu1, pClu2, ptrQ1, pQ1, newPtr1, pQone, newPtr2, pQtwo, ptrQ2, pQ2);
 
       // derive the masses of the children
       Mc1 = pClu1.mass();
       Mc2 = pClu2.mass();
       // static kinematic threshold
       if(_kinematicThresholdChoice == 0) {
         if(Mc1 < m1+m || Mc2 < m+m2 || Mc1+Mc2 > Mc) continue;
       // dynamic kinematic threshold
       } else if(_kinematicThresholdChoice == 1) {
         bool C1 = ( sqr(Mc1) )/( sqr(m1) + sqr(m) + _kinThresholdShift ) < 1.0 ? true : false;
         bool C2 = ( sqr(Mc2) )/( sqr(m2) + sqr(m) + _kinThresholdShift ) < 1.0 ? true : false;
         bool C3 = ( sqr(Mc1) + sqr(Mc2) )/( sqr(Mc) ) > 1.0 ? true : false;
 
         if( C1 || C2 || C3 ) continue;
       }
 
       if ( _phaseSpaceWeights ) {
 	if ( phaseSpaceVeto(Mc,Mc1,Mc2,m,m1,m2) )
 	  continue;
       }
 
       /**************************
        * New (not present in Fortran Herwig):
        * check whether the fragment masses  Mc1  and  Mc2  are above the
        * threshold for the production of the lightest pair of hadrons with the
        * right flavours. If not, then set by hand the mass to the lightest
        * single hadron with the right flavours, in order to solve correctly
        * the kinematics, and (later in this method) create directly such hadron
        * and add it to the children hadrons of the cluster that undergoes the
        * fission (i.e. the one pointed by iCluPtr). Notice that in this special
        * case, the heavy cluster that undergoes the fission has one single
        * cluster child and one single hadron child. We prefer this approach,
        * rather than to create a light cluster, with the mass set equal to
        * the lightest hadron, and let then the class LightClusterDecayer to do
        * the job to decay it to that single hadron, for two reasons:
        * First, because the sum of the masses of the two constituents can be,
        * in this case, greater than the mass of that hadron, hence it would
        * be impossible to solve the kinematics for such two components, and
        * therefore we would have a cluster whose components are undefined.
        * Second, the algorithm is faster, because it avoids the reshuffling
        * procedure that would be necessary if we used LightClusterDecayer
        * to decay the light cluster to the lightest hadron.
        ****************************/
       // override chosen masses if needed
       toHadron1 = _hadronSpectrum->chooseSingleHadron(ptrQ1->dataPtr(), newPtr1->dataPtr(),Mc1);
       if(toHadron1) { Mc1 = toHadron1->mass(); pClu1.setMass(Mc1); }
       toHadron2 = _hadronSpectrum->chooseSingleHadron(ptrQ2->dataPtr(), newPtr2->dataPtr(),Mc2);
       if(toHadron2) { Mc2 = toHadron2->mass(); pClu2.setMass(Mc2); }
       // if a beam cluster not allowed to decay to hadrons
       if(cluster->isBeamCluster() && (toHadron1||toHadron2) && softUEisOn)
 	continue;
       // Check if the decay kinematics is still possible: if not then
       // force the one-hadron decay for the other cluster as well.
       if(Mc1 + Mc2  >  Mc) {
 	if(!toHadron1) {
 	  toHadron1 = _hadronSpectrum->chooseSingleHadron(ptrQ1->dataPtr(), newPtr1->dataPtr(),Mc-Mc2);
 	  if(toHadron1) { Mc1 = toHadron1->mass(); pClu1.setMass(Mc1); }
 	}
 	else if(!toHadron2) {
 	  toHadron2 = _hadronSpectrum->chooseSingleHadron(ptrQ2->dataPtr(), newPtr2->dataPtr(),Mc-Mc1);
 	  if(toHadron2) { Mc2 = toHadron2->mass(); pClu2.setMass(Mc2); }
 	}
       }
       succeeded = (Mc >= Mc1+Mc2);
     }
   while (!succeeded && counter < max_loop);
 
   if(counter >= max_loop) {
     static const PPtr null = PPtr();
     return cutType(PPair(null,null),PPair(null,null));
   }
 
   // Determined the (5-components) momenta (all in the LAB frame)
   Lorentz5Momentum pClu = cluster->momentum(); // known
   Lorentz5Momentum p0Q1 = ptrQ1->momentum(); // known (mom Q1 before fission)
   calculateKinematics(pClu,p0Q1,toHadron1,toHadron2,
 		      pClu1,pClu2,pQ1,pQone,pQtwo,pQ2);
 
   /******************
    * The previous methods have determined the kinematics and positions
    * of C -> C1 + C2.
    * In the case that one of the two product is light, that means either
    * decayOneHadronClu1 or decayOneHadronClu2 is true, then the momenta
    * of the components of that light product have not been determined,
    * and a (light) cluster will not be created: the heavy father cluster
    * decays, in this case, into a single (not-light) cluster and a
    * single hadron. In the other, "normal", cases the father cluster
    * decays into two clusters, each of which has well defined components.
    * Notice that, in the case of components which point to particles, the
    * momenta of the components is properly set to the new values, whereas
    * we do not change the momenta of the pointed particles, because we
    * want to keep all of the information (that is the new momentum of a
    * component after the splitting, which is contained in the _momentum
    * member of the Component class, and the (old) momentum of that component
    * before the splitting, which is contained in the momentum of the
    * pointed particle). Please not make confusion of this only apparent
    * inconsistency!
    ********************/
   LorentzPoint posC,pos1,pos2;
   posC = cluster->vertex();
   calculatePositions(pClu, posC, pClu1, pClu2, pos1, pos2);
   cutType rval;
   if(toHadron1) {
     rval.first = produceHadron(toHadron1, newPtr1, pClu1, pos1);
     finalhadrons.push_back(rval.first.first);
   }
   else {
     rval.first = produceCluster(ptrQ1, newPtr1, pClu1, pos1, pQ1, pQone, rem1);
   }
   if(toHadron2) {
     rval.second = produceHadron(toHadron2, newPtr2, pClu2, pos2);
     finalhadrons.push_back(rval.second.first);
   }
   else {
     rval.second = produceCluster(ptrQ2, newPtr2, pClu2, pos2, pQ2, pQtwo, rem2);
   }
   return rval;
 }
 
 ClusterFissioner::cutType
 ClusterFissioner::cutTwoNew(ClusterPtr & cluster, tPVector & finalhadrons,
 			 bool softUEisOn) {
   // need to make sure only 2-cpt clusters get here
   assert(cluster->numComponents() == 2);
   tPPtr ptrQ1 = cluster->particle(0);
   tPPtr ptrQ2 = cluster->particle(1);
 	Energy Mc = cluster->mass();
 	if ( Mc < spectrum()->massLightestHadronPair(ptrQ1->dataPtr(),ptrQ2->dataPtr())) {
 		static const PPtr null = PPtr();
 		return cutType(PPair(null,null),PPair(null,null));
 	}
   assert(ptrQ1);
   assert(ptrQ2);
 
   // And check if those particles are from a beam remnant
   bool rem1 = cluster->isBeamRemnant(0);
   bool rem2 = cluster->isBeamRemnant(1);
   // workout which distribution to use
   bool soft1(false),soft2(false);
   switch (_iopRem) {
   case 0:
     soft1 = rem1 || rem2;
     soft2 = rem2 || rem1;
     break;
   case 1:
     soft1 = rem1;
     soft2 = rem2;
     break;
   }
   // Initialization for the exponential ("soft") mass distribution.
   static const int max_loop_ME= 5000000;
   int counter_MEtry = 0;
   Energy Mc1 = ZERO;
 	Energy Mc2 = ZERO;
 	Energy m=ZERO;
 	Energy m1 = ptrQ1->data().constituentMass();
 	Energy m2 = ptrQ2->data().constituentMass();
 	Energy mMin = getParticleData(ParticleID::d)->constituentMass();
 	// TODO get rid of magic number
 	double eps = 0.1;
 	// Minimal threshold for non-zero Mass PhaseSpace
 	if ( Mc < (1.0+eps)*(m1 + m2 + 2*mMin )) {
 		static const PPtr null = PPtr();
 		return cutType(PPair(null,null),PPair(null,null));
 	}
   tcPDPtr toHadron1, toHadron2;
   PPtr newPtr1 = PPtr ();
   PPtr newPtr2 = PPtr ();
   Lorentz5Momentum pClu1, pClu2, pQ1, pQone, pQtwo, pQ2;
 	Lorentz5Momentum pClu = cluster->momentum(); // known
 	Lorentz5Momentum p0Q1 = ptrQ1->momentum(); // known (mom Q1 before fission)
 	Lorentz5Momentum p0Q2 = ptrQ2->momentum(); // known (mom Q2 before fission)
 	// where to return to in case of rejected sample
 	enum returnTo {
 		FlavourSampling,
 		MassSampling,
 		PhaseSpaceSampling,
 		MatrixElementSampling,
 		Done
 	};
 	// start with FlavourSampling
 	returnTo retTo=FlavourSampling;
 	int letFissionToXHadrons = _allowHadronFinalStates;
 	// if a beam cluster not allowed to decay to hadrons
 	if (cluster->isBeamCluster() && softUEisOn) letFissionToXHadrons = 0;
   // ### Flavour, Mass, PhaseSpace and MatrixElement Sampling loop until accepted: ###
   do
   {
 	  switch (retTo)
 	  {
 			case FlavourSampling:
 			{
 				// ## Flavour sampling and kinematic constraints ##
 				drawNewFlavour(newPtr1,newPtr2,cluster);
 				// get a flavour for the qqbar pair
 				// check for right ordering
 				assert (ptrQ2);
 				assert (newPtr2);
 				assert (ptrQ2->dataPtr());
 				assert (newPtr2->dataPtr());
 				// careful if DiquarkClusters can exist
 				bool Q1diq = DiquarkMatcher::Check(ptrQ1->id());
 				bool Q2diq = DiquarkMatcher::Check(ptrQ2->id());
 				bool newQ1diq = DiquarkMatcher::Check(newPtr1->id());
 				bool newQ2diq = DiquarkMatcher::Check(newPtr2->id());
 				bool diqClu1 = Q1diq && newQ1diq;
 				bool diqClu2 = Q2diq && newQ2diq;
 				// DEBUG only:
 				// std::cout << "Make Clusters: ( " << ptrQ1->PDGName() << " " << newPtr1->PDGName() << " ), ( "
 				// << ptrQ2->PDGName() << " " << newPtr2->PDGName() << " )\n";
 				// check if Hadron formation is possible
 				if (!( diqClu1 || diqClu2 )
 						&& (cantMakeHadron(ptrQ1, newPtr1) || cantMakeHadron(ptrQ2, newPtr2))) {
 					swap(newPtr1, newPtr2);
 					// check again
 					if(cantMakeHadron(ptrQ1, newPtr1) || cantMakeHadron(ptrQ2, newPtr2)) {
 						throw Exception()
 							<< "ClusterFissioner cannot split the cluster ("
 							<< ptrQ1->PDGName() << ' ' << ptrQ2->PDGName()
 							<< ") into hadrons.\n"
 							<< "drawn Flavour: "<< newPtr1->PDGName()<<"\n"<< Exception::runerror;
 					}
 				}
 				else if ( diqClu1 || diqClu2 ){
 					bool swapped=false;
 					if ( !diqClu1 && cantMakeHadron(ptrQ1,newPtr1) ) {
 						swap(newPtr1, newPtr2);
 						swapped=true;
 					}
 					if ( !diqClu2 && cantMakeHadron(ptrQ2,newPtr2) ) {
 						assert(!swapped);
 						swap(newPtr1, newPtr2);
 					}
 					if ( diqClu2 && diqClu1 && ptrQ1->id()*newPtr1->id()>0 ) {
 						assert(!swapped);
 						swap(newPtr1, newPtr2);
 					}
 					if (!diqClu1) assert(!cantMakeHadron(ptrQ1,newPtr1));
 					if (!diqClu2) assert(!cantMakeHadron(ptrQ2,newPtr2));
 				}
 				// Check that new clusters can produce particles and there is enough
 				// phase space to choose the drawn flavour
 				m  = newPtr1->data().constituentMass();
 				// Do not split in the case there is no phase space available + permille security
 				if(Mc <  (m1 + m + m2 + m))  {
 					retTo = FlavourSampling;
 					// escape if no flavour phase space possibile without fission
 					if (fabs((m - getParticleData(ThePEG::ParticleID::d)->constituentMass())/GeV) < 1e-3) {
 						counter_MEtry = max_loop_ME;
 						retTo = Done;
 					}
 					continue;
 				}
 				pQ1.setMass(m1);
 				pQone.setMass(m);
 				pQtwo.setMass(m);
 				pQ2.setMass(m2);
 
 				Energy MLHP1 = spectrum()->hadronPairThreshold(ptrQ1->dataPtr(),newPtr1->dataPtr());
 				Energy MLHP2 = spectrum()->hadronPairThreshold(ptrQ2->dataPtr(),newPtr2->dataPtr());
 
 				Energy MLH1 = _hadronSpectrum->lightestHadron(ptrQ1->dataPtr(),newPtr1->dataPtr())->mass();
 				Energy MLH2 = _hadronSpectrum->lightestHadron(ptrQ2->dataPtr(),newPtr2->dataPtr())->mass();
 
 				bool canBeSingleHadron1 = (m1 + m) < MLHP1;
 				bool canBeSingleHadron2 = (m2 + m) < MLHP2;
 
 				Energy mThresh1 = (m1 + m);
 				Energy mThresh2 = (m2 + m);
 
 				if (canBeSingleHadron1) mThresh1 = MLHP1;
 				if (canBeSingleHadron2) mThresh2 = MLHP2;
 
 				/*
 				// TODO LEAVE this since in case of threshold problems
 				std::cout << "######################\n";
 				std::cout << "Mc    = "<< Mc/GeV <<"\n";
 				std::cout << "m1    = "<< m1/GeV <<"\n";
 				std::cout << "m2    = "<< m2/GeV <<"\n";
 				std::cout << "m     = "<< m/GeV <<"\n";
 				std::cout << "MLHP1 = "<< MLHP1/GeV <<"\n";
 				std::cout << "MLHP2 = "<< MLHP2/GeV <<"\n";
 				std::cout << "MLH1  = "<< MLH1/GeV <<"\n";
 				std::cout << "MLH2  = "<< MLH2/GeV <<"\n";
 				std::cout << "######################\n";
 				std::cout << "Mc-M1m= "<< (Mc-(m1+m))/GeV <<"\n";
 				std::cout << "Mc-M2m= "<< (Mc-(m2+m))/GeV <<"\n";
 				std::cout << "BEAM  = "<< cluster->isBeamCluster() <<"\n";
 				*/
 				switch (letFissionToXHadrons)
 				{
 					case 0:
 						{
 							// Option None: only C->C1,C2 allowed
 							// check if mass phase space is non-zero 
 							// resample or escape if only allowed mass phase space is for C->H1,H2 or C->H1,C2
 							if ( Mc < (mThresh1 + mThresh2)) {
 								// escape if not even the lightest flavour phase space is possibile
 								// TODO make this independent of explicit u/d quark
 								if (
 										fabs((m - getParticleData(ThePEG::ParticleID::u)->constituentMass())/GeV) < 1e-3
 											||
 										fabs((m - getParticleData(ThePEG::ParticleID::d)->constituentMass())/GeV) < 1e-3
 										) {
 									counter_MEtry = max_loop_ME;
 									retTo = Done;
 									continue;
 								}
 								else {
 									retTo = FlavourSampling;
 									continue;
 								}
 							}
 							break;
 						}
 					case 1:
 						{
 							// Option SemiHadronicOnly: C->H,C allowed
 							// NOTE: TODO implement matrix element for this
 							// resample or escape if only allowed mass phase space is for C->H1,H2
 							// First case is for ensuring the enough mass to  be available and second one rejects disjoint mass regions
 							if ( ( (canBeSingleHadron1 && canBeSingleHadron2)
 									    &&  Mc < (mThresh1 + mThresh2) )
 									|| 
 									 ( (canBeSingleHadron1 || canBeSingleHadron2)
 								      && (canBeSingleHadron1 ? Mc-(m2+m) < MLH1:false ||  canBeSingleHadron2 ? Mc-(m1+m) < MLH2:false) )
 								 ){
 								// escape if not even the lightest flavour phase space is possibile
 								// TODO make this independent of explicit u/d quark
 								if (
 										fabs((m - getParticleData(ThePEG::ParticleID::u)->constituentMass())/GeV) < 1e-3
 											||
 										fabs((m - getParticleData(ThePEG::ParticleID::d)->constituentMass())/GeV) < 1e-3
 										) {
 									counter_MEtry = max_loop_ME;
 									retTo = Done;
 									continue;
 								}
 								else {
 									retTo = FlavourSampling;
 									continue;
 								}
 							}
 							break;
 						}
 					case 2:
 						{
 							// Option All: C->H,C and C->H,H allowed
 							// NOTE: TODO implement matrix element for this
 							// Mass Phase space for all option can always be found if cluster massive enough to go
 							// to the lightest 2 hadrons
 							if (  ( (canBeSingleHadron1 || canBeSingleHadron2)
 								      && (canBeSingleHadron1 ? Mc-(m2+m) < MLH1:false ||  canBeSingleHadron2 ? Mc-(m1+m) < MLH2:false) )
 								 ){
 								// escape if not even the lightest flavour phase space is possibile
 								// TODO make this independent of explicit u/d quark
 								if (
 										fabs((m - getParticleData(ThePEG::ParticleID::u)->constituentMass())/GeV) < 1e-3
 											||
 										fabs((m - getParticleData(ThePEG::ParticleID::d)->constituentMass())/GeV) < 1e-3
 										) {
 									counter_MEtry = max_loop_ME;
 									retTo = Done;
 									continue;
 								}
 								else {
 									retTo = FlavourSampling;
 									continue;
 								}
 							}
 							break;
 						}
 					default:
 						assert(false);
 				}
 				// Note: want to fallthrough (in C++17 one could uncomment
 				// 			 the line below to show that this is intentional)
 				[[fallthrough]];
 			}
 			/*
 			 * MassSampling choices:
 			 * 	- Default (default)
 			 * 	- Uniform
 			 * 	- FlatPhaseSpace
 			 * 	- SoftMEPheno
 			 * 	*/
 			case MassSampling:
 			{
 				bool failure = drawNewMasses(Mc, soft1, soft2, pClu1, pClu2,
 						ptrQ1, pQ1, newPtr1, pQone,
 						newPtr2, pQtwo, ptrQ2, pQ2);
 
 				// TODO IF C->C1,C2 (and not C->C,H or H1,H2) masses sampled and is in PhaseSpace must push through
 				// because otherwise no matrix element
 				if(failure) {
 					// TODO check which option is better
 					// retTo = FlavourSampling;
 					retTo = MassSampling;
 					continue;
 				}
 
 				// derive the masses of the children
 				Mc1 = pClu1.mass();
 				Mc2 = pClu2.mass();
 
 				// static kinematic threshold
 				if(_kinematicThresholdChoice == 0) {
 					if(Mc1 < m1+m || Mc2 < m+m2 || Mc1+Mc2 > Mc){
 						// TODO check which option is better
 						// retTo = FlavourSampling;
 						retTo = MassSampling;
 						continue;
 					}
 					// dynamic kinematic threshold
 				} else if(_kinematicThresholdChoice == 1) {
 					bool C1 = ( sqr(Mc1) )/( sqr(m1) + sqr(m) + _kinThresholdShift ) < 1.0 ? true : false;
 					bool C2 = ( sqr(Mc2) )/( sqr(m2) + sqr(m) + _kinThresholdShift ) < 1.0 ? true : false;
 					bool C3 = ( sqr(Mc1) + sqr(Mc2) )/( sqr(Mc) ) > 1.0 ? true : false;
 
 					if( C1 || C2 || C3 ) {
 						// TODO check which option is better
 						// retTo = FlavourSampling;
 						retTo = MassSampling;
 						continue;
 					}
 				}
 				/**************************
 				 * New (not present in Fortran Herwig):
 				 * check whether the fragment masses  Mc1  and  Mc2  are above the
 				 * threshold for the production of the lightest pair of hadrons with the
 				 * right flavours. If not, then set by hand the mass to the lightest
 				 * single hadron with the right flavours, in order to solve correctly
 				 * the kinematics, and (later in this method) create directly such hadron
 				 * and add it to the children hadrons of the cluster that undergoes the
 				 * fission (i.e. the one pointed by iCluPtr). Notice that in this special
 				 * case, the heavy cluster that undergoes the fission has one single
 				 * cluster child and one single hadron child. We prefer this approach,
 				 * rather than to create a light cluster, with the mass set equal to
 				 * the lightest hadron, and let then the class LightClusterDecayer to do
 				 * the job to decay it to that single hadron, for two reasons:
 				 * First, because the sum of the masses of the two constituents can be,
 				 * in this case, greater than the mass of that hadron, hence it would
 				 * be impossible to solve the kinematics for such two components, and
 				 * therefore we would have a cluster whose components are undefined.
 				 * Second, the algorithm is faster, because it avoids the reshuffling
 				 * procedure that would be necessary if we used LightClusterDecayer
 				 * to decay the light cluster to the lightest hadron.
 				 ****************************/
 				// override chosen masses if needed 
 				toHadron1 = _hadronSpectrum->chooseSingleHadron(ptrQ1->dataPtr(), newPtr1->dataPtr(),Mc1);
 				if ( letFissionToXHadrons == 0 && toHadron1 ) {
 					// reject mass samples which would force C->C,H or C->H1,H2 fission if desired 
 					// TODO check which option is better
 					// retTo = FlavourSampling;
 					retTo = MassSampling;
 					continue;
 				}
 				if(toHadron1) {
 					Mc1 = toHadron1->mass();
 					pClu1.setMass(Mc1);
 				}
 				toHadron2 = _hadronSpectrum->chooseSingleHadron(ptrQ2->dataPtr(), newPtr2->dataPtr(),Mc2);
 				if ( letFissionToXHadrons == 0 && toHadron2 ) {
 					// reject mass samples which would force C->C,H or C->H1,H2 fission if desired 
 					// TODO check which option is better
 					// retTo = FlavourSampling;
 					retTo = MassSampling;
 					continue;
 				}
 				if(toHadron2) {
 					Mc2 = toHadron2->mass();
 					pClu2.setMass(Mc2);
 				}
 				if (letFissionToXHadrons == 1 && (toHadron1 && toHadron2) ) {
 					// reject mass samples which would force C->H1,H2 fission if desired 
 					// TODO check which option is better
 					// retTo = FlavourSampling;
 					retTo = MassSampling;
 					continue;
 				}
 				// Check if the decay kinematics is still possible: if not then
 				// force the one-hadron decay for the other cluster as well.
 				if(Mc1 + Mc2  >  Mc) {
 					// reject if we would need to create a C->H,H process if letFissionToXHadrons<2
 					if (letFissionToXHadrons < 2) {
 						// TODO check which option is better
 						// retTo = FlavourSampling;
 						retTo = MassSampling;
 						continue;
 					}
 
 					// TODO forbid other cluster!!!! to be also at hadron
 					if(!toHadron1) {
 						toHadron1 = _hadronSpectrum->chooseSingleHadron(ptrQ1->dataPtr(), newPtr1->dataPtr(),Mc-Mc2);
 						// toHadron1 = _hadronSpectrum->chooseSingleHadron(ptrQ1->dataPtr(), newPtr1->dataPtr(),ZERO);
 						if(toHadron1) {
 							Mc1 = toHadron1->mass();
 							pClu1.setMass(Mc1);
 						}
 					}
 					else if(!toHadron2) {
 						toHadron2 = _hadronSpectrum->chooseSingleHadron(ptrQ2->dataPtr(), newPtr2->dataPtr(),Mc-Mc1);
 						// toHadron2 = _hadronSpectrum->chooseSingleHadron(ptrQ2->dataPtr(), newPtr2->dataPtr(),ZERO);
 						if(toHadron2) {
 							Mc2 = toHadron2->mass();
 							pClu2.setMass(Mc2);
 						}
 					}
 				}
 				if (Mc <= Mc1+Mc2){
 					// escape if already lightest quark drawn
 					if (
 							fabs((m - getParticleData(ThePEG::ParticleID::u)->constituentMass())/GeV) < 1e-3
 							||
 							fabs((m - getParticleData(ThePEG::ParticleID::d)->constituentMass())/GeV) < 1e-3
 						 ) {
 						counter_MEtry = max_loop_ME;
 						retTo = Done;
 					}
 					else {
 						// Try again with lighter quark
 						retTo = FlavourSampling;
 					}
 					continue;
 				}
 				// Determined the (5-components) momenta (all in the LAB frame)
 				p0Q1.setMass(ptrQ1->mass()); // known (mom Q1 before fission)
 				p0Q1.rescaleEnergy(); // TODO check if needed
 				p0Q2.setMass(ptrQ2->mass()); // known (mom Q2 before fission)
 				p0Q2.rescaleEnergy();// TODO check if needed
 				pClu.rescaleMass();
 				// Note: want to fallthrough (in C++17 one could uncomment
 				// 			 the line below to show that this is intentional)
 				[[fallthrough]];
 			}
 			/*
 			 * PhaseSpaceSampling choices:
 			 * 	- FullyAligned (default)
 			 * 	- AlignedIsotropic
 			 * 	- FullyIsotropic
 			 * 	*/
 			case PhaseSpaceSampling:
 			{
 				// ### Sample the Phase Space with respect to Matrix Element: ###
 				// TODO insert here PhaseSpace sampler
 				bool failure = drawKinematics(pClu,p0Q1,p0Q2,toHadron1,toHadron2,
 						pClu1,pClu2,pQ1,pQone,pQtwo,pQ2);
 
 				if(failure) {
 					// TODO check which option is better
 					retTo = MassSampling;
 					continue;
 				}
 				// Should be precise i.e. no rejection expected
 				// Note: want to fallthrough (in C++17 one could uncomment
 				// 			 the line below to show that this is intentional)
 				[[fallthrough]];
 			}
 			/*
 			 * MatrixElementSampling choices:
 			 * 	- Default (default)
 			 * 	- SoftQQbar
 			 * 	*/
 			case MatrixElementSampling:
 			{
 				counter_MEtry++;
 				// TODO maybe bridge this to work more neatly
 				// Ignore matrix element for C->C,H or C->H1,H2 fission
 				if (toHadron1 || toHadron2) {
 					retTo = Done;
 					break;
 				}
 				// TODO insert here partonic Matrix Element rejection
 				double SQME = calculateSQME(p0Q1,p0Q2,pQ1,pQone,pQ2,pQtwo);
 				double SQMEoverEstimate = calculateSQME_OverEstimate(p0Q1,p0Q2,pQ1,pQone,pQ2,pQtwo); 
 				double Pacc = SQME/SQMEoverEstimate;
 				if (Pacc > 1.0 || std::isnan(Pacc) || std::isinf(Pacc)) throw Exception() << "Pacc = "<< Pacc << " > 1 in ClusterFissioner::cutTwo" << Exception::runerror;
 				if (UseRandom::rnd()<Pacc) {
 					if (0 && _matrixElement!=0) {
 						// std::cout << "\nAccept Pacc = "<<Pacc<<"\n";
 						// std::ofstream out("data_CluFis.dat", std::ios::app | std::ios::out);
 						// out << Pacc << "\t"
 							// << Mc/GeV  << "\t"
 							// << pClu1.mass()/GeV << "\t"
 							// << pClu2.mass()/GeV << "\t"
 							// << pQone*pQtwo/GeV2 << "\t"
 							// << pQ1*pQ2/GeV2 << "\t"
 							// << pQ1*pQtwo/GeV2 << "\t"
 							// << pQ2*pQone/GeV2 << "\t"
 							// << m/GeV
 							// << "\n";
 						// out.close();
 						Energy MbinStart=2.0*GeV;
 						Energy MbinEnd=91.0*GeV;
 						Energy dMbin=1.0*GeV;
 						Energy MbinLow;
 						Energy MbinHig;
 						if (   fabs((m-0.325*GeV)/GeV)<1e-5
 							&& fabs((m1-0.325*GeV)/GeV)<1e-5
 							&& fabs((m2-0.325*GeV)/GeV)<1e-5) {
 							int cnt = 0;
 							for (Energy MbinIt=MbinStart; MbinIt < MbinEnd; MbinIt+=dMbin)
 							{
 								if (0){
 									std::cout << "\nFirst\n" << std::endl;
 									int ctr=0;
 									for (Energy MbinIt=MbinStart; MbinIt < MbinEnd; MbinIt+=dMbin)
 									{
 										std::string name = "WriteOut/data_CluFis_BinM_"+std::to_string(ctr)+".dat";
 										std::ofstream out2(name,std::ios::out);
 										out2 << "# Binned from "<<MbinIt/GeV << "\tto\t" << (MbinIt+dMbin)/GeV<<"\n";
 										out2 << "# m=m1=m2=0.325\n";
 										out2 << "# (1) Pacc\t"
 											<< "(2) Mc/GeV\t"
 											<< "(3) M1/GeV\t"
 											<< "(4) M2/GeV\t"
 											<< "(5) q.qbar/GeV2\t"
 											<< "(6) q1.q2/GeV2\t"
 											<< "(7) q1.qbar/GeV2\t"
 											<< "(8) q2.q/GeV2\t"
 											<< "(9) m/GeV\n";
 										out2.close();
 										ctr++;
 									}
 									// first=0;
 								}
 								MbinLow  = MbinIt;
 								MbinHig  = MbinLow+dMbin;
 								if (Mc>MbinLow && Mc<MbinHig) {
 									std::string name = "WriteOut/data_CluFis_BinM_"+std::to_string(cnt)+".dat";
 									std::ofstream out2(name, std::ios::app );
 									out2 << Pacc << "\t"
 										<< Mc/GeV  << "\t"
 										<< pClu1.mass()/GeV << "\t"
 										<< pClu2.mass()/GeV << "\t"
 										<< pQone*pQtwo/GeV2 << "\t"
 										<< pQ1*pQ2/GeV2 << "\t"
 										<< pQ1*pQtwo/GeV2 << "\t"
 										<< pQ2*pQone/GeV2 << "\t"
 										<< m/GeV
 										<< "\n";
 									out2.close();
 									break;
 								}
 								// if (Mc<MbinIt) break;
 								cnt++;
 							}
 						}
 					}
 					retTo=Done;
 					break;
 				}
 				retTo = MassSampling;
 				continue;
 			}
 			default:
 			{
 				assert(false);
 			}
 	  }
   }
   while (retTo!=Done && counter_MEtry < max_loop_ME);
   // while (retTo!=Done);
 
   if(counter_MEtry >= max_loop_ME) {
 		// happens if we get at too light cluster to begin with
 		// or if we get too massive clusters where the matrix element
 		// is very inefficiently sampled
 		// TODO exclude this by ensuring that there is always enough phase space for M>m1+m2+2*m and maybe other conditions
 		// std::cout << "ERROR: Max Looped\n";
 		static const PPtr null = PPtr();
 		return cutType(PPair(null,null),PPair(null,null));
   }
   // ==> full sample generated
   /******************
    * The previous methods have determined the kinematics and positions
    * of C -> C1 + C2.
    * In the case that one of the two product is light, that means either
    * decayOneHadronClu1 or decayOneHadronClu2 is true, then the momenta
    * of the components of that light product have not been determined,
    * and a (light) cluster will not be created: the heavy father cluster
    * decays, in this case, into a single (not-light) cluster and a
    * single hadron. In the other, "normal", cases the father cluster
    * decays into two clusters, each of which has well defined components.
    * Notice that, in the case of components which point to particles, the
    * momenta of the components is properly set to the new values, whereas
    * we do not change the momenta of the pointed particles, because we
    * want to keep all of the information (that is the new momentum of a
    * component after the splitting, which is contained in the _momentum
    * member of the Component class, and the (old) momentum of that component
    * before the splitting, which is contained in the momentum of the
    * pointed particle). Please not make confusion of this only apparent
    * inconsistency!
    ********************/
   LorentzPoint posC,pos1,pos2;
   posC = cluster->vertex();
   calculatePositions(pClu, posC, pClu1, pClu2, pos1, pos2);
   cutType rval;
   if(toHadron1) {
     rval.first = produceHadron(toHadron1, newPtr1, pClu1, pos1);
     finalhadrons.push_back(rval.first.first);
   }
   else {
     rval.first = produceCluster(ptrQ1, newPtr1, pClu1, pos1, pQ1, pQone, rem1);
   }
   if(toHadron2) {
     rval.second = produceHadron(toHadron2, newPtr2, pClu2, pos2);
     finalhadrons.push_back(rval.second.first);
   }
   else {
     rval.second = produceCluster(ptrQ2, newPtr2, pClu2, pos2, pQ2, pQtwo, rem2);
   }
   return rval;
 }
 
 
 ClusterFissioner::cutType
 ClusterFissioner::cutThree(ClusterPtr & cluster, tPVector & finalhadrons,
 			   bool softUEisOn) {
   // need to make sure only 3-cpt clusters get here
   assert(cluster->numComponents() == 3);
   // extract quarks
   tPPtr ptrQ[3] = {cluster->particle(0),cluster->particle(1),cluster->particle(2)};
   assert( ptrQ[0] && ptrQ[1] && ptrQ[2] );
   // find maximum mass pair
   Energy mmax(ZERO);
   Lorentz5Momentum pDiQuark;
   int iq1(-1),iq2(-1);
   Lorentz5Momentum psum;
   for(int q1=0;q1<3;++q1) {
     psum+= ptrQ[q1]->momentum();
     for(int q2=q1+1;q2<3;++q2) {
       Lorentz5Momentum ptest = ptrQ[q1]->momentum()+ptrQ[q2]->momentum();
       ptest.rescaleMass();
       Energy mass = ptest.m();
       if(mass>mmax) {
 	mmax = mass;
 	pDiQuark = ptest;
 	iq1  = q1;
 	iq2  = q2;
       }
     }
   }
   // and the spectators
   int iother(-1);
   for(int ix=0;ix<3;++ix) if(ix!=iq1&&ix!=iq2) iother=ix;
   assert(iq1>=0&&iq2>=0&&iother>=0);
 
   // And check if those particles are from a beam remnant
   bool rem1 = cluster->isBeamRemnant(iq1);
   bool rem2 = cluster->isBeamRemnant(iq2);
   // workout which distribution to use
   bool soft1(false),soft2(false);
   switch (_iopRem) {
   case 0:
     soft1 = rem1 || rem2;
     soft2 = rem2 || rem1;
     break;
   case 1:
     soft1 = rem1;
     soft2 = rem2;
     break;
   }
   // Initialization for the exponential ("soft") mass distribution.
   static const int max_loop = 1000;
   int counter = 0;
   Energy Mc1 = ZERO, Mc2 = ZERO, m1=ZERO, m2=ZERO, m=ZERO;
   tcPDPtr toHadron;
   bool toDiQuark(false);
   PPtr newPtr1 = PPtr(),newPtr2 = PPtr();
   PDPtr diquark;
   bool succeeded = false;
   Lorentz5Momentum pClu1, pClu2, pQ1, pQone, pQtwo, pQ2;
   do {
     succeeded = false;
     ++counter;
 
     // get a flavour for the qqbar pair
     drawNewFlavour(newPtr1,newPtr2,cluster);
     
     // randomly pick which will be (anti)diquark and which a mesonic cluster
     if(UseRandom::rndbool()) {
       swap(iq1,iq2);
       swap(rem1,rem2);
     }
     // check first order
     if(cantMakeHadron(ptrQ[iq1], newPtr1) || !spectrum()->canMakeDiQuark(ptrQ[iq2], newPtr2)) {
       swap(newPtr1,newPtr2);
     }
     // check again
     if(cantMakeHadron(ptrQ[iq1], newPtr1) || !spectrum()->canMakeDiQuark(ptrQ[iq2], newPtr2)) {
       throw Exception()
 	<< "ClusterFissioner cannot split the cluster ("
 	<< ptrQ[iq1]->PDGName() << ' ' << ptrQ[iq2]->PDGName()
 	<< ") into a hadron and diquark.\n" << Exception::runerror;
     }
     // Check that new clusters can produce particles and there is enough
     // phase space to choose the drawn flavour
     m1 = ptrQ[iq1]->data().constituentMass();
     m2 = ptrQ[iq2]->data().constituentMass();
     m  = newPtr1->data().constituentMass();
     // Do not split in the case there is no phase space available
     if(mmax <  m1+m + m2+m) continue;
 
     pQ1.setMass(m1);
     pQone.setMass(m);
     pQtwo.setMass(m);
     pQ2.setMass(m2);
 
     bool failure = drawNewMasses(mmax, soft1, soft2, pClu1, pClu2,
 					    ptrQ[iq1], pQ1, newPtr1, pQone,
 					    newPtr2, pQtwo, ptrQ[iq1], pQ2);
 
 		if (failure) continue;
 
     Mc1 = pClu1.mass();
 	Mc2 = pClu2.mass();
 
     if(Mc1 < m1+m || Mc2 < m+m2 || Mc1+Mc2 > mmax) continue;
 
+    if ( _phaseSpaceWeights ) {
+      if ( phaseSpaceVeto(mmax,Mc1,Mc2,m,m1,m2) )
+	continue;
+    }
+    
     // check if need to force meson clster to hadron
     toHadron = _hadronSpectrum->chooseSingleHadron(ptrQ[iq1]->dataPtr(), newPtr1->dataPtr(),Mc1);
     if(toHadron) { Mc1 = toHadron->mass(); pClu1.setMass(Mc1); }
     // check if need to force diquark cluster to be on-shell
     toDiQuark = false;
     diquark = spectrum()->makeDiquark(ptrQ[iq2]->dataPtr(), newPtr2->dataPtr());
     if(Mc2 < diquark->constituentMass()) {
       Mc2 = diquark->constituentMass(); pClu2.setMass(Mc2);
       toDiQuark = true;
     }
     // if a beam cluster not allowed to decay to hadrons
     if(cluster->isBeamCluster() && toHadron && softUEisOn)
       continue;
     // Check if the decay kinematics is still possible: if not then
     // force the one-hadron decay for the other cluster as well.
     if(Mc1 + Mc2  >  mmax) {
       if(!toHadron) {
 	toHadron = _hadronSpectrum->chooseSingleHadron(ptrQ[iq1]->dataPtr(), newPtr1->dataPtr(),mmax-Mc2);
 	if(toHadron) { Mc1 = toHadron->mass(); pClu1.setMass(Mc1); }
       }
       else if(!toDiQuark) {
 	Mc2 = _hadronSpectrum->massLightestHadron(ptrQ[iq2]->dataPtr(), newPtr2->dataPtr()); pClu2.setMass(Mc2);
 	toDiQuark = true;
       }
     }
     succeeded = (mmax >= Mc1+Mc2);
   }
   while (!succeeded && counter < max_loop);
   // check no of tries
   if(counter >= max_loop) return cutType();
 
   // Determine the (5-components) momenta (all in the LAB frame)
   Lorentz5Momentum p0Q1 = ptrQ[iq1]->momentum();
-  Lorentz5Momentum p0Q2 = ptrQ[iq2]->momentum(); //dummy
-	p0Q1.setMass(ptrQ[iq1]->momentum().mass());
-	p0Q2.setMass(ptrQ[iq2]->momentum().mass());
-  drawKinematics(pDiQuark,p0Q1,p0Q2,toHadron,toDiQuark,
+  calculateKinematics(pDiQuark,p0Q1,toHadron,toDiQuark,
 		      pClu1,pClu2,pQ1,pQone,pQtwo,pQ2);
   // positions of the new clusters
   LorentzPoint pos1,pos2;
   Lorentz5Momentum pBaryon = pClu2+ptrQ[iother]->momentum();
   calculatePositions(cluster->momentum(), cluster->vertex(), pClu1, pBaryon, pos1, pos2);
   // first the mesonic cluster/meson
   cutType rval;
    if(toHadron) {
      rval.first = produceHadron(toHadron, newPtr1, pClu1, pos1);
      finalhadrons.push_back(rval.first.first);
    }
    else {
      rval.first = produceCluster(ptrQ[iq1], newPtr1, pClu1, pos1, pQ1, pQone, rem1);
    }
    if(toDiQuark) {
      rem2 |= cluster->isBeamRemnant(iother);
      PPtr newDiQuark = diquark->produceParticle(pClu2);
      rval.second = produceCluster(newDiQuark, ptrQ[iother], pBaryon, pos2, pClu2,
       				  ptrQ[iother]->momentum(), rem2);
    }
    else {
      rval.second = produceCluster(ptrQ[iq2], newPtr2, pBaryon, pos2, pQ2, pQtwo, rem2,
 				  ptrQ[iother],cluster->isBeamRemnant(iother));
    }
    cluster->isAvailable(false);
    return rval;
 }
 
 ClusterFissioner::PPair
 ClusterFissioner::produceHadron(tcPDPtr hadron, tPPtr newPtr, const Lorentz5Momentum &a,
 				const LorentzPoint &b) const {
   PPair rval;
   if(hadron->coloured()) {
     rval.first = (_hadronSpectrum->lightestHadron(hadron,newPtr->dataPtr()))->produceParticle();
   }
   else
     rval.first = hadron->produceParticle();
   rval.second = newPtr;
   rval.first->set5Momentum(a);
   rval.first->setVertex(b);
   return rval;
 }
 
 ClusterFissioner::PPair ClusterFissioner::produceCluster(tPPtr ptrQ, tPPtr newPtr,
 							 const Lorentz5Momentum & a,
 				                         const LorentzPoint & b,
 							 const Lorentz5Momentum & c,
 				                         const Lorentz5Momentum & d,
 							 bool isRem,
 							 tPPtr spect, bool remSpect) const {
   PPair rval;
   rval.second = newPtr;
   ClusterPtr cluster = !spect ? new_ptr(Cluster(ptrQ,rval.second)) : new_ptr(Cluster(ptrQ,rval.second,spect));
   rval.first = cluster;
   cluster->set5Momentum(a);
   cluster->setVertex(b);
   assert(cluster->particle(0)->id() == ptrQ->id());
   cluster->particle(0)->set5Momentum(c);
   cluster->particle(1)->set5Momentum(d);
   cluster->setBeamRemnant(0,isRem);
   if(remSpect) cluster->setBeamRemnant(2,remSpect);
   return rval;
 }
 
 
 /**
  * Calculate a veto for the phase space weight
  */
 bool ClusterFissioner::phaseSpaceVeto(const Energy Mc, const Energy Mc1, const Energy Mc2,
 		const Energy m, const Energy m1, const Energy m2) const {
 	double M_temp = Mc/GeV;
 	double M1_temp = Mc1/GeV;
 	double M2_temp = Mc2/GeV;
 	double m_temp = m/GeV;
 	double m1_temp = m1/GeV;
 	double m2_temp = m2/GeV;
 	double lam1 = sqrt(Kinematics::kaellen(M1_temp, m1_temp, m_temp));
 	double lam2 = sqrt(Kinematics::kaellen(M2_temp, m2_temp, m_temp));
 	double lam3 = sqrt(Kinematics::kaellen(M_temp,  M1_temp, M2_temp));
 	double ratio;
 	double PSweight = pow(lam1*lam2*lam3,_dim-3.)*pow(M1_temp*M2_temp,2.-_dim);
 	// overestimate only possible for dim>=3.0
 	assert(_dim>=3.0);
 	double overEstimate = _dim>=4.0 ? pow(M_temp,4.*_dim-14.):pow(M_temp,2*(_dim-3.0))/pow((m1_temp+m_temp)*(m2_temp+m_temp),4.0-_dim);
 	ratio = PSweight/overEstimate;
 	// if (!(ratio>=0)) std::cout << "M "<<M_temp<<" M1 "<<M1_temp<<" M2 "<<M2_temp<<" m1 "<<m1_temp<<" m2 "<<m2_temp<<" m "<<m_temp<<"\n\n";
 	assert (ratio >= 0);
 	assert (ratio <= 1);
 	return (UseRandom::rnd()>ratio);
 }
 
 
 /**
  * Calculate the masses and possibly kinematics of the cluster
  * fission at hand; if claculateKineamtics is perfomring non-trivial
  * steps kinematics calulcated here will be overriden. Currently resorts to the default
  */
 bool ClusterFissioner::drawNewMasses(const Energy Mc, const bool soft1, const bool soft2,
 		Lorentz5Momentum& pClu1, Lorentz5Momentum& pClu2,
 		tcPPtr ptrQ1,    const Lorentz5Momentum& pQ1, 
 		tcPPtr, const Lorentz5Momentum& pQone,
 		tcPPtr, const Lorentz5Momentum& pQtwo,
 		tcPPtr ptrQ2,    const Lorentz5Momentum& pQ2) const {
 	// TODO in all for better efficiency treat 
 	// letFissionToXHadrons!=0 as seperate cases for reduced phasespace 
 	// when mi+m < MassLightestHadronPair
 	switch (_massSampler)
 	{
 		case 0:
 			return drawNewMassesDefault(Mc, soft1, soft2, pClu1, pClu2, ptrQ1, pQ1, pQone, pQtwo, ptrQ2, pQ2);
 			break;
 		case 1: 
 			return drawNewMassesUniform(Mc, soft1, soft2, pClu1, pClu2, pQ1, pQone, pQ2);
 			break;
 		case 2:
 			return drawNewMassesPhaseSpace(Mc, soft1, soft2, pClu1, pClu2, pQ1, pQone, pQ2);
 			break;
 		case 3:
 			return drawNewMassesPhaseSpaceExtended(Mc, soft1, soft2, pClu1, pClu2, pQ1, pQone, pQ2);
 			break;
 		default:
 			assert(false);
 	}
 	return true;// failure
 }
 
 
 
 /**
  * Calculate the masses and possibly kinematics of the cluster
  * fission at hand; if claculateKineamtics is perfomring non-trivial
  * steps kinematics claulcated here will be overriden. Currentl;y resorts to the default
  */
 bool ClusterFissioner::drawNewMassesDefault(const Energy Mc, const bool soft1, const bool soft2,
 		Lorentz5Momentum& pClu1, Lorentz5Momentum& pClu2,
 		tcPPtr ptrQ1, const Lorentz5Momentum& pQ1, 
 		const Lorentz5Momentum& pQone,
 		const Lorentz5Momentum& pQtwo,
 		tcPPtr ptrQ2,  const Lorentz5Momentum& pQ2) const {
 
 
 	// power for splitting
 	double exp1 = !spectrum()->isExotic(ptrQ1->dataPtr()) ? _pSplitLight : _pSplitExotic;
 	double exp2 = !spectrum()->isExotic(ptrQ2->dataPtr()) ? _pSplitLight : _pSplitExotic;
 	for ( const long& id : spectrum()->heavyHadronizingQuarks() ) {
 		assert(_pSplitHeavy.find(id) != _pSplitHeavy.end());
 		if ( spectrum()->hasHeavy(id,ptrQ1->dataPtr()) ) exp1 = _pSplitHeavy.find(id)->second;
 		if ( spectrum()->hasHeavy(id,ptrQ2->dataPtr()) ) exp2 = _pSplitHeavy.find(id)->second;
 	}
 
 	Energy M1 = drawChildMass(Mc,pQ1.mass(),pQ2.mass(),pQone.mass(),exp1,soft1);
 	Energy M2 = drawChildMass(Mc,pQ2.mass(),pQ1.mass(),pQtwo.mass(),exp2,soft2);
 
 	pClu1.setMass(M1);
 	pClu2.setMass(M2);
 
 	return false; // succeeds
 }
 
 
 /**
  * Sample the masses for flat phase space
  * */
 bool ClusterFissioner::drawNewMassesUniform(const Energy Mc, const bool soft1, const bool soft2,
 		Lorentz5Momentum& pClu1, Lorentz5Momentum& pClu2,
 		const Lorentz5Momentum& pQ1, 
 		const Lorentz5Momentum& pQ,
 		const Lorentz5Momentum& pQ2) const {
 
 	Energy M1,M2;
 	const Energy m1 = pQ1.mass();
 	const Energy m2 = pQ2.mass();
 	const Energy m  = pQ.mass();
 	const Energy M1min = m1 + m;
 	const Energy M2min = m2 + m;
 	const Energy M1max = Mc - M2min;
 	const Energy M2max = Mc - M1min;
 
 	assert(M1max-M1min>ZERO);
 	assert(M2max-M2min>ZERO);
 
 	double r1;
 	double r2;
 
 	int counter = 0;
 	const int max_counter = 100;
 
 	while (counter < max_counter) {
 		r1 = UseRandom::rnd();
 		r2 = UseRandom::rnd();
 
 		M1 = (M1max-M1min)*r1 + M1min;
 		M2 = (M2max-M2min)*r2 + M2min;
 
 		counter++;
 		if ( Mc > M1 + M2) break;
 	}
 
 	if (counter==max_counter
 			|| Mc < M1 + M2
 			|| M1 <= M1min
 			|| M2 <= M2min ) return true; // failure
 
 	pClu1.setMass(M1);
 	pClu2.setMass(M2);
 
 	return false; // succeeds
 }
 
 
 
 /**
  * Sample the masses for flat phase space
  * */
 bool ClusterFissioner::drawNewMassesPhaseSpace(const Energy Mc, const bool soft1, const bool soft2,
 		Lorentz5Momentum& pClu1, Lorentz5Momentum& pClu2,
 		const Lorentz5Momentum& pQ1, 
 		const Lorentz5Momentum& pQ,
 		const Lorentz5Momentum& pQ2) const {
 	Energy M1,M2,MuS;
 	const Energy m1 = pQ1.mass();
 	const Energy m2 = pQ2.mass();
 	const Energy m  = pQ.mass();
 	const Energy M1min = m1 + m;
 	const Energy M2min = m2 + m;
 	// const Energy M1max = Mc - M2min;
 	// const Energy M2max = Mc - M1min;
 
 	// assert(M1max-M1min>ZERO);
 	// assert(M2max-M2min>ZERO);
 
 	double r1;
 	double r2;
 
 	int counter = 0;
 	const int max_counter = 200;
 	// const Energy MuMminS = M1min + M2min;
 	// const Energy MuMminD = M1min - M2min;
 	const Energy MuMax = Mc - (M1min+M2min);
 
 	while (counter < max_counter) {
 		r1 = UseRandom::rnd();
 		r2 = UseRandom::rnd();
 
 		// TODO make this more efficient
 		// M1 = (M1max-M1min)*r1 + M1min;
 		// M2 = (M2max-M2min)*r2 + M2min;
 
 		MuS = MuMax * sqrt(r1);
 		// MD = 2*MS*r2 - MS + MuMminD;
 
 		M1 = M1min + MuS * r2;
 		M2 = M2min + MuS * (1.0 - r2);
 
 		counter++;
 
 		// Automatically satisfied
 		// if ( Mc <= M1 + M2) std::cout << "Mc "<< Mc/GeV << " M1 "<< M1/GeV <<" M2 " <<M2/GeV << std::endl;;
 		// if ( M1 <= M1min  ) std::cout << "M1 "<< M1/GeV <<" M1min " <<M1min/GeV << std::endl;;
 		// if ( M2 <= M2min  ) std::cout << "M2 "<< M2/GeV <<" M2min " <<M2min/GeV << std::endl;;
 		// assert( Mc > M1 + M2) ;
 		// assert( M1 > M1min  ) ;
 		// assert( M2 > M2min  ) ;
 		// if ( Mc <= M1 + M2) continue;
 		// if ( M1 <= M1min  ) continue;
 		// if ( M2 <= M2min  ) continue;
 		if (!phaseSpaceVeto(Mc,M1,M2,m,m1,m2) ) break; // For FlatPhaseSpace sampling vetoing
 	}
 	if (counter==max_counter) return true; // failure
 
 	pClu1.setMass(M1);
 	pClu2.setMass(M2);
 
 
 	return false; // succeeds
 }
 
 
 /**
  * Sample the masses for flat phase space with modulation e.g. here
  * FlatPhaseSpace*(M1*M2)**alpha
  * */
 bool ClusterFissioner::drawNewMassesPhaseSpaceExtended(const Energy Mc, 
 		const bool soft1, const bool soft2,
 		Lorentz5Momentum& pClu1, Lorentz5Momentum& pClu2,
 		const Lorentz5Momentum& pQ1, 
 		const Lorentz5Momentum& pQ,
 		const Lorentz5Momentum& pQ2) const {
 
 	Energy M1,M2;
 	const Energy m1 = pQ1.mass();
 	const Energy m2 = pQ2.mass();
 	const Energy m  = pQ.mass();
 	const Energy M1min = m1 + m;
 	const Energy M2min = m2 + m;
 	const Energy M1max = Mc - M2min;
 	const Energy M2max = Mc - M1min;
 
 	assert(M1max-M1min>ZERO);
 	assert(M2max-M2min>ZERO);
 
 	double r1;
 	double r2;
 
 	int counter = 0;
 	const int max_counter = 200;
 
 	const int alpha = 2;
 
 	while (counter < max_counter) {
 		r1 = UseRandom::rnd();
 		r2 = UseRandom::rnd();
 
 		// TODO make this more efficient
 		// Uniform sampling
 		// M1 = (M1max-M1min)*r1 + M1min;
 		// M2 = (M2max-M2min)*r2 + M2min;
 		// Power sampling giving (M1*M2)**alpha
 		M1 = M1min * pow( 1.0 - r1 + r1 * pow(M1max/M1min,alpha+1.0) , 1.0/(alpha+1.0));
 		M2 = M2min * pow( 1.0 - r2 + r2 * pow(M2max/M2min,alpha+1.0) , 1.0/(alpha+1.0));
 
 		counter++;
 		if ( Mc <= M1 + M2) continue;
 		if ( M1 <= M1min  ) continue;
 		if ( M2 <= M2min  ) continue;
 		if (!phaseSpaceVeto(Mc,M1,M2,m,m1,m2) ) break; // For FlatPhaseSpace sampling vetoing
 	}
 	if (counter==max_counter
 			|| Mc < M1 + M2
 			|| M1 <= M1min
 			|| M2 <= M2min ) return true; // failure
 
 	pClu1.setMass(M1);
 	pClu2.setMass(M2);
 
 
 	return false; // succeeds
 }
 
 
 void ClusterFissioner::drawNewFlavourDiquarks(PPtr& newPtrPos,PPtr& newPtrNeg,
 		const ClusterPtr & clu) const {
 
 	// Flavour is assumed to be only  u, d, s,  with weights
 	// (which are not normalized probabilities) given
 	// by the same weights as used in HadronsSelector for
 	// the decay of clusters into two hadrons.
 
 	unsigned hasDiquarks=0;
 	assert(clu->numComponents()==2);
 	tcPDPtr pD1=clu->particle(0)->dataPtr();
 	tcPDPtr pD2=clu->particle(1)->dataPtr();
 	bool isDiq1=DiquarkMatcher::Check(pD1->id());
 	if (isDiq1) hasDiquarks++;
 	bool isDiq2=DiquarkMatcher::Check(pD2->id());
 	if (isDiq2) hasDiquarks++;
 	assert(hasDiquarks<=2);
 	Energy Mc=(clu->momentum().mass());
 	// if (fabs(clu->momentum().massError() )>1e-14) std::cout << "Mass inconsistency CF : " << std::scientific  << clu->momentum().massError() <<"\n";
 	// Not allow yet Diquark Clusters 
 	// if ( hasDiquarks>=1 || Mc < spectrum()->massLightestBaryonPair(pD1,pD2) )
 	// return drawNewFlavour(newPtrPos,newPtrNeg);
 
   Energy minMass;
   Selector<long> choice;
   // int countQ=0;
   // int countDiQ=0;
   // adding quark-antiquark pairs to the selection list
   for ( const long& id : spectrum()->lightHadronizingQuarks() ) {
 	  // TODO uncommenting below gives sometimes 0 selection possibility,
 	  // maybe need to be checked in the LightClusterDecayer and ColourReconnector
 	  // if (Mc < spectrum()->massLightestHadronPair(pD1,pD2)) continue;
 	  // countQ++;
 	  if (_fissionCluster==0) choice.insert(_hadronSpectrum->pwtQuark(id),id);
 	  else if (_fissionCluster==1) choice.insert(_fissionPwt.find(id)->second,id);
 	  else assert(false);
   }
   // adding diquark-antidiquark pairs to the selection list
   switch (hasDiquarks)
   {
   	case 0:
 		for ( const long& id : spectrum()->lightHadronizingDiquarks() ) {
 			if (_strictDiquarkKinematics) {
 				tPDPtr cand = getParticleData(id);
 				minMass = spectrum()->massLightestHadron(pD2,cand)
 						+ spectrum()->massLightestHadron(cand,pD1);
 			}
 			else minMass = spectrum()->massLightestBaryonPair(pD1,pD2);
 			if (Mc < minMass) continue;
 			// countDiQ++;
 			if (_fissionCluster==0) choice.insert(_hadronSpectrum->pwtQuark(id),id);
 			else if (_fissionCluster==1) choice.insert(_fissionPwt.find(id)->second,id);
 			else assert(false);
 		}
   		break;
   	case 1:
 		if (_diquarkClusterFission<1) break;
 		for ( const long& id : spectrum()->lightHadronizingDiquarks() ) {
 			tPDPtr diq = getParticleData(id);
 			if (isDiq1)
 				minMass = spectrum()->massLightestHadron(pD2,diq)
 						+ spectrum()->massLightestBaryonPair(diq,pD1);
 			else
 				minMass = spectrum()->massLightestHadron(pD1,diq)
 						+ spectrum()->massLightestBaryonPair(diq,pD2);
 			if (Mc < minMass) continue;
 			// countDiQ++;
 			if (_fissionCluster==0) choice.insert(_hadronSpectrum->pwtQuark(id),id);
 			else if (_fissionCluster==1) choice.insert(_fissionPwt.find(id)->second,id);
 			else assert(false);
 		}
 		break;
   	case 2:
 		if (_diquarkClusterFission<2) break;
 		for ( const long& id : spectrum()->lightHadronizingDiquarks() ) {
 			tPDPtr diq = getParticleData(id);
 			if (Mc < spectrum()->massLightestBaryonPair(pD1,pD2)) {
 				throw Exception() << "Found Diquark Cluster:\n" << *clu << "\nwith  MassCluster = "
 					<< ounit(Mc,GeV) <<" GeV MassLightestBaryonPair = "
 					<< ounit(spectrum()->massLightestBaryonPair(pD1,pD2) ,GeV)
 					<< " GeV cannot decay" << Exception::eventerror;
 			}
 			minMass = spectrum()->massLightestBaryonPair(pD1,diq)
 					+ spectrum()->massLightestBaryonPair(diq,pD2);
 			if (Mc < minMass) continue;
 			// countDiQ++;
 			if (_fissionCluster==0) choice.insert(_hadronSpectrum->pwtQuark(id),id);
 			else if (_fissionCluster==1) choice.insert(_fissionPwt.find(id)->second,id);
 			else assert(false);
 		}
   		break;
   	default:
   		assert(false);
   }
   assert(choice.size()>0);
   long idNew = choice.select(UseRandom::rnd());
   newPtrPos = getParticle(idNew);
   newPtrNeg = getParticle(-idNew);
   assert(newPtrPos);
   assert(newPtrNeg);
   assert(newPtrPos->dataPtr());
   assert(newPtrNeg->dataPtr());
 
 }
 
 void ClusterFissioner::drawNewFlavourQuarks(PPtr& newPtrPos,PPtr& newPtrNeg) const {
 
   // Flavour is assumed to be only  u, d, s,  with weights
   // (which are not normalized probabilities) given
   // by the same weights as used in HadronsSelector for
   // the decay of clusters into two hadrons.
 
 
   Selector<long> choice;
   switch(_fissionCluster){
   case 0:
     for ( const long& id : spectrum()->lightHadronizingQuarks() )
       choice.insert(_hadronSpectrum->pwtQuark(id),id);
     break;
   case 1:
     for ( const long& id : spectrum()->lightHadronizingQuarks() )
       choice.insert(_fissionPwt.find(id)->second,id);
     break;
   default :
     assert(false);
   }
   long idNew = choice.select(UseRandom::rnd());
   newPtrPos = getParticle(idNew);
   newPtrNeg = getParticle(-idNew);
   assert (newPtrPos);
   assert(newPtrNeg);
   assert (newPtrPos->dataPtr());
   assert(newPtrNeg->dataPtr());
 
 }
 
 void ClusterFissioner::drawNewFlavourEnhanced(PPtr& newPtrPos,PPtr& newPtrNeg,
                                               Energy2 mass2) const {
 
   if ( spectrum()->gluonId() != ParticleID::g )
     throw Exception() << "strange enhancement only working with Standard Model hadronization"
 		      << Exception::runerror;
   
   // Flavour is assumed to be only  u, d, s,  with weights
   // (which are not normalized probabilities) given
   // by the same weights as used in HadronsSelector for
   // the decay of clusters into two hadrons.
 
     double prob_d = 0.;
     double prob_u = 0.;
     double prob_s = 0.;
     double scale = abs(double(sqr(_m0Fission)/mass2));
     // Choose which splitting weights you wish to use
 switch(_fissionCluster){
   // 0: ClusterFissioner and ClusterDecayer use the same weights
   case 0:
     prob_d = _hadronSpectrum->pwtQuark(ParticleID::d);
      prob_u = _hadronSpectrum->pwtQuark(ParticleID::u);
      /* Strangeness enhancement:
         Case 1: probability scaling
         Case 2: Exponential scaling
      */
      if (_enhanceSProb == 1)
         prob_s = (_maxScale < scale) ? 0. : pow(_hadronSpectrum->pwtQuark(ParticleID::s),scale);
      else if (_enhanceSProb == 2)
         prob_s = (_maxScale < scale) ? 0. : exp(-scale);
     break;
     /* 1: ClusterFissioner uses its own unique set of weights,
        i.e. decoupled from ClusterDecayer */
   case 1:
     prob_d = _fissionPwt.find(ParticleID::d)->second;
     prob_u = _fissionPwt.find(ParticleID::u)->second;
      if (_enhanceSProb == 1)
        prob_s = (_maxScale < scale) ? 0. : pow(_fissionPwt.find(ParticleID::s)->second,scale);
      else if (_enhanceSProb == 2)
         prob_s = (_maxScale < scale) ? 0. : exp(-scale);
     break;
   default:
     assert(false);
   }
 
   int choice = UseRandom::rnd3(prob_u, prob_d, prob_s);
   long idNew = 0;
   switch (choice) {
   case 0: idNew = ThePEG::ParticleID::u; break;
   case 1: idNew = ThePEG::ParticleID::d; break;
   case 2: idNew = ThePEG::ParticleID::s; break;
   }
   newPtrPos = getParticle(idNew);
   newPtrNeg = getParticle(-idNew);
   assert (newPtrPos);
   assert(newPtrNeg);
   assert (newPtrPos->dataPtr());
   assert(newPtrNeg->dataPtr());
 
 }
 
 
 Energy2 ClusterFissioner::clustermass(const ClusterPtr & cluster) const {
   Lorentz5Momentum pIn = cluster->momentum();
   Energy2 endpointmass2 = sqr(cluster->particle(0)->mass() +
   cluster->particle(1)->mass());
   Energy2 singletm2 = pIn.m2();
   // Return either the cluster mass, or the lambda measure
   return (_massMeasure == 0) ? singletm2 : singletm2 - endpointmass2;
 }
 
 
 Energy ClusterFissioner::drawChildMass(const Energy M, const Energy m1,
 				       const Energy m2, const Energy m,
 				       const double expt, const bool soft) const {
 
   /***************************
    * This method, given in input the cluster mass Mclu of an heavy cluster C,
    * made of consituents of masses m1 and m2, draws the masses Mclu1 and Mclu2
    * of, respectively, the children cluster C1, made of constituent masses m1
    * and m, and cluster C2, of mass Mclu2 and made of constituent masses m2
    * and m. The mass is extracted from one of the two following mass
    * distributions:
    *   --- power-like ("normal" distribution)
    *                        d(Prob) / d(M^exponent) = const
    *       where the exponent can be different from the two children C1 (exp1)
    *       and C2 (exponent2).
    *   --- exponential ("soft" distribution)
    *                        d(Prob) / d(M^2) = exp(-b*M)
    *       where b = 2.0 / average.
    * Such distributions are limited below by the masses of
    * the constituents quarks, and above from the mass of decaying cluster C.
    * The choice of which of the two mass distributions to use for each of the
    * two cluster children is dictated by  iRemnant  (see below).
    * If the number of attempts to extract a pair of mass values that are
    * kinematically acceptable is above some fixed number (max_loop, see below)
    * the method gives up and returns false; otherwise, when it succeeds, it
    * returns true.
    *
    * These distributions have been modified from HERWIG:
    * Before these were:
    *      Mclu1 = m1 + (Mclu - m1 - m2)*pow( rnd(), 1.0/exponent1 );
    * The new one coded here is a more efficient version, same density
    * but taking into account 'in phase space from' beforehand
    ***************************/
   // hard cluster
   if(!soft) {
     return pow(UseRandom::rnd(pow((M-m1-m2-m)*UnitRemoval::InvE, expt),
 			      pow(m*UnitRemoval::InvE, expt)), 1./expt
 	       )*UnitRemoval::E + m1;
   }
   // Otherwise it uses a soft mass distribution
   else {
     static const InvEnergy b = 2.0 / _btClM;
     Energy max = M-m1-m2-2.0*m;
     double rmin = b*max;
     rmin = ( rmin < 50 ) ? exp(-rmin) : 0.;
     double r1;
     do {
       r1 = UseRandom::rnd(rmin, 1.0) * UseRandom::rnd(rmin, 1.0);
     }
     while (r1 < rmin);
     return m1 + m - log(r1)/b;
   }
 }
 
 Axis ClusterFissioner::sampleDirectionAligned(const Lorentz5Momentum & pQ, const Lorentz5Momentum pClu) const {
 	Lorentz5Momentum pQinCOM(pQ);
 	pQinCOM.setMass(pQ.m());
 	pQinCOM.boost( -pClu.boostVector() );        // boost from LAB to C
 	return pQinCOM.vect().unit();
 }
 
 Axis ClusterFissioner::sampleDirectionIsotropic() const {
   double cosTheta = -1 + 2.0 * UseRandom::rnd();
   double sinTheta = sqrt(1.0-cosTheta*cosTheta);
   double Phi = 2.0 * Constants::pi * UseRandom::rnd();
   Axis uClusterUniform(cos(Phi)*cosTheta, sin(Phi)*cosTheta, sinTheta);
   return uClusterUniform.unit();
 }
 Axis ClusterFissioner::sampleDirectionSemiUniform(const Lorentz5Momentum & pQ, const Lorentz5Momentum pClu) const {
   Axis dir = sampleDirectionAligned(pQ,pClu);
   Axis res;
   do {
 	  res=sampleDirectionIsotropic();
   }
   while (dir*res<0);
   return res;
 }
 /* SQME for p1,p2->C1(q1,q),C2(q2,qbar) 
  * Note that:
  *      p0Q1  -> p1
  *      p0Q2  -> p2
  *      pQ1   -> q1
  *      pQone -> q
  *      pQ2   -> q2
  *      pQone -> qbar
  * */
 double ClusterFissioner::calculateSQME(
 		const Lorentz5Momentum & p1,
 		const Lorentz5Momentum & p2,
 		const Lorentz5Momentum & q1,
 		const Lorentz5Momentum & q,
 		const Lorentz5Momentum & q2,
 		const Lorentz5Momentum & qbar) const {
 	double SQME;
 	switch (_matrixElement)
 	{
 		case 0:
 				SQME = 1.0;
 				break;
 		case 1:
 			{
 				// Energy2 p1p2 = p1*p2;
 				Energy2 q1q2    = q1 * q2;
 				Energy2 q1q     = q1 * q ;
 				Energy2 q2qbar  = q2 * qbar;
 				Energy2 q2q     = q2 * q ;
 				Energy2 q1qbar  = q1 * qbar;
 				Energy2 qqbar   = q  * qbar;
 				Energy2 mq2 = q.mass2();
 				double Numerator = q1q2 * (qqbar + mq2)/sqr(GeV2);
 				Numerator += 0.5 * (q1q - q1qbar)*(q2q - q2qbar)/sqr(GeV2);
 				double Denominator = sqr(qqbar + mq2)*(q1q + q1qbar)*(q2q + q2qbar)/sqr(sqr(GeV2));
 				SQME = Numerator/Denominator;
 				break;
 			}
 		default:
 			assert(false);
 	}
 	if (SQME < 0) throw	Exception()
 		<< "Squared Matrix Element = "<< SQME <<" < 0 in ClusterFissioner::calculateSQME() "
 		<< Exception::runerror;
 	return SQME;
 }
 
 /* Overestimate for SQME for p1,p2->C1(q1,q),C2(q2,qbar) 
  * Note that:
  *      p0Q1  -> p1
  *      p0Q2  -> p2
  *      pQ1   -> q1
  *      pQone -> q
  *      pQ2   -> q2
  *      pQone -> qbar
  * */
 double ClusterFissioner::calculateSQME_OverEstimate(
 		const Lorentz5Momentum & p1,
 		const Lorentz5Momentum & p2,
 		const Lorentz5Momentum & q1,
 		const Lorentz5Momentum & q,
 		const Lorentz5Momentum & q2,
 		const Lorentz5Momentum & qbar) const {
 	double SQME_OverEstimate;
 	switch (_matrixElement)
 	{
 		case 0:
 				SQME_OverEstimate = 1.0;
 				break;
 		case 1:
 			{
 				// Energy2 p1p2 = p1*p2;
 				Energy2 mq2 = q .mass2();
 				Energy2 m12 = q1.mass2();
 				Energy2 m22 = q2.mass2();
 				// Energy2 M2  = sqr(p1 + p2);
 				Energy2 M2  = sqr(q1 + q + q2 + qbar);
 				Energy2 M12 = sqr(q1 + q);
 				Energy2 M22 = sqr(q2 + qbar);
 
 				Energy2 q1q     = (M12 - m12 - mq2)/2.0; // fixed by masses
 				Energy2 q2qbar  = (M22 - m22 - mq2)/2.0; // fixed by masses
 				Energy2 q1q2Max   = (M2  - M12 - M22)/2.0;
 				// Energy2 qqbarMax  = (M2  - M12 - M22)/2.0;
 				Energy2 q2qMax    = (M2  - M12 - M22)/2.0;
 				Energy2 q1qbarMax = (M2  - M12 - M22)/2.0;
 
 				// Energy2 q1q2Min   = sqrt(m12*m22);
 				// Energy2 qqbarMin  = mq2;
 				Energy2 q2qMin    = sqrt(m22*mq2);
 				Energy2 q1qbarMin = sqrt(m12*mq2);
 				
 				double Numerator = q1q2Max * (2.0*mq2)/sqr(GeV2);
 				Numerator += 0.5 * (q1q*q2qMax + q1qbarMax*q2qbar)/sqr(GeV2);
 				Numerator -= 0.5 * (q1q*q2qbar + q1qbarMin*q2qMin)/sqr(GeV2);
 				double Denominator = sqr(2.0*mq2)*(q1q + q1qbarMin)*(q2qMin + q2qbar)/sqr(sqr(GeV2));
 				SQME_OverEstimate = Numerator/Denominator;
 				if (SQME_OverEstimate < 0) throw	Exception()
 					<< "Squared Matrix Element_Overestimate = "<< SQME_OverEstimate <<" < 0 in ClusterFissioner::calculateSQME_OverEstimate()\n"
 						<< "\tM  = " << sqrt(M2)/GeV 
 						<< "\tM1 = " << sqrt(M12)/GeV 
 						<< "\tM2 = " << sqrt(M22)/GeV 
 						<< "\n\tm1 = " << sqrt(m12)/GeV 
 						<< "\tm2 = " << sqrt(m22)/GeV 
 						<< "\tm  = " << sqrt(mq2)/GeV 
 						<< Exception::runerror;
 				break;
 			}
 		default:
 			assert(false);
 	}
 	return SQME_OverEstimate;
 }
 
 bool ClusterFissioner::drawKinematics(const Lorentz5Momentum & pClu,
 					   const Lorentz5Momentum & p0Q1,
 					   const Lorentz5Momentum & p0Q2,
 					   const bool toHadron1,
 					   const bool toHadron2,
 					   Lorentz5Momentum & pClu1,
 					   Lorentz5Momentum & pClu2,
 					   Lorentz5Momentum & pQ1,
 					   Lorentz5Momentum & pQbar,
 					   Lorentz5Momentum & pQ,
 					   Lorentz5Momentum & pQ2bar) const {
   if (pClu.mass() < pClu1.mass() + pClu2.mass()
 		  || pClu1.mass()<ZERO
 		  || pClu2.mass()<ZERO  ) {
     throw Exception() << "Impossible Kinematics in ClusterFissioner::drawKinematics() (A)"
 		      << Exception::eventerror;
   }
 
 	// Sample direction of the daughter clusters
 	Axis DirToClu = sampleDirectionCluster(p0Q1, pClu);
 	if (_covariantBoost) {
 		const Energy M  = pClu.mass();
 		const Energy M1 = pClu1.mass();
 		const Energy M2 = pClu2.mass();
 		const Energy PcomClu=Kinematics::pstarTwoBodyDecay(M,M1,M2);
 		Momentum3 pClu1sampVect( PcomClu*DirToClu);
 		Momentum3 pClu2sampVect(-PcomClu*DirToClu);
 		pClu1.setMass(M1);
 		pClu1.setVect(pClu1sampVect);
 		pClu1.rescaleEnergy();
 		pClu2.setMass(M2);
 		pClu2.setVect(pClu2sampVect);
 		pClu2.rescaleEnergy();
 	}
 	else {
 		Kinematics::twoBodyDecay(pClu, pClu1.mass(), pClu2.mass(),DirToClu, pClu1, pClu2);
 	}
 	// In the case that cluster1 does not decay immediately into a single hadron,
 	// calculate the momenta of Q1 (as constituent of C1) and Qbar in the
 	// (parent) C1 frame first, where the direction of Q1 is u.vect().unit(),
 	// and then boost back in the LAB frame.
 	if(!toHadron1) {
 		if (pClu1.m() < pQ1.mass() + pQbar.mass() ) {
 			throw Exception() << "Impossible Kinematics in ClusterFissioner::drawKinematics() (B)"
 				<< Exception::eventerror;
 		}
 		Axis DirClu1;
 		switch (_phaseSpaceSampler)
 		{
 			case 0:
 				// Default aligned
 				DirClu1 = _covariantBoost ? pClu1.vect().unit():sampleDirectionAligned(pClu1, pClu);
 				break;
 			case 1:
 				// Isotropic
 				DirClu1 = sampleDirectionIsotropic();
 				break;
 			case 2:
 				// Isotropic
 				DirClu1 = sampleDirectionIsotropic();
 				break;
 			default:
 				assert(false);  
 		}
 
 
 		// Need to boost constituents first into the pClu rest frame
 		//  boost from Cluster1 rest frame to Cluster COM Frame
 		Kinematics::twoBodyDecay(pClu1, pQ1.mass(), pQbar.mass(), DirClu1, pQ1, pQbar);
 	}
 
 	// In the case that cluster2 does not decay immediately into a single hadron,
 	// Calculate the momenta of Q and Q2bar (as constituent of C2) in the
 	// (parent) C2 frame first, where the direction of Q is u.vect().unit(),
 	// and then boost back in the LAB frame.
 	if(!toHadron2) {
 		if (pClu2.m() < pQ.mass() + pQ2bar.mass() ) {
 			throw Exception() << "Impossible Kinematics in ClusterFissioner::drawKinematics() (C)"
 				<< Exception::eventerror;
 		}
 		Axis DirClu2;
 		switch (_phaseSpaceSampler)
 		{
 			case 0:
 				// Default aligned
 					DirClu2 = _covariantBoost ? pClu2.vect().unit():sampleDirectionAligned(pClu2, pClu);
 				break;
 			case 1:
 				// Isotropic
 				DirClu2 = sampleDirectionIsotropic();
 				break;
 			case 2:
 				// Isotropic
 				DirClu2 = sampleDirectionIsotropic();
 				break;
 			default:
 				assert(false);  
 		}
 
 		//  boost from Cluster2 rest frame to Cluster COM Frame 
 		Kinematics::twoBodyDecay(pClu2, pQ.mass(), pQ2bar.mass(), DirClu2, pQ, pQ2bar);
 	}
 	// Boost all momenta from the Cluster COM frame to the Lab frame
 	if (_covariantBoost) {
 			std::vector<Lorentz5Momentum *> momenta;
 			momenta.push_back(&pClu1);
 			momenta.push_back(&pClu2);
 			if (!toHadron1) {
 				momenta.push_back(&pQ1);
 				momenta.push_back(&pQbar);
 			}
 			if (!toHadron2) {
 				momenta.push_back(&pQ);
 				momenta.push_back(&pQ2bar);
 			}
 			Kinematics::BoostIntoTwoParticleFrame(pClu.mass(),p0Q1, p0Q2, momenta);
 
 	}
 	return false; // success
 }
 void ClusterFissioner::calculateKinematics(const Lorentz5Momentum & pClu,
 					   const Lorentz5Momentum & p0Q1,
 					   const bool toHadron1,
 					   const bool toHadron2,
 					   Lorentz5Momentum & pClu1,
 					   Lorentz5Momentum & pClu2,
 					   Lorentz5Momentum & pQ1,
 					   Lorentz5Momentum & pQbar,
 					   Lorentz5Momentum & pQ,
 					   Lorentz5Momentum & pQ2bar) const {
 
   /******************
    * This method solves the kinematics of the two body cluster decay:
    *    C (Q1 Q2bar)  --->  C1 (Q1 Qbar)  +  C2 (Q Q2bar)
    * In input we receive the momentum of C, pClu, and the momentum
    * of the quark Q1 (constituent of C), p0Q1, both in the LAB frame.
    * Furthermore, two boolean variables inform whether the two fission
    * products (C1, C2) decay immediately into a single hadron (in which
    * case the cluster itself is identify with that hadron) and we do
    * not have to solve the kinematics of the components (Q1,Qbar) for
    * C1 and (Q,Q2bar) for C2.
    * The output is given by the following momenta (all 5-components,
    * and all in the LAB frame):
    *   pClu1 , pClu2   respectively of   C1 , C2
    *   pQ1 , pQbar     respectively of   Q1 , Qbar  in  C1
    *   pQ  , pQ2bar    respectively of   Q  , Q2    in  C2
    * The assumption, suggested from the string model, is that, in C frame,
    * C1 and its constituents Q1 and Qbar are collinear, and collinear to
    * the direction of Q1 in C (that is before cluster decay); similarly,
    * (always in the C frame) C2 and its constituents Q and Q2bar are
    * collinear (and therefore anti-collinear with C1,Q1,Qbar).
    * The solution is then obtained by using Lorentz boosts, as follows.
    * The kinematics of C1 and C2 is solved in their parent C frame,
    * and then boosted back in the LAB. The kinematics of Q1 and Qbar
    * is solved in their parent C1 frame and then boosted back in the LAB;
    * similarly, the kinematics of Q and Q2bar is solved in their parent
    * C2 frame and then boosted back in the LAB. In each of the three
    * "two-body decay"-like cases, we use the fact that the direction
    * of the motion of the decay products is known in the rest frame of
    * their parent. This is obvious for the first case in which the
    * parent rest frame is C; but it is also true in the other two cases
    * where the rest frames are C1 and C2. This is because C1 and C2
    * are boosted w.r.t. C in the same direction where their components,
    * respectively (Q1,Qbar) and (Q,Q2bar) move in C1 and C2 rest frame
    * respectively.
    * Of course, although the notation used assumed that C = (Q1 Q2bar)
    * where Q1 is a quark and Q2bar an antiquark, indeed everything remain
    * unchanged also in all following cases:
    *  Q1 quark, Q2bar antiquark;           --> Q quark;
    *  Q1 antiquark , Q2bar quark;          --> Q antiquark;
    *  Q1 quark, Q2bar diquark;             --> Q quark
    *  Q1 antiquark, Q2bar anti-diquark;    --> Q antiquark
    *  Q1 diquark, Q2bar quark              --> Q antiquark
    *  Q1 anti-diquark, Q2bar antiquark;    --> Q quark
    **************************/
 
   // Calculate the unit three-vector, in the C frame, along which
   // all of the constituents and children clusters move.
   Lorentz5Momentum u(p0Q1);
   u.boost( -pClu.boostVector() );        // boost from LAB to C
   // the unit three-vector is then  u.vect().unit()
 
   // Calculate the momenta of C1 and C2 in the (parent) C frame first,
   // where the direction of C1 is u.vect().unit(), and then boost back in the
   // LAB frame.
 
   if (pClu.m() < pClu1.mass() + pClu2.mass() ) {
     throw Exception() << "Impossible Kinematics in ClusterFissioner::calculateKinematics() (A)"
 		      << Exception::eventerror;
   }
   Kinematics::twoBodyDecay(pClu, pClu1.mass(), pClu2.mass(),
 			   u.vect().unit(), pClu1, pClu2);
 
   // In the case that cluster1 does not decay immediately into a single hadron,
   // calculate the momenta of Q1 (as constituent of C1) and Qbar in the
   // (parent) C1 frame first, where the direction of Q1 is u.vect().unit(),
   // and then boost back in the LAB frame.
   if(!toHadron1) {
     if (pClu1.m() < pQ1.mass() + pQbar.mass() ) {
       throw Exception() << "Impossible Kinematics in ClusterFissioner::calculateKinematics() (B)"
 			<< Exception::eventerror;
     }
     Kinematics::twoBodyDecay(pClu1, pQ1.mass(), pQbar.mass(),
 			     u.vect().unit(), pQ1, pQbar);
   }
 
   // In the case that cluster2 does not decay immediately into a single hadron,
   // Calculate the momenta of Q and Q2bar (as constituent of C2) in the
   // (parent) C2 frame first, where the direction of Q is u.vect().unit(),
   // and then boost back in the LAB frame.
   if(!toHadron2) {
     if (pClu2.m() < pQ.mass() + pQ2bar.mass() ) {
       throw Exception() << "Impossible Kinematics in ClusterFissioner::calculateKinematics() (C)"
 			<< Exception::eventerror;
     }
     Kinematics::twoBodyDecay(pClu2, pQ.mass(), pQ2bar.mass(),
 			     u.vect().unit(), pQ, pQ2bar);
   }
 }
 
 
 void ClusterFissioner::calculatePositions(const Lorentz5Momentum & pClu,
 					  const LorentzPoint & positionClu,
 					  const Lorentz5Momentum & pClu1,
 					  const Lorentz5Momentum & pClu2,
 					  LorentzPoint & positionClu1,
 					  LorentzPoint & positionClu2) const {
   // Determine positions of cluster children.
   // See Marc Smith's thesis, page 127, formulas (4.122) and (4.123).
   Energy Mclu  = pClu.m();
   Energy Mclu1 = pClu1.m();
   Energy Mclu2 = pClu2.m();
 
   // Calculate the unit three-vector, in the C frame, along which
   // children clusters move.
   Lorentz5Momentum u(pClu1);
   u.boost( -pClu.boostVector() );        // boost from LAB to C frame
 
   // the unit three-vector is then  u.vect().unit()
 
   Energy pstarChild = Kinematics::pstarTwoBodyDecay(Mclu,Mclu1,Mclu2);
 
   // First, determine the relative positions of the children clusters
   // in the parent cluster reference frame.
 
   Energy2 mag2 = u.vect().mag2();
   InvEnergy fact = mag2>ZERO ? 1./sqrt(mag2) : 1./GeV;
 
   Length x1 = ( 0.25*Mclu + 0.5*( pstarChild + (sqr(Mclu2) - sqr(Mclu1))/(2.0*Mclu)))/_kappa;
   Length t1 = Mclu/_kappa - x1;
   LorentzDistance distanceClu1( x1 * fact * u.vect(), t1 );
 
   Length x2 = (-0.25*Mclu + 0.5*(-pstarChild + (sqr(Mclu2) - sqr(Mclu1))/(2.0*Mclu)))/_kappa;
   Length t2 = Mclu/_kappa + x2;
   LorentzDistance distanceClu2( x2 * fact * u.vect(), t2 );
 
   // Then, transform such relative positions from the parent cluster
   // reference frame to the Lab frame.
   distanceClu1.boost( pClu.boostVector() );
   distanceClu2.boost( pClu.boostVector() );
 
   // Finally, determine the absolute positions in the Lab frame.
   positionClu1 = positionClu + distanceClu1;
   positionClu2 = positionClu + distanceClu2;
 
 }
 
 bool ClusterFissioner::ProbablityFunction(double scale, double threshold) {
   double cut = UseRandom::rnd(0.0,1.0);
   return 1./(1.+pow(abs((threshold-_probShift)/scale),_probPowFactor)) > cut ? true : false;
 }
 
 bool ClusterFissioner::isHeavy(tcClusterPtr clu) {
   // particle data for constituents
   tcPDPtr cptr[3]={tcPDPtr(),tcPDPtr(),tcPDPtr()};
   for(size_t ix=0;ix<min(clu->numComponents(),3);++ix) {
     cptr[ix]=clu->particle(ix)->dataPtr();
   }
   // different parameters for exotic, bottom and charm clusters
   double clpow = !spectrum()->isExotic(cptr[0],cptr[1],cptr[1]) ? _clPowLight : _clPowExotic;
   Energy clmax = !spectrum()->isExotic(cptr[0],cptr[1],cptr[1]) ? _clMaxLight : _clMaxExotic;
   for ( const long& id : spectrum()->heavyHadronizingQuarks() ) {
     if ( spectrum()->hasHeavy(id,cptr[0],cptr[1],cptr[1]) ) {
       clpow = _clPowHeavy[id];
       clmax = _clMaxHeavy[id];
     }
   }
    // required test for SUSY clusters, since aboveCutoff alone
   // cannot guarantee (Mc > m1 + m2 + 2*m) in cut()
   static const Energy minmass
     = getParticleData(ParticleID::d)->constituentMass();
   bool aboveCutoff = false, canSplitMinimally = false;
   // static kinematic threshold
   if(_kinematicThresholdChoice == 0) {
     aboveCutoff = (
     	      pow(clu->mass()*UnitRemoval::InvE , clpow)
     	      >
     	      pow(clmax*UnitRemoval::InvE, clpow)
     	      + pow(clu->sumConstituentMasses()*UnitRemoval::InvE, clpow)
     	      );
 
     canSplitMinimally = clu->mass() > clu->sumConstituentMasses() + 2.0 * minmass;
   }
   // dynamic kinematic threshold
   else if(_kinematicThresholdChoice == 1) {
     //some smooth probablity function to create a dynamic thershold
     double scale     = pow(clu->mass()/GeV , clpow);
     double threshold = pow(clmax/GeV, clpow)
                      + pow(clu->sumConstituentMasses()/GeV, clpow);
     aboveCutoff = ProbablityFunction(scale,threshold);
 
     scale     = clu->mass()/GeV;
     threshold = clu->sumConstituentMasses()/GeV + 2.0 * minmass/GeV;
 
     canSplitMinimally = ProbablityFunction(scale,threshold);
   }
 
   return aboveCutoff && canSplitMinimally;
 }
diff --git a/Hadronization/ClusterHadronizationHandler.cc b/Hadronization/ClusterHadronizationHandler.cc
--- a/Hadronization/ClusterHadronizationHandler.cc
+++ b/Hadronization/ClusterHadronizationHandler.cc
@@ -1,593 +1,590 @@
 // -*- C++ -*-
 //
 // ClusterHadronizationHandler.cc is a part of Herwig - A multi-purpose Monte Carlo event generator
 // Copyright (C) 2002-2019 The Herwig Collaboration
 //
 // Herwig is licenced under version 3 of the GPL, see COPYING for details.
 // Please respect the MCnet academic guidelines, see GUIDELINES for details.
 //
 //
 // This is the implementation of the non-inlined, non-templated member
 // functions of the ClusterHadronizationHandler class.
 //
 
 #include "ClusterHadronizationHandler.h"
 #include <ThePEG/Interface/ClassDocumentation.h>
 #include <ThePEG/Persistency/PersistentOStream.h>
 #include <ThePEG/Persistency/PersistentIStream.h>
 #include <ThePEG/Interface/Switch.h>
 #include <ThePEG/Interface/Parameter.h>
 #include <ThePEG/Interface/Reference.h>
 #include <ThePEG/Handlers/EventHandler.h>
 #include <ThePEG/Handlers/Hint.h>
 #include <ThePEG/PDT/ParticleData.h>
 #include <ThePEG/EventRecord/Particle.h>
 #include <ThePEG/EventRecord/Step.h>
 #include <ThePEG/PDT/PDT.h>
 #include <ThePEG/PDT/EnumParticles.h>
 #include <ThePEG/Utilities/Throw.h>
 #include "Herwig/Utilities/EnumParticles.h"
 #include "CluHadConfig.h"
 #include "Cluster.h"
 #include <ThePEG/Utilities/DescribeClass.h>
 #include <ThePEG/Interface/Command.h>
 
 using namespace Herwig;
 
 ClusterHadronizationHandler * ClusterHadronizationHandler::currentHandler_ = 0;
 
 DescribeClass<ClusterHadronizationHandler,HadronizationHandler>
 describeClusterHadronizationHandler("Herwig::ClusterHadronizationHandler","Herwig.so");
 
 IBPtr ClusterHadronizationHandler::clone() const {
   return new_ptr(*this);
 }
 
 IBPtr ClusterHadronizationHandler::fullclone() const {
   return new_ptr(*this);
 }
 
 void ClusterHadronizationHandler::persistentOutput(PersistentOStream & os)
   const {
   os << _partonSplitters << _clusterFinders << _colourReconnectors
      << _clusterFissioners << _lightClusterDecayers << _clusterDecayers
      << _gluonMassGenerators
      << _partonSplitter << _clusterFinder << _colourReconnector
      << _clusterFissioner << _lightClusterDecayer << _clusterDecayer
      << reshuffle_ << _gluonMassGenerator
      << ounit(_minVirtuality2,GeV2) << ounit(_maxDisplacement,mm)
      << _underlyingEventHandler << _reduceToTwoComponents;
 }
 
 
 void ClusterHadronizationHandler::persistentInput(PersistentIStream & is, int) {
   is >> _partonSplitters >> _clusterFinders >> _colourReconnectors
      >> _clusterFissioners >> _lightClusterDecayers >> _clusterDecayers
      >> _gluonMassGenerators
      >> _partonSplitter >> _clusterFinder >> _colourReconnector
      >> _clusterFissioner >> _lightClusterDecayer >> _clusterDecayer
      >> reshuffle_ >> _gluonMassGenerator
      >> iunit(_minVirtuality2,GeV2) >> iunit(_maxDisplacement,mm)
      >> _underlyingEventHandler >> _reduceToTwoComponents;
 }
 
 
 void ClusterHadronizationHandler::Init() {
 
   static ClassDocumentation<ClusterHadronizationHandler> documentation
     ("This is the main handler class for the Cluster Hadronization",
      "The hadronization was performed using the cluster model of \\cite{Webber:1983if}.",
      "%\\cite{Webber:1983if}\n"
      "\\bibitem{Webber:1983if}\n"
      "  B.~R.~Webber,\n"
      "  ``A QCD Model For Jet Fragmentation Including Soft Gluon Interference,''\n"
      "  Nucl.\\ Phys.\\  B {\\bf 238}, 492 (1984).\n"
      "  %%CITATION = NUPHA,B238,492;%%\n"
      // main manual
      );
 
 
   static Reference<ClusterHadronizationHandler,PartonSplitter>
     interfacePartonSplitter("PartonSplitter",
 			    "A reference to the PartonSplitter object",
 			    &Herwig::ClusterHadronizationHandler::_partonSplitter,
 			    false, false, true, false);
 
   static Reference<ClusterHadronizationHandler,GluonMassGenerator> interfaceGluonMassGenerator
     ("GluonMassGenerator",
      "Set a reference to a gluon mass generator.",
      &ClusterHadronizationHandler::_gluonMassGenerator, false, false, true, true, false);
 
   static Switch<ClusterHadronizationHandler,int> interfaceReshuffle
     ("Reshuffle",
      "Perform reshuffling if constituent masses have not yet been included by the shower",
      &ClusterHadronizationHandler::reshuffle_, 0, false, false);
   static SwitchOption interfaceReshuffleColourConnected
     (interfaceReshuffle,
      "ColourConnected",
      "Separate reshuffling for colour connected partons.",
      2);
   static SwitchOption interfaceReshuffleGlobal
     (interfaceReshuffle,
      "Global",
      "Reshuffle globally.",
      1);
   static SwitchOption interfaceReshuffleNo
     (interfaceReshuffle,
      "No",
      "Do not reshuffle.",
      0);
 
   static Reference<ClusterHadronizationHandler,ClusterFinder>
     interfaceClusterFinder("ClusterFinder",
 		      "A reference to the ClusterFinder object",
 		      &Herwig::ClusterHadronizationHandler::_clusterFinder,
 		      false, false, true, false);
 
   static Reference<ClusterHadronizationHandler,ColourReconnector>
     interfaceColourReconnector("ColourReconnector",
 		      "A reference to the ColourReconnector object",
 		      &Herwig::ClusterHadronizationHandler::_colourReconnector,
 		      false, false, true, false);
 
   static Reference<ClusterHadronizationHandler,ClusterFissioner>
     interfaceClusterFissioner("ClusterFissioner",
 		      "A reference to the ClusterFissioner object",
 		      &Herwig::ClusterHadronizationHandler::_clusterFissioner,
 		      false, false, true, false);
 
   static Reference<ClusterHadronizationHandler,LightClusterDecayer>
     interfaceLightClusterDecayer("LightClusterDecayer",
 		    "A reference to the LightClusterDecayer object",
 		    &Herwig::ClusterHadronizationHandler::_lightClusterDecayer,
 		    false, false, true, false);
 
   static Reference<ClusterHadronizationHandler,ClusterDecayer>
     interfaceClusterDecayer("ClusterDecayer",
 		       "A reference to the ClusterDecayer object",
 		       &Herwig::ClusterHadronizationHandler::_clusterDecayer,
 		       false, false, true, false);
 
   // functions to move the handlers so they are set
   
   
   static Parameter<ClusterHadronizationHandler,Energy2> interfaceMinVirtuality2
     ("MinVirtuality2",
      "Minimum virtuality^2 of partons to use in calculating distances  (unit [GeV2]).",
      &ClusterHadronizationHandler::_minVirtuality2, GeV2, 0.1*GeV2, ZERO, 10.0*GeV2,false,false,false);
 
   static Parameter<ClusterHadronizationHandler,Length> interfaceMaxDisplacement
     ("MaxDisplacement",
      "Maximum displacement that is allowed for a particle  (unit [millimeter]).",
      &ClusterHadronizationHandler::_maxDisplacement, mm, 1.0e-10*mm,
      0.0*mm, 1.0e-9*mm,false,false,false);
 
   static Reference<ClusterHadronizationHandler,StepHandler> interfaceUnderlyingEventHandler
     ("UnderlyingEventHandler",
      "Pointer to the handler for the Underlying Event. "
      "Set to NULL to disable.",
      &ClusterHadronizationHandler::_underlyingEventHandler, false, false, true, true, false);
 
    static Switch<ClusterHadronizationHandler,bool> interfaceReduceToTwoComponents
     ("ReduceToTwoComponents",
      "Whether or not to reduce three component baryon-number violating clusters to two components before cluster splitting or leave"
      " this till after the cluster splitting",
      &ClusterHadronizationHandler::_reduceToTwoComponents, true, false, false);
   static SwitchOption interfaceReduceToTwoComponentsYes
     (interfaceReduceToTwoComponents,
      "BeforeSplitting",
      "Reduce to two components",
      true);
   static SwitchOption interfaceReduceToTwoComponentsNo
     (interfaceReduceToTwoComponents,
      "AfterSplitting",
      "Treat as three components",
      false);
 
   static Command<ClusterHadronizationHandler> interfaceUseHandlersForInteraction
     ("UseHandlersForInteraction",
      "Use the current set of handlers for the given interaction.",
      &ClusterHadronizationHandler::_setHandlersForInteraction, false);
 
 }
 
 void ClusterHadronizationHandler::rebind(const TranslationMap & trans) {
   for (auto iter : _partonSplitters) {
      _partonSplitters[iter.first] = trans.translate(iter.second);
   }
   for (auto iter : _clusterFinders) {
      _clusterFinders[iter.first] = trans.translate(iter.second);
   }
   for (auto iter : _colourReconnectors) {
      _colourReconnectors[iter.first] = trans.translate(iter.second);
   }
   for (auto iter : _clusterFissioners) {
      _clusterFissioners[iter.first] = trans.translate(iter.second);
   }
   for (auto iter : _lightClusterDecayers) {
      _lightClusterDecayers[iter.first] = trans.translate(iter.second);
   }
   for (auto iter : _clusterDecayers) {
      _clusterDecayers[iter.first] = trans.translate(iter.second);
   }
   for (auto iter : _gluonMassGenerators) {
      _gluonMassGenerators[iter.first] = trans.translate(iter.second);
   }
   HandlerBase::rebind(trans);
 }
 
 IVector ClusterHadronizationHandler::getReferences() {
   IVector ret = HandlerBase::getReferences();
   for (auto iter : _partonSplitters) {
      ret.push_back(iter.second);
   }
   for (auto iter : _clusterFinders) {
      ret.push_back(iter.second);
   }
   for (auto iter : _colourReconnectors) {
      ret.push_back(iter.second);
   }
   for (auto iter : _clusterFissioners) {
      ret.push_back(iter.second);
   }
   for (auto iter : _lightClusterDecayers) {
      ret.push_back(iter.second);
   }
   for (auto iter : _clusterDecayers) {
      ret.push_back(iter.second);
   }
   for (auto iter : _gluonMassGenerators) {
      ret.push_back(iter.second);
   }
   return ret;
 }
 
 void ClusterHadronizationHandler::doinit() {
   HadronizationHandler::doinit();
   // put current handlers into action for QCD to guarantee default behaviour
   if ( _partonSplitters.empty() ) {
     _partonSplitters[PDT::ColouredQCD] = _partonSplitter;
     _clusterFinders[PDT::ColouredQCD] = _clusterFinder;
     _colourReconnectors[PDT::ColouredQCD] = _colourReconnector;
     _clusterFissioners[PDT::ColouredQCD] = _clusterFissioner;
     _lightClusterDecayers[PDT::ColouredQCD] = _lightClusterDecayer;
     _clusterDecayers[PDT::ColouredQCD] = _clusterDecayer; 
     _gluonMassGenerators[PDT::ColouredQCD] = _gluonMassGenerator; 
   }
 }
 
 string ClusterHadronizationHandler::_setHandlersForInteraction(string interaction) {
   int interactionId = -1;
   if ( interaction == " QCD" ) {
     interactionId = PDT::ColouredQCD;
   } else {
     return "unknown interaction " + interaction;
   }
   _partonSplitters[interactionId] = _partonSplitter;
   _clusterFinders[interactionId] = _clusterFinder;
   _colourReconnectors[interactionId] = _colourReconnector;
   _clusterFissioners[interactionId] = _clusterFissioner;
   _lightClusterDecayers[interactionId] = _lightClusterDecayer;
   _clusterDecayers[interactionId] = _clusterDecayer; 
   _gluonMassGenerators[interactionId] = _gluonMassGenerator; 
   return "";
 }
 
 namespace {
   void extractChildren(tPPtr p, set<PPtr> & all) {
     if (p->children().empty()) return;
 
     for (PVector::const_iterator child = p->children().begin();
 	 child != p->children().end(); ++child) {
       all.insert(*child);
       extractChildren(*child, all);
     }
   }
 }
 
 void ClusterHadronizationHandler::
 handle(EventHandler & ch, const tPVector & tagged,
        const Hint &) {
   useMe();
   currentHandler_ = this;
-  for (auto iter : _clusterFinders) {
-     iter.second->spectrum()->setGenerator(currentHandler_->generator());
-  }
 
   PVector theList(tagged.begin(),tagged.end());
   
   // set the scale for coloured particles to just above the gluon mass squared
   // if less than this so they are classed as perturbative
 
   // TODO: Should this be hard-coded here, or defined in inputs?
   map<int,int> interactions = {{PDT::ColouredQCD, ParticleID::g}};
   
   // PVector currentlist(tagged.begin(),tagged.end());
   map<int,PVector> currentlists;
   for ( const auto & p : theList ) {
     for ( auto i : interactions ) {
       if ( p->data().colouredInteraction() == i.first ) {
 	currentlists[i.first].push_back(p);
     Energy2 Q02 = 1.01*sqr(getParticleData(i.second)->constituentMass());
 	if(currentlists[i.first].back()->scale()<Q02) currentlists[i.first].back()->scale(Q02);
       }
     }
   }
 
   map<int,ClusterVector> clusters;
 
   // ATTENTION this needs to have changes to include the new hadron spectrum functionality (gluon mass generator)
   for ( auto i : interactions ) {
 
     // reshuffle to the constituents
     if ( reshuffle_ ) {
     
       vector<PVector> reshufflelists;
 
       if ( reshuffle_ == 1 ) { // global reshuffling
 	reshufflelists.push_back(currentlists[i.first]);
       }
       else if ( reshuffle_ == 2 ) {// colour connected reshuffling
 	splitIntoColourSinglets(currentlists[i.first], reshufflelists, i.first);
       }
 
       Ptr<GluonMassGenerator>::ptr gMassGenerator;
       auto git = _gluonMassGenerators.find(i.first);
       if ( git != _gluonMassGenerators.end() )
 	gMassGenerator = git->second;
 
       for (auto currentlist : reshufflelists){
 	// get available energy and energy needed for constituent mass shells
 	LorentzMomentum totalQ;
 	Energy needQ = ZERO;
 	size_t nGluons = 0; // number of gluons for which a mass need be generated
 	for ( auto p : currentlist ) {
 	  totalQ += p->momentum();
 	  if ( p->id() == i.second && gMassGenerator ) {
 	    ++nGluons;
 	    needQ += gMassGenerator->minGluonMass();
 	    continue;
 	  }
 	  needQ += p->dataPtr()->constituentMass();
 	}
 	Energy Q = totalQ.m();
 	if ( needQ > Q )
 	  throw Exception() << "cannot reshuffle to constituent mass shells" << Exception::eventerror;
 
 	// generate gluon masses if needed
 	list<Energy> gluonMasses;
 	if ( nGluons && gMassGenerator )
 	  gluonMasses = gMassGenerator->generateMany(nGluons,Q-needQ);
 
 	// set masses for inidividual particles
 	vector<Energy> masses;
 	for ( auto p : currentlist ) {
 	  if ( p->id() == i.second && gMassGenerator ) {
 	    list<Energy>::const_iterator it = gluonMasses.begin();
 	    advance(it,UseRandom::irnd(gluonMasses.size()));
 	    masses.push_back(*it);
 	    gluonMasses.erase(it);
 	  } 
 	  else {
 	    masses.push_back(p->dataPtr()->constituentMass());
 	  }
 	}
 
 	// reshuffle to new masses
 	reshuffle(currentlist,masses);
 
       }
 
     }
 
     // split the gluons
     if ( !currentlists[i.first].empty() ) {
       assert(_partonSplitters.find(i.first) != _partonSplitters.end());
       _partonSplitters[i.first]->split(currentlists[i.first]);
     }
 
     // form the clusters
     if ( !currentlists[i.first].empty() ) {
       assert(_clusterFinders.find(i.first) != _clusterFinders.end());
       clusters[i.first] = _clusterFinders[i.first]->formClusters(currentlists[i.first]);
       // reduce BV clusters to two components now if needed
       if(_reduceToTwoComponents)
 	_clusterFinders[i.first]->reduceToTwoComponents(clusters[i.first]);
     }
   }
 
   // perform colour reconnection if needed and then
   // decay the clusters into one hadron
   for ( auto i : interactions ) {
     if ( clusters[i.first].empty() )
       continue;
     bool lightOK = false;
     short tried = 0;
     const ClusterVector savedclusters = clusters[i.first];
     tPVector finalHadrons; // only needed for partonic decayer
     while (!lightOK && tried++ < 10) {
       // no colour reconnection with baryon-number-violating (BV) clusters
       ClusterVector CRclusters, BVclusters;
       CRclusters.reserve( clusters[i.first].size() );
       BVclusters.reserve( clusters[i.first].size() );
       for (size_t ic = 0; ic < clusters[i.first].size(); ++ic) {
 	ClusterPtr cl = clusters[i.first].at(ic);
 	bool hasClusterParent = false;
 	for (unsigned int ix=0; ix < cl->parents().size(); ++ix) {
 	  if (cl->parents()[ix]->id() == ParticleID::Cluster) {
 	    hasClusterParent = true;
 	    break;
 	  }
 	}
 	if (cl->numComponents() > 2 || hasClusterParent) BVclusters.push_back(cl);
 	else CRclusters.push_back(cl);
       }
 
       // colour reconnection
       assert(_colourReconnectors.find(i.first) != _colourReconnectors.end());
       _colourReconnectors[i.first]->rearrange(CRclusters);
 
 
       // tag new clusters as children of the partons to hadronize
       _setChildren(CRclusters);
     
    
       // forms diquarks
       // we should already have used  _clusterFinder[i.first]
       _clusterFinders[i.first]->reduceToTwoComponents(CRclusters);
     
       // recombine vectors of (possibly) reconnected and BV clusters
       clusters[i.first].clear();
       clusters[i.first].insert( clusters[i.first].end(), CRclusters.begin(), CRclusters.end() );
       clusters[i.first].insert( clusters[i.first].end(), BVclusters.begin(), BVclusters.end() );
 
       // fission of heavy clusters
       // NB: during cluster fission, light hadrons might be produced straight away
       assert(_clusterFissioners.find(i.first) != _clusterFissioners.end());
       finalHadrons = _clusterFissioners[i.first]->fission(clusters[i.first],i.first == PDT::ColouredQCD ? isSoftUnderlyingEventON() : false);
 
 
       // if clusters not previously reduced to two components do it now
       if(!_reduceToTwoComponents)
 	_clusterFinders[i.first]->reduceToTwoComponents(clusters[i.first]);
       assert(_lightClusterDecayers.find(i.first) != _lightClusterDecayers.end());
       lightOK = _lightClusterDecayers[i.first]->decay(clusters[i.first],finalHadrons);
       // if the decay of the light clusters was not successful, undo the cluster
       // fission and decay steps and revert to the original state of the event
       // record
       if (!lightOK) {
 				// std::cout << "failed LightClusterDecayer " << std::endl;
 	clusters[i.first] = savedclusters;
 	for_each(clusters[i.first].begin(),
 		 clusters[i.first].end(),
 		 std::mem_fn(&Particle::undecay));
       }
     }
     if (!lightOK) {
       throw Exception( "CluHad::handle(): tried LightClusterDecayer 10 times!",
 		       Exception::eventerror);
     }
 
     // decay the remaining clusters
     assert(_clusterDecayers[i.first]);
     _clusterDecayers[i.first]->decay(clusters[i.first],finalHadrons);
     
   }
 
   // *****************************************
   // *****************************************
   // *****************************************
 
   bool finalStateCluster=false;
   StepPtr pstep = newStep();
   set<PPtr> allDecendants;
   for (tPVector::const_iterator it = tagged.begin();
        it != tagged.end(); ++it) {
     extractChildren(*it, allDecendants);
   }
 
   for(set<PPtr>::const_iterator it = allDecendants.begin();
       it != allDecendants.end(); ++it) {
     // this is a workaround because the set sometimes
     // re-orders parents after their children
     if ((*it)->children().empty()){
       // If there is a cluster in the final state throw an event error
       if((*it)->id()==81) {
          finalStateCluster=true;
       }
       pstep->addDecayProduct(*it);
     }
     else {
       pstep->addDecayProduct(*it);
       pstep->addIntermediate(*it);
     }
   }
 
   // For very small center of mass energies it might happen that baryonic clusters cannot decay into hadrons
   if (finalStateCluster){
      throw Exception( "CluHad::Handle(): Cluster in the final state", 
                      Exception::eventerror);
   }
   // *****************************************
   // *****************************************
   // *****************************************
 
   // soft underlying event if needed
   if (isSoftUnderlyingEventON()) {
     assert(_underlyingEventHandler);
     ch.performStep(_underlyingEventHandler,Hint::Default());
   }
 }
 
 
 // Sets parent child relationship of all clusters with two components
 // Relationships for clusters with more than two components are set elsewhere in the Colour Reconnector
 void ClusterHadronizationHandler::_setChildren(const ClusterVector & clusters) const {
   // erase existing information about the partons' children
   tPVector partons;
   for ( const auto & cl : clusters ) {
     if ( cl->numComponents() > 2 ) continue;
     partons.push_back( cl->colParticle() );
     partons.push_back( cl->antiColParticle() );
   }
   // erase all previous information about parent child relationship
   for_each(partons.begin(), partons.end(), std::mem_fn(&Particle::undecay));
 
   // give new parents to the clusters: their constituents
   for ( const auto & cl : clusters ) {
     if ( cl->numComponents() > 2 ) continue;
     cl->colParticle()->addChild(cl);
     cl->antiColParticle()->addChild(cl);
   }
 }
 
 void ClusterHadronizationHandler::splitIntoColourSinglets(PVector copylist,
 							  vector<PVector>& reshufflelists,
 							  int){
  
   PVector currentlist;
   bool gluonloop;
   PPtr firstparticle, temp;
   reshufflelists.clear();
  
   while (copylist.size()>0){
     gluonloop=false;
     currentlist.clear();
  
     firstparticle=copylist.back();  
     copylist.pop_back();     
  
     if (!firstparticle->coloured()){
       continue; //non-coloured particles are not included
     }
      
     currentlist.push_back(firstparticle);
  
     //go up the anitColourLine and check if we are in a gluon loop
     temp=firstparticle;
     while( temp->hasAntiColour()){
       temp = temp->antiColourLine()->endParticle();
       if(temp==firstparticle){
 	gluonloop=true;
 	break;
       }
       else{
 	currentlist.push_back(temp);
 	copylist.erase(remove(copylist.begin(),copylist.end(), temp), copylist.end());
       }
     }
  
     //if not a gluon loop, go up the ColourLine
     if(!gluonloop){
       temp=firstparticle;
       while( temp->hasColour()){
 	temp=temp->colourLine()->startParticle();
 	currentlist.push_back(temp);
 	copylist.erase(remove(copylist.begin(),copylist.end(), temp), copylist.end());
       }
     }
  
     reshufflelists.push_back(currentlist); 
   }
  
 }
diff --git a/Hadronization/HadronSpectrum.cc b/Hadronization/HadronSpectrum.cc
--- a/Hadronization/HadronSpectrum.cc
+++ b/Hadronization/HadronSpectrum.cc
@@ -1,612 +1,613 @@
 // -*- C++ -*-
 //
 // This is the implementation of the non-inlined, non-templated member
 // functions of the HadronSpectrum class.
 //
 
 #include "HadronSpectrum.h"
 #include "ClusterHadronizationHandler.h"
 #include "ThePEG/Interface/ClassDocumentation.h"
 #include "ThePEG/EventRecord/Particle.h"
 #include "ThePEG/Repository/UseRandom.h"
 #include "ThePEG/Repository/EventGenerator.h"
 #include "ThePEG/Utilities/DescribeClass.h"
 #include <ThePEG/Repository/CurrentGenerator.h>
 #include "Herwig/Utilities/Kinematics.h"
 
 #include "ThePEG/Interface/RefVector.h"
 
 #include "ThePEG/Persistency/PersistentOStream.h"
 #include "ThePEG/Persistency/PersistentIStream.h"
 
 using namespace Herwig;
 
 namespace {
   // debug helper
   void dumpTable(const HadronSpectrum::HadronTable & tbl) {
     typedef HadronSpectrum::HadronTable::const_iterator TableIter;
     for (TableIter it = tbl.begin(); it != tbl.end(); ++it) {
       cerr << it->first.first << ' ' 
   	   << it->first.second << '\n';
       for (HadronSpectrum::KupcoData::const_iterator jt = it->second.begin();
   	   jt != it->second.end(); ++jt) {
   	cerr << '\t' << *jt << '\n';
       }
     }
   }
 }
 
 
 HadronSpectrum::HadronSpectrum() 
   : Interfaced(),
     belowThreshold_(0),
     _repwt(Lmax,vector<vector<double> >(Jmax,vector<double>(Nmax))) {}
 
 HadronSpectrum::~HadronSpectrum() {}
 
 void HadronSpectrum::doinit() {
   Interfaced::doinit();
   // construct the hadron tables
   constructHadronTable();
   // lightest members (hadrons)
   for(const PDPtr & p1 : partons()) {
     for(const PDPtr & p2 : partons()) {
       tcPDPair lp = lightestHadronPair(p1,p2);
       if(lp.first && lp.second)
 	lightestHadrons_[make_pair(p1->id(),p2->id())] = lp;
     }
   }
   // for debugging
   if (Debug::level >= 10) 
     dumpTable(table());
 }
 
 // If needed, insert default implementations of virtual function defined
 // in the InterfacedBase class here (using ThePEG-interfaced-impl in Emacs).
 
 
 void HadronSpectrum::persistentOutput(PersistentOStream & os) const {
   os << _table << _partons << _forbidden
      << belowThreshold_ << _repwt << _pwt << lightestHadrons_;
 }
 
 void HadronSpectrum::persistentInput(PersistentIStream & is, int) {
   is >> _table >> _partons >> _forbidden
      >> belowThreshold_ >> _repwt >> _pwt >> lightestHadrons_;
 }
 
 
 // *** Attention *** The following static variable is needed for the type
 // description system in ThePEG. Please check that the template arguments
 // are correct (the class and its base class), and that the constructor
 // arguments are correct (the class name and the name of the dynamically
 // loadable library where the class implementation can be found).
 DescribeAbstractClass<HadronSpectrum,Interfaced>
   describeHerwigHadronSpectrum("Herwig::HadronSpectrum", "Herwig.so");
 
 void HadronSpectrum::Init() {
 
   static ClassDocumentation<HadronSpectrum> documentation
     ("There is no documentation for the HadronSpectrum class");
 
   static RefVector<HadronSpectrum,ParticleData> interfacePartons
     ("Partons",
      "The partons which are to be considered as the consistuents of the hadrons.",
      &HadronSpectrum::_partons, -1, false, false, true, false, false);
 
   static RefVector<HadronSpectrum,ParticleData> interfaceForbidden
     ("Forbidden",
      "The PDG codes of the particles which cannot be produced in the hadronization.",
      &HadronSpectrum::_forbidden, -1, false, false, true, false, false);
 
 }
 
 void HadronSpectrum::insertToHadronTable(tPDPtr &particle, int flav1, int flav2) {
   // inserting a new Hadron in the hadron table.
   long pid  = particle->id();
   int pspin = particle->iSpin();
   HadronInfo a(pid, particle,specialWeight(pid),particle->mass());
   // set the weight to the number of spin states
   a.overallWeight = pspin*a.swtef;
   // mesons
   if(pspin%2==1)     insertMeson(a,flav1,flav2);
   // spin-1/2 baryons
   else if(pspin==2) insertOneHalf(a,flav1,flav2);
   // spin -3/2 baryons
   else if(pspin==4) insertThreeHalf(a,flav1,flav2);
   // all other cases
   else {
     assert(false);
   }
 }
 
 void HadronSpectrum::insertOneHalf(HadronInfo a, int flav1, int flav2) {
   assert(DiquarkMatcher::Check(flav1));
   long iq1 = flav1/1000;
   long iq2 = (flav1/100)%10;
   if(iq1!=iq2 && flav1%10==3) flav1-=2;
   if(iq1==iq2) {
     if(iq1==flav2) {
       a.overallWeight *= 1.5;
       _table[make_pair(flav1,flav2)].insert(a);
       _table[make_pair(flav2,flav1)].insert(a);
     }
     else {
       _table[make_pair(flav1,flav2)].insert(a);
       _table[make_pair(flav2,flav1)].insert(a);
       long f3 = makeDiquarkID(iq1,flav2,1);
       _table[make_pair(iq1,f3 )].insert(a);
       _table[make_pair(f3 ,iq1)].insert(a);
     }
   }
   else if(iq1==flav2) {
     // ud1 u type
     _table[make_pair(flav1,flav2)].insert(a);
     _table[make_pair(flav2,flav1)].insert(a);
     // and uu1 d type
     long f3 = makeDiquarkID(iq1,iq1,3);
     a.overallWeight *= a.wt;
     _table[make_pair(f3 ,iq2)].insert(a);
     _table[make_pair(iq2, f3)].insert(a);
   }
   else if(iq2==flav2) assert(false);
   else {
     _table[make_pair(flav1,flav2)].insert(a);
     _table[make_pair(flav2,flav1)].insert(a);
     long f3 = makeDiquarkID(iq1,flav2,1);
     _table[make_pair(iq2,f3)].insert(a);
     _table[make_pair(f3,iq2)].insert(a);
     // 3rd perm
     f3 = makeDiquarkID(iq2,flav2,1);
     _table[make_pair(iq1,f3)].insert(a);
     _table[make_pair(f3,iq1)].insert(a);
   }
 }
 
 void HadronSpectrum::insertThreeHalf(HadronInfo a, int flav1, int flav2) {
   assert(DiquarkMatcher::Check(flav1));
   long iq1 = flav1/1000;
   long iq2 = (flav1/100)%10;
   if(iq1!=iq2 && flav1%10==3) flav1-=2;
   if(iq1==iq2) {
     if(iq1==flav2) {
       a.overallWeight *= 1.5;
       _table[make_pair(flav1,flav2)].insert(a);
       _table[make_pair(flav2,flav1)].insert(a);
     }
     else {
       _table[make_pair(flav1,flav2)].insert(a);
       _table[make_pair(flav2,flav1)].insert(a);
       long f3 = makeDiquarkID(iq1,flav2,1);
       _table[make_pair(iq1,f3 )].insert(a);
       _table[make_pair(f3 ,iq1)].insert(a);
     }
   }
   else if(iq1==flav2) {
     // ud1 u type
     _table[make_pair(flav1,flav2)].insert(a);
     _table[make_pair(flav2,flav1)].insert(a);
     // and uu1 d type
     long f3 = makeDiquarkID(iq1,iq1,3);
     a.overallWeight *= a.wt;
     _table[make_pair(f3 ,iq2)].insert(a);
     _table[make_pair(iq2, f3)].insert(a);
   }
   else {
     _table[make_pair(flav1,flav2)].insert(a);
     _table[make_pair(flav2,flav1)].insert(a);
     long f3 = makeDiquarkID(iq1,flav2,1);
     _table[make_pair(iq2,f3)].insert(a);
     _table[make_pair(f3,iq2)].insert(a);
     // 3rd perm
     f3 = makeDiquarkID(iq2,flav2,1);
     _table[make_pair(iq1,f3)].insert(a);
     _table[make_pair(f3,iq1)].insert(a);
   }
 }
 
 
 tcPDPtr HadronSpectrum::chooseSingleHadron(tcPDPtr par1, tcPDPtr par2,
 							Energy mass) const {
   Energy threshold = hadronPairThreshold(par1,par2);
   // only do one hadron decay if mass less than the threshold
   if(mass>=threshold) return tcPDPtr();
 
   // select the hadron
   tcPDPtr hadron;
   // old option pick the lightest hadron
   if(belowThreshold_ == 0) {
     hadron= lightestHadron(par1,par2);
   }
   // new option select from those available
   else if(belowThreshold_ == 1) {
     vector<pair<tcPDPtr,double> > hadrons = 
       hadronsBelowThreshold(threshold,par1,par2);
     if(hadrons.size()==1) {
       hadron = hadrons[0].first;
     }
     else if(hadrons.empty()) {
       hadron= lightestHadron(par1,par2);
     }
     else {
       double totalWeight=0.;
       for(unsigned int ix=0;ix<hadrons.size();++ix) {
 	totalWeight += hadrons[ix].second;
       }
       totalWeight *= UseRandom::rnd();
       for(unsigned int ix=0;ix<hadrons.size();++ix) {
 	if(totalWeight<=hadrons[ix].second) {
 	  hadron = hadrons[ix].first;
 	  break;
 	}
 	else
 	  totalWeight -= hadrons[ix].second;
       }
       assert(hadron);
     }
   }
   else
     assert(false);
   return hadron;
 }
 
 tcPDPair HadronSpectrum::chooseHadronPair(const Energy cluMass,
 					  tcPDPtr par1, tcPDPtr par2) const {
   useMe();
   // if either of the input partons is a diquark don't allow diquarks to be
   // produced
   bool isDiquark1 = DiquarkMatcher::Check(par1->id());
   bool isDiquark2 = DiquarkMatcher::Check(par2->id());
   bool noDiquarkInCluster = !(isDiquark1 || isDiquark2);
   bool oneDiquarkInCluster = (isDiquark1 != isDiquark2);
   bool quark = true;
   // decide is baryon or meson production
   if(noDiquarkInCluster) std::tie(quark,noDiquarkInCluster,oneDiquarkInCluster)
   						= selectBaryon(cluMass,par1,par2);
   // weights for the different possibilities
   Energy weight, wgtsum(ZERO);
   // loop over all hadron pairs with the allowed flavours
   static vector<Kupco> hadrons;
   hadrons.clear();
   for(unsigned int ix=0;ix<partons().size();++ix) {
     tcPDPtr quarktopick  = partons()[ix];
     if(!quark && std::find(hadronizingQuarks().begin(), hadronizingQuarks().end(),
         abs(quarktopick->id())) != hadronizingQuarks().end()) continue;
     if(DiquarkMatcher::Check(quarktopick->id()) &&
        ((!noDiquarkInCluster && quarktopick->iSpin()==1) ||
 	(!oneDiquarkInCluster && quarktopick->iSpin()==3))) continue;
     HadronTable::const_iterator
       tit1 = table().find(make_pair(abs(par1->id()),quarktopick->id()));
     HadronTable::const_iterator
       tit2 = table().find(make_pair(quarktopick->id(),abs(par2->id())));
     // If not in table skip
     if(tit1 == table().end()||tit2==table().end()) continue;
     // tables empty skip
     const KupcoData & T1 = tit1->second;
     const KupcoData & T2 = tit2->second;
     if(T1.empty()||T2.empty()) continue;
     // if too massive skip
     if(cluMass <= T1.begin()->mass +
                   T2.begin()->mass) continue;
     // quark weight
     double quarkWeight =  pwt(quarktopick->id());
     quarkWeight = specialQuarkWeight(quarkWeight,quarktopick->id(),
             cluMass,par1,par2);
     // loop over the hadrons
     KupcoData::const_iterator H1,H2;
     for(H1 = T1.begin();H1 != T1.end(); ++H1) {
       for(H2 = T2.begin();H2 != T2.end(); ++H2) {
  	// break if cluster too light
  	if(cluMass < H1->mass + H2->mass) break;
 	weight = quarkWeight * H1->overallWeight * H2->overallWeight *
 	  Kinematics::pstarTwoBodyDecay(cluMass, H1->mass, H2->mass);
 	int signQ = 0;
 	assert (par1 && quarktopick);
 	assert (par2);
 
 	assert(quarktopick->CC());
 
 	if(canBeHadron(par1, quarktopick->CC())
 	   && canBeHadron(quarktopick, par2))
 	   signQ = +1;
 	else if(canBeHadron(par1, quarktopick)
 		&& canBeHadron(quarktopick->CC(), par2))
 	   signQ = -1;
 	else {
 	  cerr << "Could not make sign for" << par1->id()<< " " << quarktopick->id()
 	       << " " << par2->id() << "\n";
 	  assert(false);
 	}
 
 	if (signQ  == -1)
 	  quarktopick = quarktopick->CC();
 	// construct the object with the info
 	Kupco a(quarktopick, H1->ptrData, H2->ptrData, weight);
 	hadrons.push_back(a);
 	wgtsum += weight;
       }
     }
   }
   if (hadrons.empty())
     return make_pair(tcPDPtr(),tcPDPtr());
   // select the hadron
   wgtsum *= UseRandom::rnd();
   unsigned int ix=0;
   do {
     wgtsum-= hadrons[ix].weight;
     ++ix;
   }
   while(wgtsum > ZERO && ix < hadrons.size());
   if(ix == hadrons.size() && wgtsum > ZERO)
       return make_pair(tcPDPtr(),tcPDPtr());
   --ix;
   assert(hadrons[ix].idQ);
   int signHad1 = signHadron(par1, hadrons[ix].idQ->CC(), hadrons[ix].hadron1);
   int signHad2 = signHadron(par2, hadrons[ix].idQ, hadrons[ix].hadron2);
   assert( signHad1 != 0 && signHad2 != 0 );
   return make_pair
     ( signHad1 > 0 ? hadrons[ix].hadron1 : tcPDPtr(hadrons[ix].hadron1->CC()),
       signHad2 > 0 ? hadrons[ix].hadron2 : tcPDPtr(hadrons[ix].hadron2->CC()));
 }
 
 std::tuple<bool,bool,bool> HadronSpectrum::selectBaryon(const Energy, tcPDPtr, tcPDPtr )  const {
   assert(false);
 }
 
 tcPDPair HadronSpectrum::lightestHadronPair(tcPDPtr ptr1, tcPDPtr ptr2) const {
   Energy currentSum = Constants::MaxEnergy;
   tcPDPair output;
   for(unsigned int ix=0; ix<partons().size(); ++ix) {
     HadronTable::const_iterator
       tit1=table().find(make_pair(abs(ptr1->id()),partons()[ix]->id())),
       tit2=table().find(make_pair(partons()[ix]->id(),abs(ptr2->id())));
     if( tit1==table().end() || tit2==table().end()) continue;
     if(tit1->second.empty()||tit2->second.empty()) continue;
     Energy s = tit1->second.begin()->mass + tit2->second.begin()->mass;
     if(currentSum > s) {
       currentSum = s;
       output.first  = tit1->second.begin()->ptrData;
       output.second = tit2->second.begin()->ptrData;
     }
   }
   return output;
 }
 
 tcPDPtr HadronSpectrum::lightestHadron(tcPDPtr ptr1, tcPDPtr ptr2) const {
   assert(ptr1 && ptr2);
   // find entry in the table
   pair<long,long> ids = make_pair(abs(ptr1->id()),abs(ptr2->id()));
   HadronTable::const_iterator tit=_table.find(ids);
   // throw exception if flavours wrong
   if (tit==_table.end()) 
     throw Exception() << "Could not find " 
 		      << ids.first << ' ' << ids.second 
 		      << " in _table. "
 		      << "In HadronSpectrum::lightestHadron()"
 		      << Exception::eventerror;
   if(tit->second.empty())
     throw Exception() << "HadronSpectrum::lightestHadron "
 		      << "could not find any hadrons containing " 
 		      << ptr1->id() << ' ' << ptr2->id() << '\n'
 		      << tit->first.first << ' ' 
 		      << tit->first.second << Exception::eventerror;
   // find the lightest hadron
   int sign = signHadron(ptr1,ptr2,tit->second.begin()->ptrData);
   tcPDPtr candidate = sign > 0 ? 
     tit->second.begin()->ptrData : tit->second.begin()->ptrData->CC();
   // \todo 20 GeV limit is temporary fudge to let SM particles go through.
   // \todo Use isExotic instead?
   if (candidate->mass() > 20*GeV 
       && candidate->mass() < ptr1->constituentMass() + ptr2->constituentMass()) {
     generator()->log() << "HadronSpectrum::lightestHadron: "
 		       << "chosen candidate " << candidate->PDGName() 
 		       << " is lighter than its constituents "
 		       << ptr1->PDGName() << ", " << ptr2->PDGName() << '\n'
 		       << candidate->mass()/GeV << " < " << ptr1->constituentMass()/GeV
 		       << " + " << ptr2->constituentMass()/GeV << '\n'
 		       << "Check your particle data tables.\n";
     assert(false);
   }
   return candidate;
 }
 
 vector<pair<tcPDPtr,double> > 
 HadronSpectrum::hadronsBelowThreshold(Energy threshold, tcPDPtr ptr1,
 				      tcPDPtr ptr2) const {
   assert(ptr1 && ptr2);
   // find entry in the table
   pair<long,long> ids = make_pair(abs(ptr1->id()),abs(ptr2->id()));
   HadronTable::const_iterator tit=_table.find(ids);
   // throw exception if flavours wrong
   if (tit==_table.end()) 
     throw Exception() << "Could not find " 
 		      << ids.first << ' ' << ids.second 
 		      << " in _table. "
 		      << "In HadronSpectrum::hadronsBelowThreshold()"
 		      << Exception::eventerror;
   if(tit->second.empty())
     throw Exception() << "HadronSpectrum::hadronsBelowThreshold() "
 		      << "could not find any hadrons containing " 
 		      << ptr1->id() << ' ' << ptr2->id() << '\n'
 		      << tit->first.first << ' ' 
 		      << tit->first.second << Exception::eventerror;
   vector<pair<tcPDPtr,double> > candidates;
   KupcoData::const_iterator hit = tit->second.begin();
   // find the hadrons
   while(hit!=tit->second.end()&&hit->mass<threshold) {
     // find the hadron
     int sign = signHadron(ptr1,ptr2,hit->ptrData);
     tcPDPtr candidate = sign > 0 ? hit->ptrData : hit->ptrData->CC();
     // \todo 20 GeV limit is temporary fudge to let SM particles go through.
     // \todo Use isExotic instead?
     if (candidate->mass() > 20*GeV 
 	&& candidate->mass() < ptr1->constituentMass() + ptr2->constituentMass()) {
       generator()->log() << "HadronSpectrum::hadronsBelowTheshold: "
 			 << "chosen candidate " << candidate->PDGName() 
 			 << " is lighter than its constituents "
 			 << ptr1->PDGName() << ", " << ptr2->PDGName() << '\n'
 			 << candidate->mass()/GeV << " < " << ptr1->constituentMass()/GeV
 			 << " + " << ptr2->constituentMass()/GeV << '\n'
 			 << "Check your particle data tables.\n";
       assert(false);
     } 
     candidates.push_back(make_pair(candidate,hit->overallWeight));
     ++hit;
   }
   return candidates;
 }
 
 Energy HadronSpectrum::massLightestBaryonPair(tcPDPtr ptr1, tcPDPtr ptr2) const {
   // Make sure that we don't have any diquarks as input, return arbitrarily
   // large value if we do
   Energy currentSum = Constants::MaxEnergy; 
   for(unsigned int ix=0; ix<_partons.size(); ++ix) {
     if(!DiquarkMatcher::Check(_partons[ix]->id())) continue;
     HadronTable::const_iterator 
       tit1=_table.find(make_pair(abs(ptr1->id()),_partons[ix]->id())),
       tit2=_table.find(make_pair(_partons[ix]->id(),abs(ptr2->id())));
     if( tit1==_table.end() || tit2==_table.end()) continue;
     if(tit1->second.empty()||tit2->second.empty()) continue;
     Energy s = tit1->second.begin()->mass + tit2->second.begin()->mass;
     if(currentSum > s) currentSum = s;
   }
   return currentSum;
 }
 
 double HadronSpectrum::mesonWeight(long id) const {
   // Total angular momentum
   int j  = ((id % 10) - 1) / 2;
   // related to Orbital angular momentum l
   int nl = (id/10000 )%10;
   int l  = -999;
   int n  = (id/100000)%10;  // Radial excitation
   if(j == 0) l = nl;
   else if(nl == 0) l = j - 1;
   else if(nl == 1  || nl == 2) l = j;
   else if(nl == 3) l = j + 1;
   // Angular or Radial excited meson
   if((l||j||n) && l>=0  &&  l<Lmax  &&  j<Jmax  &&  n<Nmax) {
     return sqr(_repwt[l][j][n]);
   }
   // rest is not excited or
   // has spin >= 5/2 (ispin >= 6), haven't got those
   else
     return 1.0;
 }
 
 int HadronSpectrum::signHadron(tcPDPtr idQ1, tcPDPtr idQ2, 
 			       tcPDPtr hadron) const {
   // This method receives in input three PDG ids, whose the
   // first two have proper signs (corresponding to particles, id > 0, 
   // or antiparticles, id < 0 ), whereas the third one must
   // be always positive (particle not antiparticle),
   // corresponding to:
   //  --- quark-antiquark, or antiquark-quark, or
   //      quark-diquark, or diquark-quark, or
   //      antiquark-antidiquark, or antidiquark-antiquark
   //      for the first two input (idQ1, idQ2);
   //  --- meson or baryon for the third input (idHad): 
   // The method returns:
   //  --- + 1  if the two partons (idQ1, idQ2) are exactly
   //           the constituents for the hadron idHad;
   //  --- - 1  if the two partons (idQ1, idQ2) are exactly
   //           the constituents for the anti-hadron -idHad;
   //  --- + 0  otherwise.
   // The method it is therefore useful to decide the
   // sign of the id of the produced hadron as appeared 
   // in the vector _vecHad (where only hadron idHad > 0 are present)  
   // given the two constituent partons.
   int sign = 0;
   long idHad = hadron->id();
   assert(idHad > 0);
   int chargeIn  = idQ1->iCharge() + idQ2->iCharge();
   int chargeOut = hadron->iCharge();
   // same charge
   if(     chargeIn ==  chargeOut && chargeIn  !=0 ) sign = +1;
   else if(chargeIn == -chargeOut && chargeIn  !=0 ) sign = -1;
   else if(chargeIn == 0          && chargeOut == 0 ) {  
     // In the case of same null charge, there are four cases:
     //  i) K0-like mesons, B0-like mesons, Bs-like mesons
     //     the PDG convention is to consider them "antiparticle" (idHad < 0) 
     //     if the "dominant" (heavier) flavour (respectively, s, b)
     //     is a quark (idQ > 0): for instance, B0s = (b, sbar) has id < 0
     //     Remember that there is an important exception for K0L (id=130) and
     //     K0S (id=310): they don't have antiparticles, therefore idHad > 0
     //     always. We use below the fact that K0L and K0S are the unique
     //     hadrons having 0 the first (less significant) digit of their id.
     //  2) D0-like mesons: the PDG convention is to consider them "particle"
     //     (idHad > 0) if the charm flavour is carried by a c: (c,ubar) has id>0
     //  3) the remaining mesons should not have antiparticle, therefore their
     //     sign is always positive.
     //  4) for baryons, that is when one of idQ1 and idQ2 is a (anti-) quark and 
     //     the other one is a (anti-) diquark the sign is negative when both
     //     constituents are "anti", that is both with id < 0; positive otherwise.
     // meson
     if(std::find(hadronizingQuarks().begin(), hadronizingQuarks().end(),
                  abs(idQ1->id())) != hadronizingQuarks().end() &&
        std::find(hadronizingQuarks().begin(), hadronizingQuarks().end(),
                  abs(idQ2->id())) != hadronizingQuarks().end())
     {
       int idQa = abs(idQ1->id());
       int idQb = abs(idQ2->id()); 
       int dominant = idQ2->id();
 
       if(idQa > idQb) {
 	swap(idQa,idQb);
 	dominant = idQ1->id();
       }
 
       if((idQa==ParticleID::d && idQb==ParticleID::s) ||
 	 (idQa==ParticleID::d && idQb==ParticleID::b) ||
 	 (idQa==ParticleID::s && idQb==ParticleID::b)) { 
 	// idHad%10 is zero for K0L,K0S
 	if (dominant < 0 || idHad%10 == 0) sign = +1;
 	else if(dominant > 0)              sign = -1;
       } 
       else if((idQa==ParticleID::u && idQb==ParticleID::c) ||
 	      (idQa==ParticleID::u && idQb==ParticleID::t) ||
 	      (idQa==ParticleID::c && idQb==ParticleID::t)) {
 	if     (dominant > 0) sign = +1;
 	else if(dominant < 0) sign = -1;
       } 
       else if(idQa==idQb) sign = +1;
       // sets sign for Susy particles
       else sign = (dominant > 0) ? +1 : -1;
     }
     // baryon
     else if(DiquarkMatcher::Check(idQ1->id()) || DiquarkMatcher::Check(idQ2->id())) {
       if     (idQ1->id() > 0 && idQ2->id() > 0) sign = +1;
       else if(idQ1->id() < 0 && idQ2->id() < 0) sign = -1;
     }
   }
   if (sign == 0) {
     cerr << "Could not work out sign for " 
 	 << idQ1->PDGName() << ' ' 
 	 << idQ2->PDGName() << " => " 
 	 << hadron->PDGName() << '\n';
     assert(false);
   }
   return sign;
 }
-/*
+
 PDPtr HadronSpectrum::makeDiquark(tcPDPtr par1, tcPDPtr par2) const {
     long id1 = par1->id();
     long id2 = par2->id();
     long pspin = id1==id2 ? 3 : 1;
     long idnew = makeDiquarkID(id1,id2, pspin);
-    return getParticleData(idnew);
+    assert(!CurrentGenerator::isVoid());
+    return CurrentGenerator::current().getParticleData(idnew);
 }
-*/
+
 bool HadronSpectrum::canBeMeson(tcPDPtr par1,tcPDPtr par2) const {
   assert(par1 && par2);
   long id1 = par1->id();
   long id2 = par2->id();
   // a Meson must not have any diquarks
   if(DiquarkMatcher::Check(id1) || DiquarkMatcher::Check(id2)) return false;
   return (std::find(hadronizingQuarks().begin(), hadronizingQuarks().end(),
                     abs(id1)) != hadronizingQuarks().end() &&
           std::find(hadronizingQuarks().begin(), hadronizingQuarks().end(),
                     abs(id2)) != hadronizingQuarks().end() &&
           id1*id2 < 0);
 }
   
diff --git a/Hadronization/HadronSpectrum.h b/Hadronization/HadronSpectrum.h
--- a/Hadronization/HadronSpectrum.h
+++ b/Hadronization/HadronSpectrum.h
@@ -1,649 +1,649 @@
 // -*- C++ -*-
 #ifndef Herwig_HadronSpectrum_H
 #define Herwig_HadronSpectrum_H
 //
 // This is the declaration of the HadronSpectrum class.
 //
 
 #include "ThePEG/Interface/Interfaced.h"
 #include "HadronSpectrum.fh"
 #include <ThePEG/Persistency/PersistentOStream.h>
 #include <ThePEG/Persistency/PersistentIStream.h>
 #include <ThePEG/PDT/ParticleData.h>
 #include "Kupco.h"
 /* These last two imports don't seem to be used here, but are needed for other
     classes which import this. Should tidy up at some point*/
 #include <ThePEG/PDT/StandardMatchers.h>
 #include <ThePEG/Repository/EventGenerator.h>
 
 namespace Herwig {
 
 using namespace ThePEG;
 
 /**
  * Here is the documentation of the HadronSpectrum class.
  *
  * @see \ref HadronSpectrumInterfaces "The interfaces"
  * defined for HadronSpectrum.
  */
 class HadronSpectrum: public Interfaced {
 
 public:
 
   /** \ingroup Hadronization
    *  \class HadronInfo 
    *  \brief Class used to store all the hadron information for easy access.
    *  \author Philip Stephens
    *  
    *  Note that:
    *  - the hadrons in _table can be filled in any ordered 
    *    w.r.t. the mass value, and flavours for different
    *    groups (for instance, (u,s) hadrons don't need to
    *    be placed after (d,s) or any other flavour), but 
    *    all hadrons with the same flavours must be consecutive
    *    ( for instance you cannot alternate hadrons of type
    *    (d,s) with those of flavour (u,s) ).
    *    Furthermore, it is assumed that particle and antiparticle
    *    have the same weights, and therefore only one of them
    *    must be entered in the table: we have chosen to refer
    *    to the particle, defined as PDG id > 0, although if
    *    an anti-particle is provided in input it is automatically
    *    transform to its particle, simply by taking the modulus
    *    of its id.
    */
   class HadronInfo {  
 
   public:
     
     /**
      *  Constructor
      * @param idin The PDG code of the hadron
      * @param datain The pointer to the ParticleData object
      * @param swtin  The singlet/decuplet/orbital factor
      * @param massin The mass of the hadron
      */
     HadronInfo(long idin=0, tPDPtr datain=tPDPtr(),
 	       double swtin=1., Energy massin=ZERO)
       : id(idin), ptrData(datain), swtef(swtin), wt(1.0), overallWeight(0.0),
 	mass(massin)
     {}
     
     /**
      *  Comparision operator on mass
      */
      bool operator<(const HadronInfo &x) const {
       if(mass!=x.mass) return mass < x.mass;
       else return id < x.id;
     }
     
     /**
      * The hadrons id.
      */
     long  id;
     
     /**
      * pointer to ParticleData, to get the spin, etc...
      */
     tPDPtr ptrData;
     
     /**
      * singlet/decuplet/orbital factor 
      */
     double swtef;
     
     /**
      * mixing factor
      */
     double wt;          
     
     /**
      * (2*J+1)*wt*swtef
      */
     double overallWeight;
     
     /**
      * The hadrons mass
      */
     Energy mass;
     
     /**
      *  Rescale the weight for a given hadron
      */
     void rescale(double x) const { 
       const_cast<HadronInfo*>(this)->overallWeight *= x; 
     }
     
     /**
      * Friend method used to print the value of a table element.
      */
     friend PersistentOStream & operator<< (PersistentOStream & os, 
 					   const HadronInfo & hi ) {
       os << hi.id << hi.ptrData << hi.swtef << hi.wt 
 	 << hi.overallWeight << ounit(hi.mass,GeV);
       return os;
     }
     
     /**
      * debug output
      */
     friend ostream & operator<< (ostream & os, const HadronInfo & hi ) {
       os << std::scientific << std::showpoint
 	 << std::setprecision(4)
 	 << setw(2)
 	 << hi.id << '\t'
 	 << hi.swtef << '\t'
 	 << hi.wt << '\t'
 	 << hi.overallWeight << '\t'
 	 << ounit(hi.mass,GeV);
       return os;
     }
     
     /**
      * Friend method used to read in the value of a table element.
      */
     friend PersistentIStream & operator>> (PersistentIStream & is, 
 					   HadronInfo & hi ) {
       is >> hi.id >> hi.ptrData >> hi.swtef >> hi.wt 
 	 >> hi.overallWeight >> iunit(hi.mass,GeV);
       return is;
     }
   };
   
 
 public:
 
   /**
    *  The helper classes
    */
   //@{
   /**
    * The type is used to contain all the hadrons info of a given flavour.
    */
   typedef set<HadronInfo> KupcoData;
   //@}
 
   /**
    * The hadron table type.
    */
   typedef map<pair<long,long>,KupcoData> HadronTable;
 
 public:
 
   /** @name Standard constructors and destructors. */
   //@{
   /**
    * The default constructor.
    */
   HadronSpectrum();
 
   /**
    * The destructor.
    */
   virtual ~HadronSpectrum();
   //@}
 
 public:
 
   /** @name Partonic content */
   //@{
 
   /**
    * Return the id of the gluon
    */
   virtual long gluonId() const = 0;
 
   /**
    * Return the ids of all hadronizing quarks
    */
   virtual const vector<long>& hadronizingQuarks() const = 0;
 
   /**
    * The light hadronizing quarks
    */
   virtual const vector<long>& lightHadronizingQuarks() const = 0;
 
   /**
    * The light hadronizing diquarks
    */
   virtual const vector<long>& lightHadronizingDiquarks() const = 0;
 
   /**
    * The heavy hadronizing quarks
    */
   virtual const vector<long>& heavyHadronizingQuarks() const = 0;
 
   /**
    * Return true if any of the possible three input particles contains
    * the indicated heavy quark.  false otherwise. In the case that
    * only the first particle is specified, it can be: an (anti-)quark,
    * an (anti-)diquark an (anti-)meson, an (anti-)baryon; in the other
    * cases, each pointer is assumed to be either (anti-)quark or
    * (anti-)diquark.
    */
   virtual bool hasHeavy(long id, tcPDPtr par1, tcPDPtr par2 = PDPtr(), tcPDPtr par3 = PDPtr()) const = 0;
 
   /**
    * Return true, if any of the possible input particle pointer is an
    * exotic quark, e.g. Susy quark; false otherwise.
    */
   virtual bool isExotic(tcPDPtr par1, tcPDPtr par2 = PDPtr(), tcPDPtr par3 = PDPtr()) const = 0;
 
   //@}
 
   
   /**
    *  Access the parton weights
    */
    double pwt(long pid) const {
     map<long,double>::const_iterator it = _pwt.find(abs(pid));
     assert( it != _pwt.end() );
     return it->second;
   }
 
    /**
    * Return true if the two or three particles in input can be the components 
    * of a hadron; false otherwise.
    */
   inline bool canBeHadron(tcPDPtr par1, tcPDPtr par2 , tcPDPtr par3 = PDPtr()) const {
     return (!par3 && canBeMeson(par1,par2)) || canBeBaryon(par1,par2,par3);
   }
 
   /**
    * Check if can't make a diquark from the partons
    */
   bool canMakeDiQuark(tcPPtr p1, tcPPtr p2) const {
     long id1 = p1->id(), id2 = p2->id();
     return QuarkMatcher::Check(id1) && QuarkMatcher::Check(id2) && id1*id2>0;
   }
 
   /**
    * Return the particle data of the diquark (anti-diquark) made by the two 
    * quarks (antiquarks) par1, par2.
    * @param par1 (anti-)quark data pointer
    * @param par2 (anti-)quark data pointer
    */
-  virtual PDPtr makeDiquark(tcPDPtr par1, tcPDPtr par2) const = 0;
+  PDPtr makeDiquark(tcPDPtr par1, tcPDPtr par2) const;
 
   /**
    * Method to return a pair of hadrons given the PDG codes of
    * two or three constituents
    * @param cluMass The mass of the cluster
    * @param par1 The first constituent
    * @param par2 The second constituent
    * @param par3 The third constituent
    */
   virtual pair<tcPDPtr,tcPDPtr> chooseHadronPair(const Energy cluMass, tcPDPtr par1, 
 						 tcPDPtr par2) const;
 
   /**
    * Select the single hadron for a cluster decay
    * return null pointer if not a single hadron decay
    * @param par1 1st constituent
    * @param par2 2nd constituent
    * @param mass Mass of the cluster
    */
   virtual tcPDPtr chooseSingleHadron(tcPDPtr par1, tcPDPtr par2, Energy mass) const;
 
   /**
    * This returns the lightest pair of hadrons given by the flavours.
    *
    * Given the two (or three) constituents of a cluster, it returns
    * the two lightest hadrons with proper flavour numbers.
    * Furthermore, the first of the two hadrons must have the constituent with
    * par1, and the second must have the constituent with par2. 
    * \todo At the moment it does *nothing* in the case that also par3 is present.
    *
    * The method is implemented by calling twice lightestHadron, 
    * once with (par1,quarktopick->CC()) ,and once with (par2,quarktopick)
    * where quarktopick is either the pointer to
    * d or u quarks . In fact, the idea is that whatever the flavour of par1 
    * and par2, no matter if (anti-)quark or (anti-)diquark, the lightest
    * pair of hadrons containing flavour par1 and par2 will have either 
    * flavour d or u, being the lightest quarks.
    * The method returns the pair (PDPtr(),PDPtr()) if anything goes wrong. 
    *
    * \todo The method assumes par3 == PDPtr() (otherwise we don't know how to proceed: a 
    * possible, trivial way would be to randomly select two of the three 
    * (anti-)quarks and treat them as a (anti-)diquark, reducing the problem
    * to two components as treated below.
    * In the normal (two components) situation, the strategy is the following:
    * treat in the same way the two possibilities:  (d dbar)  (i=0) and  
    * (u ubar)  (i=1)  as the pair quark-antiquark necessary to form a
    * pair of hadrons containing the input flavour  par1  and  par2; finally,
    * select the one that produces the lightest pair of hadrons, compatible
    * with the charge conservation constraint.
    */
   tcPDPair lightestHadronPair(tcPDPtr ptr1, tcPDPtr ptr2) const;
 
   /**
    *  Returns the mass of the lightest pair of hadrons with the given particles
    * @param ptr1 is the first  constituent
    * @param ptr2 is the second constituent
    */
   Energy massLightestHadronPair(tcPDPtr ptr1, tcPDPtr ptr2) const  { 
     map<pair<long,long>,tcPDPair>::const_iterator lightest =
       lightestHadrons_.find(make_pair(abs(ptr1->id()),abs(ptr2->id())));
     if(lightest!=lightestHadrons_.end())
       return lightest->second.first->mass()+lightest->second.second->mass();
     else
       return ZERO;
   }
 
   /**
    * Returns the lightest hadron formed by the given particles.
    *
    * Given the id of two (or three) constituents of a cluster, it returns
    * the  lightest hadron with proper flavour numbers.
    * @param ptr1 is the first  constituent
    * @param ptr2 is the second constituent
    */
    tcPDPtr lightestHadron(tcPDPtr ptr1, tcPDPtr ptr2) const;
   
   /**
    * Return the threshold for a cluster to split into a pair of hadrons.
    * This is normally the mass of the lightest hadron Pair, but can be
    * higher for heavy and exotic clusters
    */
   virtual Energy hadronPairThreshold(tcPDPtr par1, tcPDPtr par2) const=0;
 
   /**
    * Returns the hadrons below the constituent mass threshold formed by the given particles,
    * together with their total weight
    *
    * Given the id of two (or three) constituents of a cluster, it returns
    * the  lightest hadron with proper flavour numbers.
    * At the moment it does *nothing* in the case that also 'ptr3' present.
    * @param threshold The theshold
    * @param ptr1 is the first  constituent
    * @param ptr2 is the second constituent 
    * @param ptr3 is the third  constituent
    */
   vector<pair<tcPDPtr,double> > hadronsBelowThreshold(Energy threshold,
 							      tcPDPtr ptr1, tcPDPtr ptr2) const;
 
   /**
    * Return the nominal mass of the hadron returned by lightestHadron()
    * @param ptr1 is the first  constituent
    * @param ptr2 is the second constituent 
    * @param ptr3 is the third  constituent 
    */
    Energy massLightestHadron(tcPDPtr ptr1, tcPDPtr ptr2) const {
     // find entry in the table
     pair<long,long> ids(abs(ptr1->id()),abs(ptr2->id()));
     HadronTable::const_iterator tit=_table.find(ids);
     // throw exception if flavours wrong
     if(tit==_table.end()||tit->second.empty())
       throw Exception() <<  "HadronSpectrum::massLightestHadron "
 			<< "failed for particle" << ptr1->id()  << " " 
 			<< ptr2->id() 
 			<< Exception::eventerror;
     // return the mass
     return tit->second.begin()->mass;
   }
 
   /**
    *  Force baryon/meson selection
    */
   virtual std::tuple<bool,bool,bool> selectBaryon(const Energy cluMass, tcPDPtr par1, tcPDPtr par2) const;
 
   /**
    *  Returns the mass of the lightest pair of baryons.
    * @param ptr1 is the first  constituent
    * @param ptr2 is the second constituent 
    */
   Energy massLightestBaryonPair(tcPDPtr ptr1, tcPDPtr ptr2) const;
   
   /**
    * Return the weight for the given flavour
    */
    virtual double pwtQuark(const long& id) const = 0;
 
   virtual double specialQuarkWeight(double quarkWeight, long,
 				    const Energy, tcPDPtr, tcPDPtr) const {
     return quarkWeight;
   }
 
 public:
 
   /** @name Functions used by the persistent I/O system. */
   //@{
   /**
    * Function used to write out object persistently.
    * @param os the persistent output stream written to.
    */
   void persistentOutput(PersistentOStream & os) const;
 
   /**
    * Function used to read in object persistently.
    * @param is the persistent input stream read from.
    * @param version the version number of the object when written.
    */
   void persistentInput(PersistentIStream & is, int version);
   //@}
 
   /**
    * The standard Init function used to initialize the interfaces.
    * Called exactly once for each class by the class description system
    * before the main function starts or
    * when this class is dynamically loaded.
    */
   static void Init();
 
   void setGenerator(tEGPtr generator) {
     Interfaced::setGenerator(generator);
   }
 
 protected:
 
   /** @name Standard Interfaced functions. */
   //@{
   /**
    * Initialize this object after the setup phase before saving an
    * EventGenerator to disk.
    *
    *  The array _repwt is initialized using the interfaces to set different
    *  weights for different meson multiplets and the constructHadronTable()
    *  method called to complete the construction of the hadron tables.
    *
    * @throws InitException if object could not be initialized properly.
    */
   virtual void doinit();
   //@}
 
   /**
    * Return the id of the diquark (anti-diquark) made by the two 
    * quarks (antiquarks) of id specified in input (id1, id2).
    * Caller must ensure that id1 and id2 are quarks.
    */
   virtual long makeDiquarkID(long id1, long id2, long pspin)  const = 0;
 
 protected:
   /**
    * Return true if the two particles in input can be the components of a meson;
    *false otherwise.
    */
   bool canBeMeson(tcPDPtr par1,tcPDPtr par2)  const;
 
   /**
    * Return true if the two or three particles in input can be the components 
    * of a baryon; false otherwise.
    */
   virtual bool canBeBaryon(tcPDPtr par1, tcPDPtr par2 , tcPDPtr par3 = PDPtr())  const = 0;
 
 
   /**
    *  A sub-function of HadronSpectrum::constructHadronTable().
    *  It receives the information of a prospective Hadron and inserts it
    *  into the hadron table construct.
    *  @param particle is a particle data pointer to the hadron
    *  @param flav1 is the first  constituent of the hadron
    *  @param flav2 is the second constituent of the hadron
    */
   void insertToHadronTable(tPDPtr &particle, int flav1, int flav2);
 
   /**
    *  Construct the table of hadron data
    *  This is the main method to initialize the hadron data (mainly the
    *  weights associated to each hadron, taking into account its spin, 
    *  eventual isoscalar-octect mixing, singlet-decuplet factor). This is
    *  the method that one should update when new or updated hadron data is
    *  available. 
    *
    *  This class implements the construction of the basic table but can be 
    *  overridden if needed in inheriting classes.
    *
    *  The rationale for factors used for diquarks involving different quarks can 
    *  be can be explained by taking a prototype example that in the  exact SU(2) limit,
    *  in which:
    *  \f[m_u=m_d\f] 
    *  \f[M_p=M_n=M_\Delta\f]
    *      and we will have equal numbers of u and d quarks produced.
    *      Suppose that we weight 1 the diquarks made of the same 
    *      quark and 1/2 those made of different quarks, the fractions
    *      of u and d baryons (p, n, Delta) we get are the following:
    *        - \f$\Delta^{++}\f$: 1 possibility only  u uu  with weight 1
    *        - \f$\Delta^-   \f$: 1 possibility only  d dd  with weight 1
    *        - \f$p,\Delta^+ \f$: 2 possibilities     u ud  with weight 1/2
    *                                                 d uu  with weight 1
    *        - \f$n,\Delta^0 \f$: 2 possibilities     d ud  with weight 1/2
    *                                                 u dd  with weight 1
    *      In the latter two cases, we have to take into account the 
    *      fact that  p  and  n  have spin 1/2 whereas  Delta+  and  Delta0
    *      have spin 3/2 therefore from phase space we get a double weight 
    *      for  Delta+  and  Delta0  relative to  p  and  n  respectively.
    *      Therefore the relative amount of these baryons that is
    *      produced is the following:
    *       # p = # n = ( 1/2 + 1 ) * 1/3 = 1/2
    *       # Delta++ = # Delta- = 1 = ( 1/2 + 1) * 2/3 # Delta+ = # Delta0
    *      which is correct, and therefore the weight 1/2 for the
    *      diquarks of different types of quarks is justified (at least
    *      in this limit of exact SU(2) ).
    */
   virtual void constructHadronTable() = 0;
 
   /**
    * The table of hadron data
    */
   HadronTable _table;
 
   /**
    *  The PDG codes of the constituent particles allowed
    */
   vector<PDPtr> _partons;
 
   /**
    *  The PDG codes of the hadrons which cannot be produced in the hadronization
    */
   vector<PDPtr> _forbidden;
 
   /**
    *  Access to the table of hadrons
    */
    const HadronTable & table() const {
     return _table;
   }
   
   /**
    *  Access to the list of partons
    */
    const vector<PDPtr> & partons() const {
     return _partons;
   }
 
   /**
    * Calculates a special weight specific to  a given hadron.
    * @param id The PDG code of the hadron
    */
   double specialWeight(long id) const {
     const int pspin = id % 10;
     // Only K0L and K0S have pspin == 0, should
     // not get them until Decay step
     assert( pspin != 0 );
     // Baryon : J = 1/2 or 3/2
     if(pspin%2==0)
       return baryonWeight(id);
     // Meson
     else 
       return mesonWeight(id); 
   }
   
   /**
    *  Weights for mesons
    */
   virtual double mesonWeight(long id) const;
 
   /**
    *  Weights for baryons
    */
   virtual double baryonWeight(long id) const = 0;
 
   /**
    * This method returns the proper sign ( > 0 hadron; < 0 anti-hadron )
    * for the input PDG id  idHad > 0, suppose to be made by the
    * two constituent particle pointers: par1 and par2 (both with proper sign).
    */
   int signHadron(tcPDPtr ptr1, tcPDPtr ptr2, tcPDPtr hadron) const;
 
   /**
    *   Insert a meson in the table
    */
   virtual void insertMeson(HadronInfo a, int flav1, int flav2) = 0;
 
   /**
    *   Insert a spin\f$\frac12\f$ baryon in the table
    */
   virtual void insertOneHalf(HadronInfo a, int flav1, int flav2);
 
   /**
    *   Insert a spin\f$\frac32\f$ baryon in the table
    */
   virtual void insertThreeHalf(HadronInfo a, int flav1, int flav2);
 
   /**
    *  Option for the selection of hadrons below the pair threshold
    */
   unsigned int belowThreshold_;
 
   /**
    *  The weights for the excited meson multiplets
    */
   vector<vector<vector<double> > > _repwt;
 
   /**
    * Weights for quarks and diquarks.
    */
   map<long,double> _pwt;
 
   /**
    * Enums so arrays can be statically allocated
    */
   //@{
   /**
    * Defines values for array sizes. L,J,N max values for excited mesons.
    */
   enum MesonMultiplets { Lmax = 3, Jmax = 4, Nmax = 4}; 
   //@}
   
   /**
    *  Caches of lightest pairs for speed
    */
   //@{
   /**
    * Masses of lightest hadron pair
    */
   map<pair<long,long>,tcPDPair> lightestHadrons_;
   //@}
 
 private:
 
   /**
    * The assignment operator is private and must never be called.
    * In fact, it should not even be implemented.
    */
   HadronSpectrum & operator=(const HadronSpectrum &) = delete;
 
 };
 
 }
 
 #endif /* Herwig_HadronSpectrum_H */
diff --git a/Hadronization/StandardModelHadronSpectrum.cc b/Hadronization/StandardModelHadronSpectrum.cc
--- a/Hadronization/StandardModelHadronSpectrum.cc
+++ b/Hadronization/StandardModelHadronSpectrum.cc
@@ -1,718 +1,709 @@
 // -*- C++ -*-
 //
 // This is the implementation of the non-inlined, non-templated member
 // functions of the StandardModelHadronSpectrum class.
 //
 
 #include "StandardModelHadronSpectrum.h"
 #include "ThePEG/Interface/ClassDocumentation.h"
 #include "ThePEG/Interface/Parameter.h"
 #include "ThePEG/Interface/Switch.h"
 #include "ThePEG/Interface/ParVector.h"
 #include "ThePEG/Interface/RefVector.h"
 #include "ThePEG/EventRecord/Particle.h"
 #include "ThePEG/Repository/UseRandom.h"
 #include "ThePEG/Repository/EventGenerator.h"
 #include "ThePEG/Utilities/DescribeClass.h"
 
 #include <ThePEG/PDT/EnumParticles.h>
 #include <ThePEG/Repository/EventGenerator.h>
 #include <ThePEG/Repository/Repository.h>
 
 
 #include "ThePEG/Persistency/PersistentOStream.h"
 #include "ThePEG/Persistency/PersistentIStream.h"
 
 using namespace Herwig;
 
 namespace {
   bool weightIsLess (pair<long,double> a, pair<long,double> b) {
     return a.second < b.second;
   }
 
   /**
    * Return true if the particle pointer corresponds to a diquark 
    * or anti-diquark carrying b flavour; false otherwise.
    */
   inline bool isDiquarkWithB(tcPDPtr par1) {
     if (!par1) return false;
     long id1 = par1->id();
     return DiquarkMatcher::Check(id1)  &&  (abs(id1)/1000)%10 == ParticleID::b;
   }
   
   /**
    * Return true if the particle pointer corresponds to a diquark
    *  or anti-diquark carrying c flavour; false otherwise.
    */
   inline bool isDiquarkWithC(tcPDPtr par1) {
     if (!par1) return false;
     long id1 = par1->id();
     return ( DiquarkMatcher::Check(id1)  &&  
        ( (abs(id1)/1000)%10 == ParticleID::c  
          || (abs(id1)/100)%10 == ParticleID::c ) );
   }
 
 }
 
 
 StandardModelHadronSpectrum::StandardModelHadronSpectrum(unsigned int opt) 
   : HadronSpectrum(),
 	_hadronizingStrangeDiquarks(1),
     _pwtDquark( 1.0 ),_pwtUquark( 1.0 ),_pwtSquark( 1.0 ),_pwtCquark( 0.0 ),
     _pwtBquark( 0.0 ),
     _sngWt( 1.0 ),_decWt( 1.0 ), 
     _weight1S0(Nmax,1.),_weight3S1(Nmax,1.),_weight1P1(Nmax,1.),_weight3P0(Nmax,1.),
     _weight3P1(Nmax,1.),_weight3P2(Nmax,1.),_weight1D2(Nmax,1.),_weight3D1(Nmax,1.),
     _weight3D2(Nmax,1.),_weight3D3(Nmax,1.),
     _topt(opt),_trial(0), 
     _limBottom(0.0), _limCharm(0.0), _limExotic(0.0) 
 {
   // The mixing angles
   // the ideal mixing angle
   const double idealAngleMix = atan( sqrt(0.5) ) * 180.0 / Constants::pi;
   // \eta-\eta' mixing angle
   _etamix   = -23.0;
   // phi-omega mixing angle
   _phimix   = +36.0;
   // h_1'-h_1 mixing angle
   _h1mix    = idealAngleMix;
   // f_0(1710)-f_0(1370) mixing angle
   _f0mix    = idealAngleMix;
   // f_1(1420)-f_1(1285)\f$ mixing angle
   _f1mix    = idealAngleMix;
   // f'_2-f_2\f$ mixing angle
   _f2mix    = +26.0;
   // eta_2(1870)-eta_2(1645) mixing angle
   _eta2mix  = idealAngleMix;
   // phi(???)-omega(1650) mixing angle
   _omhmix   = idealAngleMix;
   // phi_3-omega_3 mixing angle
   _ph3mix   = +28.0;
   // eta(1475)-eta(1295) mixing angle
   _eta2Smix = idealAngleMix;
   // phi(1680)-omega(1420) mixing angle
   _phi2Smix = idealAngleMix;
 }
 
 
 StandardModelHadronSpectrum::~StandardModelHadronSpectrum() {}
 
 
 void StandardModelHadronSpectrum::persistentOutput(PersistentOStream & os) const {
   os << _hadronizingStrangeDiquarks
      << _pwtDquark  << _pwtUquark << _pwtSquark 
      << _pwtCquark << _pwtBquark
      << _etamix << _phimix << _h1mix << _f0mix << _f1mix << _f2mix 
      << _eta2mix << _omhmix << _ph3mix << _eta2Smix << _phi2Smix 
      << _weight1S0 << _weight3S1 << _weight1P1 << _weight3P0 << _weight3P1 
      << _weight3P2 << _weight1D2 << _weight3D1 << _weight3D2 << _weight3D3
      << _sngWt << _decWt << _repwt
      << _limBottom << _limCharm << _limExotic;
 }
 
 void StandardModelHadronSpectrum::persistentInput(PersistentIStream & is, int) {
   is >> _hadronizingStrangeDiquarks
      >> _pwtDquark  >> _pwtUquark >> _pwtSquark 
      >> _pwtCquark >> _pwtBquark 
      >> _etamix >> _phimix >> _h1mix >> _f0mix >> _f1mix >> _f2mix 
      >> _eta2mix >> _omhmix >> _ph3mix >> _eta2Smix >> _phi2Smix 
      >> _weight1S0 >> _weight3S1 >> _weight1P1 >> _weight3P0 >> _weight3P1 
      >> _weight3P2 >> _weight1D2 >> _weight3D1 >> _weight3D2 >> _weight3D3
      >> _sngWt >> _decWt >> _repwt
      >> _limBottom >> _limCharm >> _limExotic;
 }
 
 
 // *** Attention *** The following static variable is needed for the type
 // description system in ThePEG. Please check that the template arguments
 // are correct (the class and its base class), and that the constructor
 // arguments are correct (the class name and the name of the dynamically
 // loadable library where the class implementation can be found).
 DescribeAbstractClass<StandardModelHadronSpectrum,HadronSpectrum>
 describeHerwigStandardModelHadronSpectrum("Herwig::StandardModelHadronSpectrum", "Herwig.so");
 
 void StandardModelHadronSpectrum::Init() {
 
   static ClassDocumentation<StandardModelHadronSpectrum> documentation
     ("There is no documentation for the StandardModelHadronSpectrum class");
 
   static Parameter<StandardModelHadronSpectrum,double>
     interfacePwtDquark("PwtDquark","Weight for choosing a quark D",
 		       &StandardModelHadronSpectrum::_pwtDquark, 0, 1.0, 0.0, 10.0,
 		       false,false,false);
 
   static Parameter<StandardModelHadronSpectrum,double>
     interfacePwtUquark("PwtUquark","Weight for choosing a quark U",
 		       &StandardModelHadronSpectrum::_pwtUquark, 0, 1.0, 0.0, 10.0,
 		       false,false,false);
 
   static Parameter<StandardModelHadronSpectrum,double>
     interfacePwtSquark("PwtSquark","Weight for choosing a quark S",
 		       &StandardModelHadronSpectrum::_pwtSquark, 0, 1.0, 0.0, 10.0,
 		       false,false,false);
 
   static Parameter<StandardModelHadronSpectrum,double>
     interfacePwtCquark("PwtCquark","Weight for choosing a quark C",
 		       &StandardModelHadronSpectrum::_pwtCquark, 0, 0.0, 0.0, 10.0,
 		       false,false,false);
 
   static Parameter<StandardModelHadronSpectrum,double>
     interfacePwtBquark("PwtBquark","Weight for choosing a quark B",
 		       &StandardModelHadronSpectrum::_pwtBquark, 0, 0.0, 0.0, 10.0,
 		       false,false,false);
 
   static Parameter<StandardModelHadronSpectrum,double>
     interfaceSngWt("SngWt","Weight for singlet baryons",
                   &StandardModelHadronSpectrum::_sngWt, 0, 1.0, 0.0, 10.0,
 		   false,false,false);
 
   static Parameter<StandardModelHadronSpectrum,double>
     interfaceDecWt("DecWt","Weight for decuplet baryons",
                   &StandardModelHadronSpectrum::_decWt, 0, 1.0, 0.0, 10.0,
 		   false,false,false);
 
   //
   // mixing angles
   //
   // the ideal mixing angle
   const double idealAngleMix = atan( sqrt(0.5) ) * 180.0 / Constants::pi;
 
   static Parameter<StandardModelHadronSpectrum,double> interface11S0Mixing
     ("11S0Mixing",
      "The mixing angle for the I=0 mesons from the 1 1S0 multiplet,"
      " i.e. eta and etaprime.",
      &StandardModelHadronSpectrum::_etamix, -23., -180., 180.,
      false, false, Interface::limited);
 
   static Parameter<StandardModelHadronSpectrum,double> interface13S1Mixing
     ("13S1Mixing",
      "The mixing angle for the I=0 mesons from the 1 3S1 multiplet,"
      " i.e. phi and omega.",
      &StandardModelHadronSpectrum::_phimix, +36., -180., 180.,
      false, false, Interface::limited);
 
   static Parameter<StandardModelHadronSpectrum,double> interface11P1Mixing
     ("11P1Mixing",
      "The mixing angle for the I=0 mesons from the 1 1P1 multiplet,"
      " i.e. h_1' and h_1.",
      &StandardModelHadronSpectrum::_h1mix, idealAngleMix, -180., 180.,
      false, false, Interface::limited);
 
   static Parameter<StandardModelHadronSpectrum,double> interface13P0Mixing
     ("13P0Mixing",
      "The mixing angle for the I=0 mesons from the 1 3P0 multiplet,"
      " i.e. f_0(1710) and f_0(1370).",
      &StandardModelHadronSpectrum::_f0mix, idealAngleMix, -180., 180.,
      false, false, Interface::limited);
 
   static Parameter<StandardModelHadronSpectrum,double> interface13P1Mixing
     ("13P1Mixing",
      "The mixing angle for the I=0 mesons from the 1 3P1 multiplet,"
      " i.e. f_1(1420) and f_1(1285).",
      &StandardModelHadronSpectrum::_f1mix, idealAngleMix, -180., 180.,
      false, false, Interface::limited);
 
   static Parameter<StandardModelHadronSpectrum,double> interface13P2Mixing
     ("13P2Mixing",
      "The mixing angle for the I=0 mesons from the 1 3P2 multiplet,"
      " i.e. f'_2 and f_2.",
      &StandardModelHadronSpectrum::_f2mix, 26.0, -180., 180.,
      false, false, Interface::limited);
 
   static Parameter<StandardModelHadronSpectrum,double> interface11D2Mixing
     ("11D2Mixing",
      "The mixing angle for the I=0 mesons from the 1 1D2 multiplet,"
      " i.e. eta_2(1870) and eta_2(1645).",
      &StandardModelHadronSpectrum::_eta2mix, idealAngleMix, -180., 180.,
      false, false, Interface::limited);
 
   static Parameter<StandardModelHadronSpectrum,double> interface13D0Mixing
     ("13D0Mixing",
      "The mixing angle for the I=0 mesons from the 1 3D0 multiplet,"
      " i.e. eta_2(1870) phi(?) and omega(1650).",
      &StandardModelHadronSpectrum::_omhmix, idealAngleMix, -180., 180.,
      false, false, Interface::limited);
 
   static Parameter<StandardModelHadronSpectrum,double> interface13D1Mixing
     ("13D1Mixing",
      "The mixing angle for the I=0 mesons from the 1 3D1 multiplet,"
      " i.e. phi_3 and omega_3.",
      &StandardModelHadronSpectrum::_ph3mix, 28.0, -180., 180.,
      false, false, Interface::limited);
 
   static Parameter<StandardModelHadronSpectrum,double> interface21S0Mixing
     ("21S0Mixing",
      "The mixing angle for the I=0 mesons from the 2 1S0 multiplet,"
      " i.e. eta(1475) and eta(1295).",
      &StandardModelHadronSpectrum::_eta2Smix, idealAngleMix, -180., 180.,
      false, false, Interface::limited);
 
   static Parameter<StandardModelHadronSpectrum,double> interface23S1Mixing
     ("23S1Mixing",
      "The mixing angle for the I=0 mesons from the 1 3S1 multiplet,"
      " i.e. phi(1680) and omega(1420).",
      &StandardModelHadronSpectrum::_phi2Smix, idealAngleMix, -180., 180.,
      false, false, Interface::limited);
   //
   //  the meson weights
   //
   static ParVector<StandardModelHadronSpectrum,double> interface1S0Weights
     ("1S0Weights",
      "The weights for the 1S0 multiplets start with n=1.",
      &StandardModelHadronSpectrum::_weight1S0, Nmax, 1.0, 0.0, 100.0,
      false, false, Interface::limited);
 
   static ParVector<StandardModelHadronSpectrum,double> interface3S1Weights
     ("3S1Weights",
      "The weights for the 3S1 multiplets start with n=1.",
      &StandardModelHadronSpectrum::_weight3S1, Nmax, 1.0, 0.0, 100.0,
      false, false, Interface::limited);
 
   static ParVector<StandardModelHadronSpectrum,double> interface1P1Weights
     ("1P1Weights",
      "The weights for the 1P1 multiplets start with n=1.",
      &StandardModelHadronSpectrum::_weight1P1, Nmax, 1.0, 0.0, 100.0,
      false, false, Interface::limited);
 
   static ParVector<StandardModelHadronSpectrum,double> interface3P0Weights
     ("3P0Weights",
      "The weights for the 3P0 multiplets start with n=1.",
      &StandardModelHadronSpectrum::_weight3P0, Nmax, 1.0, 0.0, 100.0,
      false, false, Interface::limited);
 
   static ParVector<StandardModelHadronSpectrum,double> interface3P1Weights
     ("3P1Weights",
      "The weights for the 3P1 multiplets start with n=1.",
      &StandardModelHadronSpectrum::_weight3P1, Nmax, 1.0, 0.0, 100.0,
      false, false, Interface::limited);
 
   static ParVector<StandardModelHadronSpectrum,double> interface3P2Weights
     ("3P2Weights",
      "The weights for the 3P2 multiplets start with n=1.",
      &StandardModelHadronSpectrum::_weight3P2, Nmax, 1.0, 0.0, 100.0,
      false, false, Interface::limited);
 
   static ParVector<StandardModelHadronSpectrum,double> interface1D2Weights
     ("1D2Weights",
      "The weights for the 1D2 multiplets start with n=1.",
      &StandardModelHadronSpectrum::_weight1D2, Nmax, 1.0, 0.0, 100.0,
      false, false, Interface::limited);
 
   static ParVector<StandardModelHadronSpectrum,double> interface3D1Weights
     ("3D1Weights",
      "The weights for the 3D1 multiplets start with n=1.",
      &StandardModelHadronSpectrum::_weight3D1, Nmax, 1.0, 0.0, 100.0,
      false, false, Interface::limited);
 
   static ParVector<StandardModelHadronSpectrum,double> interface3D2Weights
     ("3D2Weights",
      "The weights for the 3D2 multiplets start with n=1.",
      &StandardModelHadronSpectrum::_weight3D2, Nmax, 1.0, 0.0, 100.0,
      false, false, Interface::limited);
 
   static ParVector<StandardModelHadronSpectrum,double> interface3D3Weights
     ("3D3Weights",
      "The weights for the 3D3 multiplets start with n=1.",
      &StandardModelHadronSpectrum::_weight3D3, Nmax, 1.0, 0.0, 100.0,
      false, false, Interface::limited);
 
   static Switch<StandardModelHadronSpectrum,unsigned int> interfaceTrial
     ("Trial",
      "A Debugging option to only produce certain types of hadrons",
      &StandardModelHadronSpectrum::_trial, 0, false, false);
   static SwitchOption interfaceTrialAll
     (interfaceTrial,
      "All",
      "Produce all the hadrons",
      0);
   static SwitchOption interfaceTrialPions
     (interfaceTrial,
      "Pions",
      "Only produce pions",
      1);
   static SwitchOption interfaceTrialSpin2
     (interfaceTrial,
      "Spin2",
      "Only mesons with spin less than or equal to two are produced",
      2);
   static SwitchOption interfaceTrialSpin3
     (interfaceTrial,
      "Spin3",
      "Only hadrons with spin less than or equal to three are produced",
      3);
 
   static Parameter<StandardModelHadronSpectrum,double>
     interfaceSingleHadronLimitBottom ("SingleHadronLimitBottom",
 				      "Threshold for one-hadron decay of b-cluster",
 				      &StandardModelHadronSpectrum::_limBottom,
 				      0, 0.0, 0.0, 100.0,false,false,false);
 
   static Parameter<StandardModelHadronSpectrum,double>
     interfaceSingleHadronLimitCharm ("SingleHadronLimitCharm",
 				     "threshold for one-hadron decay of c-cluster",
 				     &StandardModelHadronSpectrum::_limCharm,
 				     0, 0.0, 0.0, 100.0,false,false,false);
 
   static Parameter<StandardModelHadronSpectrum,double>
     interfaceSingleHadronLimitExotic ("SingleHadronLimitExotic",
 				      "threshold for one-hadron decay of exotic cluster",
 				      &StandardModelHadronSpectrum::_limExotic,
 				      0, 0.0, 0.0, 100.0,false,false,false);
 
   static Switch<StandardModelHadronSpectrum,unsigned int> interfaceBelowThreshold
     ("BelowThreshold",
      "Option fo the selection of the hadrons if the cluster is below the pair threshold",
      &StandardModelHadronSpectrum::belowThreshold_, 0, false, false);
   static SwitchOption interfaceBelowThresholdLightest
     (interfaceBelowThreshold,
      "Lightest",
      "Force cluster to decay to the lightest hadron with the appropriate flavours",
      0);
   static SwitchOption interfaceBelowThresholdAll
     (interfaceBelowThreshold,
      "All",
      "Select from all the hadrons below the two hadron threshold according to their spin weights",
      1);
 
   static Switch<StandardModelHadronSpectrum,unsigned int> interfaceHadronizingStrangeDiquarks
     ("HadronizingStrangeDiquarks",
      "Option for adding strange diquarks to Hadronization",
      &StandardModelHadronSpectrum::_hadronizingStrangeDiquarks, 0, false, false);
   static SwitchOption interfaceHadronizingStrangeDiquarksNo
     (interfaceHadronizingStrangeDiquarks,
      "No",
      "No strangeness containing diquarks in Hadronization",
      0);
   static SwitchOption interfaceHadronizingStrangeDiquarksOnlySingleStrange
     (interfaceHadronizingStrangeDiquarks,
      "OnlySingleStrange",
      "Only one strangeness containing diquarks in Hadronization i.e. su,sd",
      1);
   static SwitchOption interfaceHadronizingStrangeDiquarksAll
     (interfaceHadronizingStrangeDiquarks,
      "All",
      "All strangeness containing diquarks in Hadronization i.e. su,sd,ss",
      2);
 
 }
 
-
-PDPtr StandardModelHadronSpectrum::makeDiquark(tcPDPtr par1, tcPDPtr par2) const {
-    long id1 = par1->id();
-    long id2 = par2->id();
-    long pspin = id1==id2 ? 3 : 1;
-    long idnew = makeDiquarkID(id1,id2, pspin);
-    return getParticleData(idnew);
-}
-
 Energy StandardModelHadronSpectrum::hadronPairThreshold(tcPDPtr par1, tcPDPtr par2) const {
   // Determine the sum of the nominal masses of the two lightest hadrons
   // with the right flavour numbers as the cluster under consideration.
   // Notice that we don't need real masses (drawn by a Breit-Wigner 
   // distribution) because the lightest pair of hadrons does not involve
   // any broad resonance.
   Energy threshold = massLightestHadronPair(par1,par2);
   // Special: it allows one-hadron decays also above threshold.
   if (isExotic(par1,par2)) 
     threshold *= (1.0 + UseRandom::rnd()*_limExotic);
   else if (hasBottom(par1,par2)) 
     threshold *= (1.0 + UseRandom::rnd()*_limBottom);
   else if (hasCharm(par1,par2)) 
     threshold *= (1.0 + UseRandom::rnd()*_limCharm);
   return threshold;
 }
   
 double StandardModelHadronSpectrum::mixingStateWeight(long id) const {
   switch(id) {
   case ParticleID::eta:      return 0.5*probabilityMixing(_etamix  ,1);
   case ParticleID::etaprime: return 0.5*probabilityMixing(_etamix  ,2);
   case ParticleID::phi:      return 0.5*probabilityMixing(_phimix  ,1);
   case ParticleID::omega:    return 0.5*probabilityMixing(_phimix  ,2);
   case ParticleID::hprime_1: return 0.5*probabilityMixing(_h1mix   ,1);
   case ParticleID::h_1:      return 0.5*probabilityMixing(_h1mix   ,2);
   case 10331:                return 0.5*probabilityMixing(_f0mix   ,1);
   case 10221:                return 0.5*probabilityMixing(_f0mix   ,2);
   case ParticleID::fprime_1: return 0.5*probabilityMixing(_f1mix   ,1);
   case ParticleID::f_1:      return 0.5*probabilityMixing(_f1mix   ,2);
   case ParticleID::fprime_2: return 0.5*probabilityMixing(_f2mix   ,1);
   case ParticleID::f_2:      return 0.5*probabilityMixing(_f2mix   ,2);
   case 10335:                return 0.5*probabilityMixing(_eta2mix ,1);
   case 10225:		     return 0.5*probabilityMixing(_eta2mix ,2);
   case 30333:		     return 0.5*probabilityMixing(_omhmix  ,1);
   case 30223:		     return 0.5*probabilityMixing(_omhmix  ,2);
   case 337:                  return 0.5*probabilityMixing(_ph3mix  ,1);
   case 227:		     return 0.5*probabilityMixing(_ph3mix  ,2);
   case 100331:               return 0.5*probabilityMixing(_eta2mix ,1);
   case 100221:		     return 0.5*probabilityMixing(_eta2mix ,2);
   case 100333:               return 0.5*probabilityMixing(_phi2Smix,1);
   case 100223:		     return 0.5*probabilityMixing(_phi2Smix,2);
   default:                   return 1./3.;
   }
 }
 
 void StandardModelHadronSpectrum::doinit() {
   // set the weights for the various excited mesons
   // set all to one to start with
   for (int l = 0; l < Lmax; ++l ) {
     for (int j = 0; j < Jmax; ++j) {
       for (int n = 0; n < Nmax; ++n) {
 	_repwt[l][j][n] = 1.0;
       }
     }
   }
   // set the others from the relevant vectors
   for( int ix=0;ix<max(int(_weight1S0.size()),int(Nmax));++ix)
     _repwt[0][0][ix]=_weight1S0[ix];
   for( int ix=0;ix<max(int(_weight3S1.size()),int(Nmax));++ix)
     _repwt[0][1][ix]=_weight3S1[ix];
   for( int ix=0;ix<max(int(_weight1P1.size()),int(Nmax));++ix)
     _repwt[1][1][ix]=_weight1P1[ix];
   for( int ix=0;ix<max(int(_weight3P0.size()),int(Nmax));++ix)
     _repwt[1][0][ix]=_weight3P0[ix];
   for( int ix=0;ix<max(int(_weight3P1.size()),int(Nmax));++ix)
     _repwt[1][1][ix]=_weight3P1[ix];
   for( int ix=0;ix<max(int(_weight3P2.size()),int(Nmax));++ix)
     _repwt[1][2][ix]=_weight3P2[ix];
   for( int ix=0;ix<max(int(_weight1D2.size()),int(Nmax));++ix)
     _repwt[2][2][ix]=_weight1D2[ix];
   for( int ix=0;ix<max(int(_weight3D1.size()),int(Nmax));++ix)
     _repwt[2][1][ix]=_weight3D1[ix];
   for( int ix=0;ix<max(int(_weight3D2.size()),int(Nmax));++ix)
     _repwt[2][2][ix]=_weight3D2[ix];
   for( int ix=0;ix<max(int(_weight3D3.size()),int(Nmax));++ix)
     _repwt[2][3][ix]=_weight3D3[ix];
 
   // find the maximum
   map<long,double>::iterator pit =
     max_element(_pwt.begin(),_pwt.end(),weightIsLess); 
   const double pmax = pit->second;
   for(pit=_pwt.begin(); pit!=_pwt.end(); ++pit) {
     pit->second/=pmax;
   }
   HadronSpectrum::doinit();
 }
 
 void StandardModelHadronSpectrum::constructHadronTable() {
   // initialise the table
   _table.clear();
   for(unsigned int ix=0; ix<_partons.size(); ++ix) {
     for(unsigned int iy=0; iy<_partons.size(); ++iy) {
       if (!(DiquarkMatcher::Check(_partons[ix]->id()) 
 	    && DiquarkMatcher::Check(_partons[iy]->id())))
       _table[make_pair(_partons[ix]->id(),_partons[iy]->id())] = KupcoData();
     }
   }
   // get the particles from the event generator
   ParticleMap particles = generator()->particles();
   // loop over the particles
   //double maxdd(0.),maxss(0.),maxrest(0.);
   for(ParticleMap::iterator it=particles.begin(); 
       it!=particles.end(); ++it) {
     long pid = it->first;
     tPDPtr particle = it->second;
     int pspin = particle->iSpin();
     // Don't include hadrons which are explicitly forbidden
     if(find(_forbidden.begin(),_forbidden.end(),particle)!=_forbidden.end()) 
       continue;
     // Don't include non-hadrons or antiparticles
     if(pid < 100) continue;
     // remove diffractive particles
     if(pspin == 0) continue;
     // K_0S and K_0L not made make K0 and Kbar0
     if(pid==ParticleID::K_S0||pid==ParticleID::K_L0) continue;
     // Debugging options
     // Only include those with 2J+1 less than...5
     if(_trial==2 && pspin >= 5) continue;
     // Only include those with 2J+1 less than...7
     if(_trial==3 && pspin >= 7) continue;
     // Only include pions
     if(_trial==1 && pid!=111 && pid!=211) continue;
     // shouldn't be coloured
     if(particle->coloured()) continue;
     // Get the flavours
     const int x4 = (pid/1000)%10; 
     const int x3 = (pid/100 )%10;
     const int x2 = (pid/10  )%10;
     const int x7 = (pid/1000000)%10;
     const bool wantSusy = x7 == 1 || x7 == 2;
     // Skip non-hadrons (susy particles, etc...)
     if(x3 == 0 || x2 == 0) continue;
     // Skip particles which are neither SM nor SUSY 
     if(x7 >= 3 && x7 != 9) continue;
     int flav1,flav2;
     // meson
     if(x4 == 0) {
       flav1 = x2;
       flav2 = x3;
     }
     // baryon
     else {
       flav2 = x4;
       // insert the spin 1 diquark, sort out the rest later
       flav1 = makeDiquarkID(x2,x3,3);
     }
     if (wantSusy) flav2 += 1000000 * x7;
     insertToHadronTable(particle,flav1,flav2);
   }
   // normalise the weights
 
 
   if(_topt == 0) {
     HadronTable::const_iterator tit;
     KupcoData::iterator it;
     for(tit=_table.begin();tit!=_table.end();++tit) {
       double weight=0;
       for(it = tit->second.begin(); it!=tit->second.end(); ++it)
 	weight=max(weight,it->overallWeight);
       weight = 1./weight;
     }
 
     //   double weight;
     //   if(tit->first.first==tit->first.second) {
     // 	if(tit->first.first==1||tit->first.first==2) weight=1./maxdd;
     // 	else if (tit->first.first==3)                weight=1./maxss;
     // 	else                                         weight=1./maxrest;
     //   }
     //   else                                           weight=1./maxrest;
     //   for(it = tit->second.begin(); it!=tit->second.end(); ++it) {
     // 	it->rescale(weight);
     //   }
     // }
   }
 }
 
 double StandardModelHadronSpectrum::strangeWeight(const Energy, tcPDPtr, tcPDPtr) const {
   assert(false);
 }
 
 void StandardModelHadronSpectrum::insertMeson(HadronInfo a, int flav1, int flav2) {
   // identical light flavours
   if(flav1 == flav2 && flav1<=3) {
     // ddbar> uubar> admixture states
     if(flav1==1) {
       a.overallWeight *= 0.5;
       _table[make_pair(1,1)].insert(a);
       _table[make_pair(2,2)].insert(a);
     }
     // load up ssbar> uubar> ddbar> admixture states
     else {
       // uubar ddbar pieces
       a.wt = mixingStateWeight(a.id);
       a.overallWeight *= a.wt;
       _table[make_pair(1,1)].insert(a);
       _table[make_pair(2,2)].insert(a);
       a.overallWeight /=a.wt;
       // ssbar piece
       a.wt = 1.- 2.*a.wt;
       if(a.wt > 0) {
         a.overallWeight *= a.wt;
         _table[make_pair(3,3)].insert(a);
       }
     }
   }
   else {
     _table[make_pair(flav1,flav2)].insert(a);
     if(flav1 != flav2) _table[make_pair(flav2,flav1)].insert(a);
   }
 }
 
 
 long StandardModelHadronSpectrum::makeDiquarkID(long id1, long id2, long pspin) const {
 
   assert( id1 * id2 > 0  
           && QuarkMatcher::Check(id1)  
 	  && QuarkMatcher::Check(id2)) ;
   long ida = abs(id1);
   long idb = abs(id2);
   if (ida < idb) swap(ida,idb);
   if (pspin != 1 && pspin != 3) assert(false);
   long idnew = ida*1000 + idb*100 + pspin;
   // Diquarks made of quarks of the same type: uu, dd, ss, cc, bb,
   // have spin 1, and therefore the less significant digit (which
   // corresponds to 2*J+1) is 3 rather than 1 as all other Diquarks.
   if (id1 == id2 && pspin == 1) {
     //cerr<<"WARNING: spin-0 diquiark of the same type cannot exist."
     //    <<" Switching to spin-1 diquark.\n";
     idnew = ida*1000 + idb*100 + 3;
   }
 
   return id1 > 0 ? idnew : -idnew;
 }
 
 bool StandardModelHadronSpectrum::hasBottom(tcPDPtr par1, tcPDPtr par2, tcPDPtr par3) const {
   long id1 = par1 ? par1->id() : 0;
   if ( !par2  &&  !par3 ) {
     return 
       abs(id1) == ThePEG::ParticleID::b    ||
       isDiquarkWithB(par1)                 ||
       ( MesonMatcher::Check(id1)  
 	&& (abs(id1)/100)%10  == ThePEG::ParticleID::b ) ||
       ( BaryonMatcher::Check(id1) 
 	&& (abs(id1)/1000)%10 == ThePEG::ParticleID::b );
   } 
   else {
     long id2 = par2 ? par2->id() : 0;
     long id3 = par3 ? par3->id() : 0;
     return 
       abs(id1) == ThePEG::ParticleID::b  ||  isDiquarkWithB(par1)  || 
       abs(id2) == ThePEG::ParticleID::b  ||  isDiquarkWithB(par2)  || 
       abs(id3) == ThePEG::ParticleID::b  ||  isDiquarkWithB(par3); 
   }
 }
 
 
 bool StandardModelHadronSpectrum::hasCharm(tcPDPtr par1, tcPDPtr par2, tcPDPtr par3) const {
   long id1 = par1 ? par1->id(): 0;
   if (!par2  &&  !par3) {
     return
       abs(id1) == ThePEG::ParticleID::c     ||
       isDiquarkWithC(par1)                  ||
       ( MesonMatcher::Check(id1) && 
         ((abs(id1)/100)%10 == ThePEG::ParticleID::c ||
 	 (abs(id1)/10)%10 == ThePEG::ParticleID::c) ) ||
       ( BaryonMatcher::Check(id1) && 
         ((abs(id1)/1000)%10 == ThePEG::ParticleID::c  ||
 	 (abs(id1)/100)%10  == ThePEG::ParticleID::c  ||
 	 (abs(id1)/10)%10   == ThePEG::ParticleID::c) );
   } 
   else {
  long id2 = par2 ? par1->id(): 0;
  long id3 = par3 ? par1->id(): 0;
     return 
       abs(id1) == ThePEG::ParticleID::c  ||  isDiquarkWithC(par1)  || 
       abs(id2) == ThePEG::ParticleID::c  ||  isDiquarkWithC(par2)  || 
       abs(id3) == ThePEG::ParticleID::c  ||  isDiquarkWithC(par3); 
   }
 }  
 
 bool StandardModelHadronSpectrum::isExotic(tcPDPtr par1, tcPDPtr par2, tcPDPtr par3) const {
   /// \todo make this more general
   long id1 = par1 ? par1->id(): 0;
   long id2 = par2 ? par2->id(): 0;
   long id3 = par3 ? par3->id(): 0;
 return 
   ( (id1/1000000)% 10 != 0 && (id1/1000000)% 10 != 9 ) ||
   ( (id2/1000000)% 10 != 0 && (id2/1000000)% 10 != 9 ) ||
   ( (id3/1000000)% 10 != 0 && (id3/1000000)% 10 != 9 ) ||
   abs(id1)==6||abs(id2)==6;
 }
 
 
 bool StandardModelHadronSpectrum::canBeBaryon(tcPDPtr par1, tcPDPtr par2 , tcPDPtr par3) const {
   assert(par1 && par2);
   long id1 = par1->id(), id2 = par2->id();
   if (!par3) {
     if( id1*id2 < 0) return false;
     if(DiquarkMatcher::Check(id1))
 return abs(int(par2->iColour())) == 3 && !DiquarkMatcher::Check(id2); 
     if(DiquarkMatcher::Check(id2))
 return abs(int(par1->iColour())) == 3;
     return false;
   } 
   else {
     // In this case, to be a baryon, all three components must be (anti-)quarks
     // and with the same sign.
     return (par1->iColour() == 3 && par2->iColour() == 3 && par3->iColour() == 3) ||
 (par1->iColour() == -3 && par2->iColour() == -3 && par3->iColour() == -3);
   }
 }
diff --git a/Hadronization/StandardModelHadronSpectrum.h b/Hadronization/StandardModelHadronSpectrum.h
--- a/Hadronization/StandardModelHadronSpectrum.h
+++ b/Hadronization/StandardModelHadronSpectrum.h
@@ -1,622 +1,614 @@
 // -*- C++ -*-
 #ifndef Herwig_StandardModelHadronSpectrum_H
 #define Herwig_StandardModelHadronSpectrum_H
 //
 // This is the declaration of the StandardModelHadronSpectrum class.
 //
 
 #include "Herwig/Hadronization/HadronSpectrum.h"
 #include <ThePEG/PDT/ParticleData.h>
 #include <ThePEG/PDT/StandardMatchers.h>
 #include <ThePEG/Repository/EventGenerator.h>
 #include <ThePEG/PDT/EnumParticles.h>
 #include "ThePEG/Repository/CurrentGenerator.h"
 
 #include <ThePEG/Persistency/PersistentOStream.h>
 #include <ThePEG/Persistency/PersistentIStream.h>
 namespace Herwig {
 
 using namespace ThePEG;
 
 /**
  * Here is the documentation of the StandardModelHadronSpectrum class.
  *
  * @see \ref StandardModelHadronSpectrumInterfaces "The interfaces"
  * defined for StandardModelHadronSpectrum.
  */
 class StandardModelHadronSpectrum: public HadronSpectrum {
 
 public:
 
   /** @name Standard constructors and destructors. */
   //@{
   /**
    * The default constructor.
    */
   StandardModelHadronSpectrum(unsigned int opt);
 
   /**
    * The destructor.
    */
   virtual ~StandardModelHadronSpectrum();
   //@}
 
 public:
 
   /** @name Partonic content */
   //@{
 
   /**
    * Return the id of the gluon
    */
   virtual long gluonId() const { return ParticleID::g; }
 
   /**
    * Return the ids of all hadronizing quarks
    */
   virtual const vector<long>& hadronizingQuarks() const {
     static vector<long> hadronizing =
       { ParticleID::d, ParticleID::u, ParticleID::s, ParticleID::c, ParticleID::b };
     return hadronizing;
   }
 
   /**
    * The light hadronizing quarks
    */
   virtual const vector<long>& lightHadronizingQuarks() const {
     static vector<long> light =
       { ParticleID::d, ParticleID::u, ParticleID::s };
     return light;
   }
 
   /**
    * The light hadronizing diquarks
    */
   virtual const vector<long>& lightHadronizingDiquarks() const {
 	  /**
 	   * Diquarks q==q_0 are not allowed as they need to have antisymmetric
 	   * spin wave-function, which forces the spin to 1
 	   * Diquarks q!=q'_1 are not allowed as they need to have antisymmetric
 	   * spin wave-function, which forces the spin to 1
 	   * */
 
 		// TODO: strange diquarks are turned off for the moment
 		// 		 since in combination with the current ClusterFission
 		// 		 they fail (overshoot) to reproduce the Xi and Lambda 
 		// 		 pT spectra.
 		// 		 One may enable these after the ClusterFission
 		// 		 kinematics are settled
 		// TODO why ud_1 not allowed?
 		// exceptions: Could not find 2103 1 in _table
 		// but no problem for 2103 2 ???
 		// ParticleID::ud_1
 	switch(_hadronizingStrangeDiquarks) {
 		case 0:
 			{
 				static vector<long> light = {
 					ParticleID::uu_1,
 					ParticleID::dd_1,
 					ParticleID::ud_0
 					// ParticleID::ud_1,
 				};
 				return light;
 				// break;
 			}
 		case 1:
 			{
 				static vector<long> light = {
 					ParticleID::uu_1,
 					ParticleID::dd_1,
 					ParticleID::ud_0,
 					// ParticleID::ud_1,
 					ParticleID::su_0,
 					// ParticleID::su_1,
 					ParticleID::sd_0
 					// ParticleID::sd_1
 				};
 				return light;
 			}
 		case 2:
 			{
 				static vector<long> light = {
 					ParticleID::uu_1,
 					ParticleID::dd_1,
 					ParticleID::ud_0,
 					// ParticleID::ud_1,
 					ParticleID::su_0,
 					// ParticleID::su_1,
 					ParticleID::sd_0,
 					// ParticleID::sd_1,
 					ParticleID::ss_1
 				};
 				return light;
 				// break;
 			}
 		default:
 			assert(false);
 	}
 	static vector<long> light;
 	return light;
   }
 
   /**
    * The heavy hadronizing quarks
    */
   virtual const vector<long>& heavyHadronizingQuarks() const {
     static vector<long> heavy =
       { ParticleID::c, ParticleID::b };
     return heavy;
   }
 
   /**
    * Return true if any of the possible three input particles contains
    * the indicated heavy quark.  false otherwise. In the case that
    * only the first particle is specified, it can be: an (anti-)quark,
    * an (anti-)diquark an (anti-)meson, an (anti-)baryon; in the other
    * cases, each pointer is assumed to be either (anti-)quark or
    * (anti-)diquark.
    */
   virtual bool hasHeavy(long id, tcPDPtr par1, tcPDPtr par2 = PDPtr(), tcPDPtr par3 = PDPtr()) const {
     if ( abs(id) == ParticleID::c )
       return hasCharm(par1,par2,par3);
     if ( abs(id) == ParticleID::b )
       return hasBottom(par1,par2,par3);
     return false;
   }
 
   //@}
 
   /**
    * Return the threshold for a cluster to split into a pair of hadrons.
    * This is normally the mass of the lightest hadron Pair, but can be
    * higher for heavy and exotic clusters
    */
   virtual Energy hadronPairThreshold(tcPDPtr par1, tcPDPtr par2) const;
 
   /**
    * Return the weight for the given flavour
    */
   virtual double pwtQuark(const long& id) const {
     switch(id) {
     case ParticleID::d: return pwtDquark(); break;
     case ParticleID::u: return pwtUquark(); break;
     case ParticleID::s: return pwtSquark(); break;
     case ParticleID::c: return pwtCquark(); break;
     case ParticleID::b: return pwtBquark(); break;
     }
     return 0.;
   }
 
   /**
    * The down quark weight.
    */
    double pwtDquark()  const {
     return _pwtDquark;
   } 
 
   /**
    * The up quark weight.
    */
    double pwtUquark()  const { 
     return _pwtUquark;
   }
 
   /**
    * The strange quark weight.
    */
    double pwtSquark()  const { 
     return _pwtSquark;
   }
 
   /**
    * The charm quark weight.
    */
    double pwtCquark()  const { 
     return _pwtCquark;
   }
 
   /**
    * The bottom quark weight.
    */
    double pwtBquark()  const { 
     return _pwtBquark;
   } 
   
   /**
    * The diquark weight.
    */
    double pwtDIquark() const {
     return _pwtDIquark;
   }
 
 public:
 
   /** @name Functions used by the persistent I/O system. */
   //@{
   /**
    * Function used to write out object persistently.
    * @param os the persistent output stream written to.
    */
   void persistentOutput(PersistentOStream & os) const;
 
   /**
    * Function used to read in object persistently.
    * @param is the persistent input stream read from.
    * @param version the version number of the object when written.
    */
   void persistentInput(PersistentIStream & is, int version);
   //@}
 
   /**
    * The standard Init function used to initialize the interfaces.
    * Called exactly once for each class by the class description system
    * before the main function starts or
    * when this class is dynamically loaded.
    */
   static void Init();
 
-  /**
-   * Return the particle data of the diquark (anti-diquark) made by the two 
-   * quarks (antiquarks) par1, par2.
-   * @param par1 (anti-)quark data pointer
-   * @param par2 (anti-)quark data pointer
-   */
-  PDPtr makeDiquark(tcPDPtr par1, tcPDPtr par2) const;
-
 protected:
 
   /** @name Standard Interfaced functions. */
   //@{
   /**
    * Initialize this object after the setup phase before saving an
    * EventGenerator to disk.
    *
    *  The array _repwt is initialized using the interfaces to set different
    *  weights for different meson multiplets and the constructHadronTable()
    *  method called to complete the construction of the hadron tables.
    *
    * @throws InitException if object could not be initialized properly.
    */
   virtual void doinit();
   //@}
 
   
   /**
    * Return the id of the diquark (anti-diquark) made by the two 
    * quarks (antiquarks) of id specified in input (id1, id2).
    * Caller must ensure that id1 and id2 are quarks.
    */
   long makeDiquarkID(long id1, long id2, long pspin)  const;
 
   /**
    * Return true if any of the possible three input particles has
    * b-flavour; 
    * false otherwise. In the case that only the first particle is specified,
    * it can be: an (anti-)quark, an (anti-)diquark
    * an (anti-)meson, an (anti-)baryon; in the other cases, each pointer
    * is assumed to be either (anti-)quark or (anti-)diquark.
    */
   bool hasBottom(tcPDPtr par1, tcPDPtr par2 = PDPtr(), tcPDPtr par3 = PDPtr())  const;
   /**
    * Return true if any of the possible three input particles has 
    * c-flavour; 
    * false otherwise.In the case that only the first pointer is specified,
    * it can be: a (anti-)quark, a (anti-)diquark
    * a (anti-)meson, a (anti-)baryon; in the other cases, each pointer
    * is assumed to be either (anti-)quark or (anti-)diquark.
    */
   bool hasCharm(tcPDPtr par1, tcPDPtr par2 = PDPtr(), tcPDPtr par3 = PDPtr())  const;
   /**
    * Return true, if any of the possible input particle pointer is an exotic quark, e.g. Susy quark;
    * false otherwise.   
    */
   bool isExotic(tcPDPtr par1, tcPDPtr par2 = PDPtr(), tcPDPtr par3 = PDPtr())  const;
 
   /**
    * Return true if the two or three particles in input can be the components 
    * of a baryon; false otherwise.
    */
   virtual bool canBeBaryon(tcPDPtr par1, tcPDPtr par2 , tcPDPtr par3 = PDPtr())  const;
 
 protected:
 
   /**
    *  Construct the table of hadron data
    *  This is the main method to initialize the hadron data (mainly the
    *  weights associated to each hadron, taking into account its spin, 
    *  eventual isoscalar-octect mixing, singlet-decuplet factor). This is
    *  the method that one should update when new or updated hadron data is
    *  available. 
    *
    *  This class implements the construction of the basic table but can be 
    *  overridden if needed in inheriting classes.
    *
    *  The rationale for factors used for diquarks involving different quarks can 
    *  be can be explained by taking a prototype example that in the  exact SU(2) limit,
    *  in which:
    *  \f[m_u=m_d\f] 
    *  \f[M_p=M_n=M_\Delta\f]
    *      and we will have equal numbers of u and d quarks produced.
    *      Suppose that we weight 1 the diquarks made of the same 
    *      quark and 1/2 those made of different quarks, the fractions
    *      of u and d baryons (p, n, Delta) we get are the following:
    *        - \f$\Delta^{++}\f$: 1 possibility only  u uu  with weight 1
    *        - \f$\Delta^-   \f$: 1 possibility only  d dd  with weight 1
    *        - \f$p,\Delta^+ \f$: 2 possibilities     u ud  with weight 1/2
    *                                                 d uu  with weight 1
    *        - \f$n,\Delta^0 \f$: 2 possibilities     d ud  with weight 1/2
    *                                                 u dd  with weight 1
    *      In the latter two cases, we have to take into account the 
    *      fact that  p  and  n  have spin 1/2 whereas  Delta+  and  Delta0
    *      have spin 3/2 therefore from phase space we get a double weight 
    *      for  Delta+  and  Delta0  relative to  p  and  n  respectively.
    *      Therefore the relative amount of these baryons that is
    *      produced is the following:
    *       # p = # n = ( 1/2 + 1 ) * 1/3 = 1/2
    *       # Delta++ = # Delta- = 1 = ( 1/2 + 1) * 2/3 # Delta+ = # Delta0
    *      which is correct, and therefore the weight 1/2 for the
    *      diquarks of different types of quarks is justified (at least
    *      in this limit of exact SU(2) ).
    */
   virtual void constructHadronTable();
 
   /**
    *   Insert a meson in the table
    */
   virtual void insertMeson(HadronInfo a, int flav1, int flav2);
 
   /**
    * Methods for the mixing of \f$I=0\f$ mesons
    */
   //@{
   /**
    * Return the probability of mixing for Octet-Singlet isoscalar mixing,
    * the probability of the 
    * \f$\frac1{\sqrt{2}}(|u\bar{u}\rangle + |d\bar{d}\rangle)\f$ component
    * is returned.
    * @param angleMix The mixing angle in degrees (not radians)
    * @param order is 0 for no mixing, 1 for the first resonance of a pair,
    *                 2 for the second one.
    * The mixing is defined so that for example with \f$\eta-\eta'\f$ mixing where
    * the mixing angle is \f$\theta=-23^0$ with $\eta\f$ as the first particle
    * and \f$\eta'\f$ the second one.
    * The convention used is 
    * \f[\eta  = \cos\theta|\eta_{\rm octet  }\rangle
    *           -\sin\theta|\eta_{\rm singlet}\rangle\f]
    * \f[\eta' = \sin\theta|\eta_{\rm octet  }\rangle
    *           -\cos\theta|\eta_{\rm singlet}\rangle\f]
    * with 
    * \f[|\eta_{\rm singlet}\rangle = \frac1{\sqrt{3}}
    * \left[|u\bar{u}\rangle + |d\bar{d}\rangle +  |s\bar{s}\rangle\right]\f]
    * \f[|\eta_{\rm octet  }\rangle = \frac1{\sqrt{6}}
    * \left[|u\bar{u}\rangle + |d\bar{d}\rangle - 2|s\bar{s}\rangle\right]\f]
    */
    double probabilityMixing(const double angleMix,
 				  const int order) const {
     static double convert=Constants::pi/180.0;
     if (order == 1)      
       return sqr( cos( angleMix*convert + atan( sqrt(2.0) ) ) );
     else if (order == 2) 
       return sqr( sin( angleMix*convert + atan( sqrt(2.0) ) ) );
     else                 
       return 1.;
   }
 
   /**
    * Returns the weight of given mixing state.
    * @param id The PDG code of the meson
    */
   virtual double mixingStateWeight(long id) const; 
   //@}
 
   virtual double specialQuarkWeight(double quarkWeight, long id,
             const Energy cluMass, tcPDPtr par1, tcPDPtr par2) const {
     // special for strange
     if(abs(id) == 3)
       return strangeWeight(cluMass,par1,par2);
     else
       return quarkWeight;
   }
 
   /**
    *  Strange quark weight
    */
   virtual double strangeWeight(const Energy cluMass, tcPDPtr par1, tcPDPtr par2) const;
 
   /**
    *  Strange diquark option for Hadronization
    */
   unsigned int _hadronizingStrangeDiquarks;
   /**
    *  The weights for the different quarks and diquarks
    */
   //@{
   /**
    * The probability of producting a down quark.
    */
   double _pwtDquark;
 
   /**
    * The probability of producting an up quark.
    */
   double _pwtUquark;
 
   /**
    * The probability of producting a strange quark.
    */
   double _pwtSquark;
 
   /**
    * The probability of producting a charm quark.
    */
   double _pwtCquark;
 
   /**
    * The probability of producting a bottom quark.
    */
   double _pwtBquark;
   //@}
 
   /**
    * The probability of producting a diquark.
    */
   double _pwtDIquark;
   /**
    * Singlet and Decuplet weights
    */
   //@{
   /**
    *  The singlet weight
    */
   double _sngWt; 
 
   /**
    *  The decuplet weight
    */
   double _decWt; 
   //@}
 
   /**
    *  The mixing angles for the \f$I=0\f$ mesons containing light quarks
    */
   //@{
   /**
    *  The \f$\eta-\eta'\f$ mixing angle 
    */
   double _etamix;
 
   /**
    *  The \f$\phi-\omega\f$ mixing angle
    */
   double _phimix;
 
   /**
    *  The \f$h_1'-h_1\f$ mixing angle
    */
   double _h1mix;
 
   /**
    *  The \f$f_0(1710)-f_0(1370)\f$ mixing angle
    */
   double _f0mix;
 
   /**
    *  The \f$f_1(1420)-f_1(1285)\f$ mixing angle
    */
   double _f1mix;
 
   /**
    *  The \f$f'_2-f_2\f$ mixing angle
    */
   double _f2mix;
 
   /**
    *  The \f$\eta_2(1870)-\eta_2(1645)\f$ mixing angle
    */
   double _eta2mix;
 
   /**
    *  The \f$\phi(???)-\omega(1650)\f$ mixing angle
    */
   double _omhmix;
 
   /**
    *  The \f$\phi_3-\omega_3\f$ mixing angle
    */
   double _ph3mix;
 
   /**
    *  The \f$\eta(1475)-\eta(1295)\f$ mixing angle
    */
   double _eta2Smix;
 
   /**
    *  The \f$\phi(1680)-\omega(1420)\f$ mixing angle
    */
   double _phi2Smix;
   //@}
 
   /**
    *  The weights for the various meson multiplets to be used to supress the
    * production of particular states
    */
   //@{
   /**
    *  The weights for the \f$\phantom{1}^1S_0\f$ multiplets
    */
   vector<double> _weight1S0;
 
   /**
    *  The weights for the \f$\phantom{1}^3S_1\f$ multiplets
    */
   vector<double> _weight3S1;
 
   /**
    *  The weights for the \f$\phantom{1}^1P_1\f$ multiplets
    */
   vector<double> _weight1P1;
 
   /**
    *  The weights for the \f$\phantom{1}^3P_0\f$ multiplets
    */
   vector<double> _weight3P0;
 
   /**
    *  The weights for the \f$\phantom{1}^3P_1\f$ multiplets
    */
   vector<double> _weight3P1;
 
   /**
    *  The weights for the \f$\phantom{1}^3P_2\f$ multiplets
    */
   vector<double> _weight3P2;
 
   /**
    *  The weights for the \f$\phantom{1}^1D_2\f$ multiplets
    */
   vector<double> _weight1D2;
 
   /**
    *  The weights for the \f$\phantom{1}^3D_1\f$ multiplets
    */
   vector<double> _weight3D1;
 
   /**
    *  The weights for the \f$\phantom{1}^3D_2\f$ multiplets
    */
   vector<double> _weight3D2;
 
   /**
    *  The weights for the \f$\phantom{1}^3D_3\f$ multiplets
    */
   vector<double> _weight3D3;
   //@}
 
   /**
    *  Option for the construction of the tables
    */ 
   unsigned int _topt;
 
   /**
    *  Which particles to produce for debugging purposes
    */
   unsigned int _trial;
 
   /**
    * @name A parameter used for determining when clusters are too light.
    *
    * This parameter is used for setting the lower threshold, \f$ t \f$ as
    * \f[ t' = t(1 + r B^1_{\rm lim}) \f]
    * where \f$ r \f$ is a random number [0,1].
    */
   //@{
   double _limBottom;
   double _limCharm;
   double _limExotic;
   //@}
 
 };
 
 }
 
 #endif /* Herwig_StandardModelHadronSpectrum_H */
diff --git a/src/defaults/Hadronization.in b/src/defaults/Hadronization.in
--- a/src/defaults/Hadronization.in
+++ b/src/defaults/Hadronization.in
@@ -1,143 +1,143 @@
 # -*- ThePEG-repository -*-
 
 ############################################################
 # Setup of default hadronization 
 #
 # There are no user servicable parts inside.
 #
 # Anything that follows below should only be touched if you 
 # know what you're doing. 
 #############################################################
 
 cd /Herwig/Particles
 create ThePEG::ParticleData Cluster
 setup Cluster 81 Cluster 0.00990 0.0 0.0 0.0  0 0  0  1
 create ThePEG::ParticleData Remnant
 setup Remnant 82 Remnant 0.00990 0.0 0.0 0.0  0 0  0  1
 
 mkdir /Herwig/Hadronization
 cd /Herwig/Hadronization
 
 create Herwig::ClusterHadronizationHandler ClusterHadHandler
 create Herwig::PartonSplitter PartonSplitter
 create Herwig::ClusterFinder ClusterFinder
 create Herwig::ColourReconnector ColourReconnector
 create Herwig::ClusterFissioner ClusterFissioner
 create Herwig::LightClusterDecayer LightClusterDecayer
 create Herwig::ClusterDecayer ClusterDecayer
 create Herwig::HwppSelector SMHadronSpectrum
 
 newdef ClusterHadHandler:PartonSplitter PartonSplitter
 newdef ClusterHadHandler:ClusterFinder ClusterFinder
 newdef ClusterHadHandler:ColourReconnector ColourReconnector
 newdef ClusterHadHandler:ClusterFissioner ClusterFissioner
 newdef ClusterHadHandler:LightClusterDecayer LightClusterDecayer
 newdef ClusterHadHandler:ClusterDecayer ClusterDecayer
 
 do ClusterHadHandler:UseHandlersForInteraction QCD
 
 newdef ClusterHadHandler:MinVirtuality2 0.1*GeV2
 newdef ClusterHadHandler:MaxDisplacement 1.0e-10*millimeter
 newdef ClusterHadHandler:UnderlyingEventHandler NULL
 
 newdef PartonSplitter:HadronSpectrum SMHadronSpectrum
 newdef ClusterFinder:HadronSpectrum SMHadronSpectrum
 newdef ClusterFissioner:HadronSpectrum SMHadronSpectrum
 newdef ClusterDecayer:HadronSpectrum SMHadronSpectrum
 newdef LightClusterDecayer:HadronSpectrum SMHadronSpectrum
 
 # ColourReconnector Default Parameters
 newdef ColourReconnector:HadronSpectrum SMHadronSpectrum
 newdef ColourReconnector:ColourReconnection Yes
 newdef ColourReconnector:Algorithm Baryonic
 
 # Statistical CR Parameters:
 newdef ColourReconnector:AnnealingFactor 0.9
 newdef ColourReconnector:AnnealingSteps 50
 newdef ColourReconnector:TriesPerStepFactor 5.0
 newdef ColourReconnector:InitialTemperature 0.1
 
 # Plain and Baryonic CR Paramters
 newdef ColourReconnector:ReconnectionProbability 0.95
 newdef ColourReconnector:ReconnectionProbabilityBaryonic 0.7
 
 # BaryonicMesonic and BaryonicMesonic CR Paramters
 newdef ColourReconnector:ReconnectionProbability3Mto3M 0.5
 newdef ColourReconnector:ReconnectionProbability3MtoBBbar 0.5
 newdef ColourReconnector:ReconnectionProbabilityBbarBto3M 0.5
 newdef ColourReconnector:ReconnectionProbability2Bto2B 0.05
 newdef ColourReconnector:ReconnectionProbabilityMBtoMB 0.5
 newdef ColourReconnector:StepFactor 1.0
 newdef ColourReconnector:MesonToBaryonFactor 1.333
 
 # General Parameters and switches
 newdef ColourReconnector:MaxDistance 1.0e50
 newdef ColourReconnector:OctetTreatment All
 newdef ColourReconnector:CR2BeamClusters No
 newdef ColourReconnector:Junction Yes
 newdef ColourReconnector:LocalCR No
 newdef ColourReconnector:CausalCR No
 # Debugging 
 newdef ColourReconnector:Debug No
 
 # set ClusterFissioner parameters
-set /Herwig/Hadronization/ClusterFissioner:KinematicThreshold Dynamic
-set /Herwig/Hadronization/ClusterFissioner:ProbablityPowerFactor  3.3462
-set /Herwig/Hadronization/ClusterFissioner:ProbablityShift        6.0442
-set /Herwig/Hadronization/ClusterFissioner:KineticThresholdShift -1.5321
+newdef ClusterFissioner:KinematicThreshold Dynamic
+newdef ClusterFissioner:ProbablityPowerFactor  3.3462
+newdef ClusterFissioner:ProbablityShift        6.0442
+newdef ClusterFissioner:KineticThresholdShift -1.5321
 
 # Clustering parameters for light quarks
 newdef ClusterFissioner:ClMaxLight  3.2344
 newdef ClusterFissioner:ClPowLight  2.6464
 newdef ClusterFissioner:PSplitLight 0.7235
 newdef ClusterFissioner:Fission Default
 insert ClusterFissioner:FissionPwt 1 1.0
 insert ClusterFissioner:FissionPwt 2 1.0
 insert ClusterFissioner:FissionPwt 3 0.35743
 newdef ClusterDecayer:ClDirLight 1
 newdef ClusterDecayer:ClSmrLight 0.78
 
 # Clustering parameters for b-quarks
 insert ClusterFissioner:ClMaxHeavy 5 3.757*GeV
 insert ClusterFissioner:ClPowHeavy 5  0.547*GeV
 insert ClusterFissioner:PSplitHeavy 5 0.625*GeV
 insert ClusterDecayer:ClDirHeavy 5 1
 insert ClusterDecayer:ClSmrHeavy 5 0.078
 newdef SMHadronSpectrum:SingleHadronLimitBottom 0.000
 
 # Clustering parameters for c-quarks
 insert ClusterFissioner:ClMaxHeavy 4 3.950
 insert ClusterFissioner:ClPowHeavy 4  2.559
 insert ClusterFissioner:PSplitHeavy 4 0.994
 insert ClusterDecayer:ClDirHeavy 4 1
 insert ClusterDecayer:ClSmrHeavy 4 0.163
 newdef SMHadronSpectrum:SingleHadronLimitCharm 0.000
 
 # Clustering parameters for exotic quarks
 # (e.g. hadronizing Susy particles)
 newdef ClusterFissioner:ClMaxExotic  2.7*GeV
 newdef ClusterFissioner:ClPowExotic  1.46
 newdef ClusterFissioner:PSplitExotic 1.00
 newdef ClusterDecayer:ClDirExotic 1
 newdef ClusterDecayer:ClSmrExotic 0.
 newdef SMHadronSpectrum:SingleHadronLimitExotic 0.
 
 #
 insert PartonSplitter:SplitPwt 1 1.0
 insert PartonSplitter:SplitPwt 2 1.0
 insert PartonSplitter:SplitPwt 3 0.824135
 newdef PartonSplitter:Split Light
 
 # 
 newdef SMHadronSpectrum:PwtDquark  1.0
 newdef SMHadronSpectrum:PwtUquark  1.0
 newdef SMHadronSpectrum:PwtSquark  0.35743
 newdef SMHadronSpectrum:PwtCquark  0.0
 newdef SMHadronSpectrum:PwtBquark  0.0
 newdef SMHadronSpectrum:PwtDIquark 0.36452
 newdef SMHadronSpectrum:SngWt      0.88022
 newdef SMHadronSpectrum:DecWt      0.34622
 newdef SMHadronSpectrum:Mode 1
 newdef SMHadronSpectrum:BelowThreshold All
 
 create Herwig::SpinHadronizer SpinHadronizer