]> git.uio.no Git - u/mrichter/AliRoot.git/blobdiff - PYTHIA8/pythia8170/src/SpaceShower.cxx
Update to pythi8.170
[u/mrichter/AliRoot.git] / PYTHIA8 / pythia8170 / src / SpaceShower.cxx
diff --git a/PYTHIA8/pythia8170/src/SpaceShower.cxx b/PYTHIA8/pythia8170/src/SpaceShower.cxx
new file mode 100644 (file)
index 0000000..766bad2
--- /dev/null
@@ -0,0 +1,1827 @@
+// SpaceShower.cc is a part of the PYTHIA event generator.
+// Copyright (C) 2012 Torbjorn Sjostrand.
+// PYTHIA is licenced under the GNU GPL version 2, see COPYING for details.
+// Please respect the MCnet Guidelines, see GUIDELINES for details.
+
+// Function definitions (not found in the header) for the
+// SpaceShower class.
+
+#include "SpaceShower.h"
+
+namespace Pythia8 {
+
+//==========================================================================
+
+// The SpaceShower class.
+
+//--------------------------------------------------------------------------
+
+// Constants: could be changed here if desired, but normally should not.
+// These are of technical nature, as described for each.
+
+// Leftover companion can give PDF > 0 at small Q2 where other PDF's = 0,
+// and then one can end in infinite loop of impossible kinematics.
+const int    SpaceShower::MAXLOOPTINYPDF = 10; 
+
+// Switch to alternative (but equivalent) backwards evolution for
+// g -> Q Qbar (Q = c or b) when below QTHRESHOLD * mQ2.
+const double SpaceShower::CTHRESHOLD     = 2.0; 
+const double SpaceShower::BTHRESHOLD     = 2.0; 
+
+// Renew evaluation of PDF's when the pT2 step is bigger than this 
+// (in addition to initial scale and c and b thresholds.)
+const double SpaceShower::EVALPDFSTEP    = 0.1;
+
+// Lower limit on PDF value in order to avoid division by zero.
+const double SpaceShower::TINYPDF        = 1e-10;
+
+// Lower limit on estimated evolution rate, below which stop.
+const double SpaceShower::TINYKERNELPDF  = 1e-6;
+
+// Lower limit on pT2, below which branching is rejected. 
+const double SpaceShower::TINYPT2        = 0.25e-6;
+
+// No attempt to do backwards evolution of a heavy (c or b) quark 
+// if evolution starts at a scale pT2 < HEAVYPT2EVOL * mQ2.
+const double SpaceShower::HEAVYPT2EVOL   = 1.1;
+
+// No attempt to do backwards evolution of a heavy (c or b) quark 
+// if evolution starts at a  x > HEAVYXEVOL * x_max, where 
+// x_max is the largest possible x value for a g -> Q Qbar branching.
+const double SpaceShower::HEAVYXEVOL     = 0.9;
+  
+// When backwards evolution Q -> g + Q creates a heavy quark Q,
+// an earlier branching g -> Q + Qbar will restrict kinematics
+// to  M_{Q Qbar}^2 > EXTRASPACEQ * 4 m_Q^2. (Smarter to be found??) 
+const double SpaceShower::EXTRASPACEQ    = 2.0;
+
+// Never pick pT so low that alphaS is evaluated too close to Lambda_3. 
+const double SpaceShower::LAMBDA3MARGIN  = 1.1;
+
+// Do not warn for large PDF ratios at small pT2 scales.
+const double SpaceShower::PT2MINWARN = 1.;
+
+// Cutoff for f_e^e at x < 1 - 10^{-10} to be used in z selection.
+// Note: the x_min quantity come from 1 - x_max.
+const double SpaceShower::LEPTONXMIN     = 1e-10;
+const double SpaceShower::LEPTONXMAX     = 1. - 1e-10;
+
+// Stop l -> l gamma evolution slightly above m2l.
+const double SpaceShower::LEPTONPT2MIN   = 1.2;
+
+// Enhancement of l -> l gamma trial rate to compensate imperfect modelling.
+const double SpaceShower::LEPTONFUDGE    = 10.;
+
+//--------------------------------------------------------------------------
+
+// Initialize alphaStrong, alphaEM and related pTmin parameters.
+
+void SpaceShower::init( BeamParticle* beamAPtrIn, 
+  BeamParticle* beamBPtrIn) {
+
+  // Store input pointers for future use. 
+  beamAPtr        = beamAPtrIn;
+  beamBPtr        = beamBPtrIn;
+
+  // Main flags to switch on and off branchings.
+  doQCDshower     = settingsPtr->flag("SpaceShower:QCDshower");
+  doQEDshowerByQ  = settingsPtr->flag("SpaceShower:QEDshowerByQ");
+  doQEDshowerByL  = settingsPtr->flag("SpaceShower:QEDshowerByL");
+
+  // Matching in pT of hard interaction to shower evolution.
+  pTmaxMatch      = settingsPtr->mode("SpaceShower:pTmaxMatch"); 
+  pTdampMatch     = settingsPtr->mode("SpaceShower:pTdampMatch"); 
+  pTmaxFudge      = settingsPtr->parm("SpaceShower:pTmaxFudge"); 
+  pTmaxFudgeMPI   = settingsPtr->parm("SpaceShower:pTmaxFudgeMPI"); 
+  pTdampFudge     = settingsPtr->parm("SpaceShower:pTdampFudge"); 
+
+  // Optionally force emissions to be ordered in rapidity/angle.
+  doRapidityOrder = settingsPtr->flag("SpaceShower:rapidityOrder");
+
+  // Charm, bottom and lepton mass thresholds.
+  mc              = particleDataPtr->m0(4); 
+  mb              = particleDataPtr->m0(5); 
+  m2c             = pow2(mc);
+  m2b             = pow2(mb);
+
+  // Parameters of scale choices.
+  renormMultFac     = settingsPtr->parm("SpaceShower:renormMultFac");
+  factorMultFac     = settingsPtr->parm("SpaceShower:factorMultFac");
+
+  // Parameters of alphaStrong generation.
+  alphaSvalue     = settingsPtr->parm("SpaceShower:alphaSvalue");
+  alphaSorder     = settingsPtr->mode("SpaceShower:alphaSorder");
+  alphaS2pi       = 0.5 * alphaSvalue / M_PI;
+  
+  // Initialize alpha_strong generation.
+  alphaS.init( alphaSvalue, alphaSorder); 
+  
+  // Lambda for 5, 4 and 3 flavours.
+  Lambda5flav     = alphaS.Lambda5(); 
+  Lambda4flav     = alphaS.Lambda4(); 
+  Lambda3flav     = alphaS.Lambda3(); 
+  Lambda5flav2    = pow2(Lambda5flav);
+  Lambda4flav2    = pow2(Lambda4flav);
+  Lambda3flav2    = pow2(Lambda3flav);
+  // Regularization of QCD evolution for pT -> 0. Can be taken 
+  // same as for multiparton interactions, or be set separately.
+  useSamePTasMPI  = settingsPtr->flag("SpaceShower:samePTasMPI"); 
+  if (useSamePTasMPI) {
+    pT0Ref        = settingsPtr->parm("MultipartonInteractions:pT0Ref");
+    ecmRef        = settingsPtr->parm("MultipartonInteractions:ecmRef");
+    ecmPow        = settingsPtr->parm("MultipartonInteractions:ecmPow");
+    pTmin         = settingsPtr->parm("MultipartonInteractions:pTmin");
+  } else {
+    pT0Ref        = settingsPtr->parm("SpaceShower:pT0Ref");
+    ecmRef        = settingsPtr->parm("SpaceShower:ecmRef");
+    ecmPow        = settingsPtr->parm("SpaceShower:ecmPow");
+    pTmin         = settingsPtr->parm("SpaceShower:pTmin");
+  }
+
+  // Calculate nominal invariant mass of events. Set current pT0 scale.
+  sCM             = m2( beamAPtr->p(), beamBPtr->p());
+  eCM             = sqrt(sCM);
+  pT0             = pT0Ref * pow(eCM / ecmRef, ecmPow);
+
+  // Restrict pTmin to ensure that alpha_s(pTmin^2 + pT_0^2) does not blow up.
+  double pTminAbs = sqrtpos(pow2(LAMBDA3MARGIN) * Lambda3flav2 / renormMultFac
+                  - pT0*pT0);
+  if (pTmin < pTminAbs) { 
+    pTmin         = pTminAbs;
+    ostringstream newPTmin;
+    newPTmin << fixed << setprecision(3) << pTmin;
+    infoPtr->errorMsg("Warning in SpaceShower::init: pTmin too low",
+                     ", raised to " + newPTmin.str() );
+    infoPtr->setTooLowPTmin(true);
+  }
+
+  // Parameters of alphaEM generation.
+  alphaEMorder    = settingsPtr->mode("SpaceShower:alphaEMorder");
+
+  // Initialize alphaEM generation.
+  alphaEM.init( alphaEMorder, settingsPtr); 
+  // Parameters of QED evolution.
+  pTminChgQ       = settingsPtr->parm("SpaceShower:pTminchgQ"); 
+  pTminChgL       = settingsPtr->parm("SpaceShower:pTminchgL"); 
+
+  // Derived parameters of QCD evolution.
+  pT20            = pow2(pT0);
+  pT2min          = pow2(pTmin);
+  pT2minChgQ      = pow2(pTminChgQ);
+  pT2minChgL      = pow2(pTminChgL);
+
+  // Various other parameters. 
+  doMEcorrections = settingsPtr->flag("SpaceShower:MEcorrections");
+  doMEafterFirst  = settingsPtr->flag("SpaceShower:MEafterFirst");
+  doPhiPolAsym    = settingsPtr->flag("SpaceShower:phiPolAsym");
+  doPhiIntAsym    = settingsPtr->flag("SpaceShower:phiIntAsym");
+  strengthIntAsym = settingsPtr->parm("SpaceShower:strengthIntAsym");
+  nQuarkIn        = settingsPtr->mode("SpaceShower:nQuarkIn");
+
+  // Optional dampening at small pT's when large multiplicities.
+  enhanceScreening 
+    = settingsPtr->mode("MultipartonInteractions:enhanceScreening");
+  if (!useSamePTasMPI) enhanceScreening = 0;
+
+  // Possibility to allow user veto of emission step.
+  canVetoEmission = (userHooksPtr != 0) 
+                  ? userHooksPtr->canVetoISREmission() : false;
+
+} 
+
+//--------------------------------------------------------------------------
+
+// Find whether to limit maximum scale of emissions.
+// Also allow for dampening at factorization or renormalization scale. 
+
+bool SpaceShower::limitPTmax( Event& event, double Q2Fac, double Q2Ren) {
+
+  // Find whether to limit pT. Begin by user-set cases.
+  bool dopTlimit = false;
+  if      (pTmaxMatch == 1) dopTlimit = true;
+  else if (pTmaxMatch == 2) dopTlimit = false;
+   
+  // Look if any quark (u, d, s, c, b), gluon or photon in final state. 
+  else {
+    for (int i = 5; i < event.size(); ++i) 
+    if (event[i].status() != -21) {
+      int idAbs = event[i].idAbs();
+      if (idAbs <= 5 || idAbs == 21 || idAbs == 22) dopTlimit = true;
+    }
+  }
+
+  // Dampening at factorization or renormalization scale.
+  dopTdamp   = false;
+  pT2damp    = 0.;
+  if ( !dopTlimit && (pTdampMatch == 1 || pTdampMatch == 2) ) {
+    dopTdamp = true;
+    pT2damp  = pow2(pTdampFudge) * ((pTdampMatch == 1) ? Q2Fac : Q2Ren);
+  }
+
+  // Done.
+  return dopTlimit;
+}
+
+//--------------------------------------------------------------------------
+
+// Prepare system for evolution; identify ME.
+// Routine may be called after multiparton interactions, for a new subystem.
+
+void SpaceShower::prepare( int iSys, Event& event, bool limitPTmaxIn) {
+
+  // Find positions of incoming colliding partons.
+  int in1 = partonSystemsPtr->getInA(iSys);
+  int in2 = partonSystemsPtr->getInB(iSys);
+
+  // Rescattered partons cannot radiate.
+  bool canRadiate1 = !(event[in1].isRescatteredIncoming());
+  bool canRadiate2 = !(event[in2].isRescatteredIncoming());
+
+  // Reset dipole-ends list for first interaction. Also resonances.
+  if (iSys == 0) dipEnd.resize(0);
+  if (iSys == 0) idResFirst  = 0;
+  if (iSys == 1) idResSecond = 0;
+
+  // Find matrix element corrections for system.
+  int MEtype = findMEtype( iSys, event); 
+
+  // Maximum pT scale for dipole ends.
+  double pTmax1 = (limitPTmaxIn) ? event[in1].scale() : eCM;
+  double pTmax2 = (limitPTmaxIn) ? event[in2].scale() : eCM;
+  if (iSys == 0 && limitPTmaxIn) {
+    pTmax1 *= pTmaxFudge;
+    pTmax2 *= pTmaxFudge;
+  } else if (iSys > 0 && limitPTmaxIn) {
+    pTmax1 *= pTmaxFudgeMPI;
+    pTmax2 *= pTmaxFudgeMPI;
+  }
+
+  // Find dipole ends for QCD radiation.
+  // Note: colour type can change during evolution, so book also if zero.
+  if (doQCDshower) {
+    int colType1 = event[in1].colType();
+    if (canRadiate1) dipEnd.push_back( SpaceDipoleEnd( iSys,  1, 
+      in1, in2, pTmax1, colType1, 0, MEtype, canRadiate2) );
+    int colType2 = event[in2].colType();
+    if (canRadiate2) dipEnd.push_back( SpaceDipoleEnd( iSys,  2, 
+      in2, in1, pTmax2, colType2, 0, MEtype, canRadiate1) );
+  }
+
+  // Find dipole ends for QED radiation.
+  // Note: charge type can change during evolution, so book also if zero.
+  if (doQEDshowerByQ || doQEDshowerByL) {
+    int chgType1 = ( (event[in1].isQuark() && doQEDshowerByQ)
+      || (event[in1].isLepton() && doQEDshowerByL) )
+      ? event[in1].chargeType() : 0;
+    // Special: photons have charge zero, but can evolve (only off Q for now)
+    if (event[in1].id() == 22 && doQEDshowerByQ) chgType1 = 22 ;
+    if (canRadiate1) dipEnd.push_back( SpaceDipoleEnd( iSys, -1, 
+      in1, in2, pTmax1, 0, chgType1, MEtype, canRadiate2) );
+    int chgType2 = ( (event[in2].isQuark() && doQEDshowerByQ)
+      || (event[in2].isLepton() && doQEDshowerByL) )
+      ? event[in2].chargeType() : 0;
+    // Special: photons have charge zero, but can evolve (only off Q for now)
+    if (event[in2].id() == 22 && doQEDshowerByQ) chgType2 = 22 ;
+    if (canRadiate2) dipEnd.push_back( SpaceDipoleEnd( iSys, -2, 
+      in2, in1, pTmax2, 0, chgType2, MEtype, canRadiate1) );
+  }
+
+  // Store the z and pT2 values of the last previous splitting
+  // when an event history has already been constructed.
+  if (iSys == 0 && infoPtr->hasHistory()) {
+    double zNow   = infoPtr->zNowISR();
+    double pT2Now = infoPtr->pT2NowISR();
+    for (int iDipEnd = 0; iDipEnd < int(dipEnd.size()); ++iDipEnd) {
+      dipEnd[iDipEnd].zOld = zNow;
+      dipEnd[iDipEnd].pT2Old = pT2Now;
+      ++dipEnd[iDipEnd].nBranch;
+    }
+  }
+
+}
+
+//--------------------------------------------------------------------------
+// Select next pT in downwards evolution of the existing dipoles.
+
+double SpaceShower::pTnext( Event& event, double pTbegAll, double pTendAll, 
+  int nRadIn) {
+
+  // Current cm energy, in case it varies between events.
+  sCM           = m2( beamAPtr->p(), beamBPtr->p());
+  eCM           = sqrt(sCM);
+  pTbegRef      = pTbegAll;
+
+  // Starting values: no radiating dipole found.
+  nRad          = nRadIn;
+  double pT2sel = pow2(pTendAll);
+  iDipSel       = 0;
+  iSysSel       = 0;
+  dipEndSel     = 0; 
+
+  // Loop over all possible dipole ends.
+  for (int iDipEnd = 0; iDipEnd < int(dipEnd.size()); ++iDipEnd) {
+    iDipNow        = iDipEnd;
+    dipEndNow      = &dipEnd[iDipEnd];        
+    iSysNow        = dipEndNow->system;
+    dipEndNow->pT2 = 0.;
+   
+    // Check whether dipole end should be allowed to shower. 
+    double pT2begDip = pow2( min( pTbegAll, dipEndNow->pTmax ));
+    if (pT2begDip > pT2sel 
+      && ( dipEndNow->colType != 0 || dipEndNow->chgType != 0 ) ) {
+      double pT2endDip = 0.;
+
+      // Determine lower cut for evolution, for QCD or QED (q or l).      
+      if (dipEndNow->colType != 0) pT2endDip = max( pT2sel, pT2min );   
+      else if (abs(dipEndNow->chgType) != 3) pT2endDip 
+        = max( pT2sel, pT2minChgQ );   
+      else pT2endDip = max( pT2sel, pT2minChgL );  
+
+      // Find properties of dipole and radiating dipole end.
+      sideA        = ( abs(dipEndNow->side) == 1 ); 
+      BeamParticle& beamNow = (sideA) ? *beamAPtr : *beamBPtr;
+      BeamParticle& beamRec = (sideA) ? *beamBPtr : *beamAPtr;
+      iNow         = beamNow[iSysNow].iPos();
+      iRec         = beamRec[iSysNow].iPos();
+      idDaughter   = beamNow[iSysNow].id();
+      xDaughter    = beamNow[iSysNow].x();
+      x1Now        = (sideA) ? xDaughter : beamRec[iSysNow].x();
+      x2Now        = (sideA) ? beamRec[iSysNow].x() : xDaughter;
+
+      // Note dipole mass correction when recoiler is a rescatter.
+      m2Rec        = (dipEndNow->normalRecoil) ? 0. : event[iRec].m2(); 
+      m2Dip        = x1Now * x2Now * sCM + m2Rec;
+
+      // Now do evolution in pT2, for QCD or QED 
+      if (pT2begDip > pT2endDip) { 
+        if (dipEndNow->colType != 0) pT2nextQCD( pT2begDip, pT2endDip);
+        else                         pT2nextQED( pT2begDip, pT2endDip);
+      }
+
+      // Update if found larger pT than current maximum.
+      if (dipEndNow->pT2 > pT2sel) {
+        pT2sel    = dipEndNow->pT2;
+        iDipSel   = iDipNow;
+        iSysSel   = iSysNow;
+        dipEndSel = dipEndNow;
+      }
+
+    // End loop over dipole ends.
+    }
+  } 
+
+  // Return nonvanishing value if found pT is bigger than already found.
+  return (dipEndSel == 0) ? 0. : sqrt(pT2sel); 
+}
+
+//--------------------------------------------------------------------------
+
+// Evolve a QCD dipole end. 
+
+void SpaceShower::pT2nextQCD( double pT2begDip, double pT2endDip) { 
+
+  // Some properties and kinematical starting values.
+  BeamParticle& beam = (sideA) ? *beamAPtr : *beamBPtr;
+  bool   isGluon     = (idDaughter == 21);
+  bool   isValence   = beam[iSysNow].isValence();
+  int    MEtype      = dipEndNow->MEtype;
+  double pT2         = pT2begDip;
+  double xMaxAbs     = beam.xMax(iSysNow);
+  double zMinAbs     = xDaughter / xMaxAbs;
+  if (xMaxAbs < 0.) {
+    infoPtr->errorMsg("Warning in SpaceShower::pT2nextQCD: "
+    "xMaxAbs negative"); 
+    return;
+  }
+  
+  // Starting values for handling of massive quarks (c/b), if any.
+  double idMassive   = 0;
+  if ( abs(idDaughter) == 4 ) idMassive = 4;
+  if ( abs(idDaughter) == 5 ) idMassive = 5;
+  bool   isMassive   = (idMassive > 0);
+  double m2Massive   = 0.;
+  double mRatio      = 0.;
+  double zMaxMassive = 1.;
+  double m2Threshold = pT2;
+
+  // Evolution below scale of massive quark or at large x is impossible.
+  if (isMassive) { 
+    m2Massive = (idMassive == 4) ? m2c : m2b;
+    if (pT2 < HEAVYPT2EVOL * m2Massive) return;
+    mRatio = sqrt( m2Massive / m2Dip );
+    zMaxMassive = (1. -  mRatio) / ( 1. +  mRatio * (1. -  mRatio) ); 
+    if (xDaughter > HEAVYXEVOL * zMaxMassive * xMaxAbs) return; 
+  
+    // Find threshold scale below which only g -> Q + Qbar will be allowed.
+    m2Threshold = (idMassive == 4) ? min( pT2, CTHRESHOLD * m2c)
+      : min( pT2, BTHRESHOLD * m2b); 
+  }
+  
+  // Variables used inside evolution loop. (Mainly dummy starting values.)
+  int    nFlavour       = 3; 
+  double b0             = 4.5;
+  double Lambda2        = Lambda3flav2;
+  double pT2minNow      = pT2endDip; 
+  int    idMother       = 0; 
+  int    idSister       = 0;
+  double z              = 0.;
+  double zMaxAbs        = 0.;
+  double zRootMax       = 0.;
+  double zRootMin       = 0.;
+  double g2gInt         = 0.; 
+  double q2gInt         = 0.; 
+  double q2qInt         = 0.;
+  double g2qInt         = 0.;
+  double g2Qenhance     = 0.;
+  double xPDFdaughter   = 0.;
+  double xPDFmother[21] = {0.};
+  double xPDFgMother    = 0.;
+  double xPDFmotherSum  = 0.;
+  double kernelPDF      = 0.;
+  double xMother        = 0.;
+  double wt             = 0.;
+  double Q2             = 0.;
+  double mSister        = 0.;
+  double m2Sister       = 0.;
+  double pT2corr        = 0.;
+  double pT2PDF         = pT2;
+  bool   needNewPDF     = true;
+
+  // Begin evolution loop towards smaller pT values.
+  int    loopTinyPDFdau = 0;
+  bool   hasTinyPDFdau  = false;
+  do { 
+    wt = 0.;
+
+    // Bad sign if repeated looping with small daughter PDF, so fail.
+    // (Example: if all PDF's = 0 below Q_0, except for c/b companion.)
+    if (hasTinyPDFdau) ++loopTinyPDFdau;  
+    if (loopTinyPDFdau > MAXLOOPTINYPDF) {
+      infoPtr->errorMsg("Warning in SpaceShower::pT2nextQCD: "
+      "small daughter PDF"); 
+      return;
+    }
+
+    // Initialize integrals of splitting kernels and evaluate parton 
+    // densities at the beginning. Reinitialize after long evolution 
+    // in pT2 or when crossing c and b flavour thresholds.
+    if (needNewPDF || pT2 < EVALPDFSTEP * pT2PDF) {
+      pT2PDF        = pT2;
+      hasTinyPDFdau = false;
+
+      // Determine overestimated z range; switch at c and b masses.
+      if (pT2 > m2b) {
+        nFlavour  = 5;
+        pT2minNow = max( m2b, pT2endDip);
+        b0        = 23./6.;
+        Lambda2   = Lambda5flav2;
+      } else if (pT2 > m2c) {
+        nFlavour  = 4;
+        pT2minNow = max( m2c, pT2endDip);
+        b0        = 25./6.;
+        Lambda2   = Lambda4flav2;
+      } else { 
+        nFlavour  = 3;
+        pT2minNow = pT2endDip;
+        b0        = 27./6.;
+        Lambda2   = Lambda3flav2;
+      }
+      // A change of renormalization scale expressed by a change of Lambda. 
+      Lambda2    /= renormMultFac;
+      zMaxAbs     = 1. - 0.5 * (pT2minNow / m2Dip) *
+        ( sqrt( 1. + 4. * m2Dip / pT2minNow ) - 1. );
+      if (isMassive) zMaxAbs = min( zMaxAbs, zMaxMassive); 
+
+      // Go to another z range with lower mass scale if current is closed.
+      if (zMinAbs > zMaxAbs) { 
+        if (nFlavour == 3 || (idMassive == 4 && nFlavour == 4) 
+          || idMassive == 5) return;
+        pT2 = (nFlavour == 4) ? m2c : m2b;
+        continue;
+      } 
+
+      // Parton density of daughter at current scale. 
+      xPDFdaughter = beam.xfISR(iSysNow, idDaughter, xDaughter, 
+        factorMultFac * pT2);
+      if (xPDFdaughter < TINYPDF) {
+        xPDFdaughter  = TINYPDF;
+        hasTinyPDFdau = true;
+      }
+
+      // Integrals of splitting kernels for gluons: g -> g, q -> g.
+      if (isGluon) {
+        g2gInt = 6. * log(zMaxAbs * (1.-zMinAbs) 
+          / (zMinAbs * (1.-zMaxAbs)));
+        if (doMEcorrections) g2gInt *= calcMEmax(MEtype, 21, 21);
+        q2gInt = (16./3.) * (1./sqrt(zMinAbs) - 1./sqrt(zMaxAbs));
+        if (doMEcorrections) q2gInt *= calcMEmax(MEtype, 1, 21);
+
+        // Parton density of potential quark mothers to a g.
+        xPDFmotherSum = 0.;
+        for (int i = -nQuarkIn; i <= nQuarkIn; ++i) {
+          if (i == 0) {
+            xPDFmother[10] = 0.;
+          } else {
+            xPDFmother[i+10] = beam.xfISR(iSysNow, i, xDaughter, 
+              factorMultFac * pT2); 
+            xPDFmotherSum += xPDFmother[i+10]; 
+          }
+        } 
+
+        // Total QCD evolution coefficient for a gluon.
+        kernelPDF = g2gInt + q2gInt * xPDFmotherSum / xPDFdaughter;
+
+      // For valence quark only need consider q -> q g branchings.
+      // Introduce an extra factor sqrt(z) to smooth bumps.
+      } else if (isValence) {
+        zRootMin = (1. + sqrt(zMinAbs)) / (1. - sqrt(zMinAbs));
+        zRootMax = (1. + sqrt(zMaxAbs)) / (1. - sqrt(zMaxAbs));
+        q2qInt = (8./3.) * log( zRootMax / zRootMin );
+        if (doMEcorrections) q2qInt *= calcMEmax(MEtype, 1, 1);
+        kernelPDF = q2qInt; 
+
+      // Integrals of splitting kernels for quarks: q -> q, g -> q.
+      } else {
+        q2qInt = (8./3.) * log( (1. - zMinAbs) / (1. - zMaxAbs) );
+        if (doMEcorrections) q2qInt *= calcMEmax(MEtype, 1, 1);
+        g2qInt = 0.5 * (zMaxAbs - zMinAbs);
+        if (doMEcorrections) g2qInt *= calcMEmax(MEtype, 21, 1);
+
+        // Increase estimated upper weight for g -> Q + Qbar.
+        if (isMassive) {
+          if (alphaSorder == 0) g2Qenhance = log(pT2/m2Massive) 
+            / log(m2Threshold/m2Massive);    
+          else {
+            double m2log = log( m2Massive / Lambda2);
+            g2Qenhance = log( log(pT2/Lambda2) / m2log ) 
+              / log( log(m2Threshold/Lambda2) / m2log );
+          }
+          g2qInt *= g2Qenhance;
+        }
+
+        // Parton density of a potential gluon mother to a q.
+        xPDFgMother = beam.xfISR(iSysNow, 21, xDaughter, factorMultFac * pT2);
+
+        // Total QCD evolution coefficient for a quark.
+        kernelPDF = q2qInt + g2qInt * xPDFgMother / xPDFdaughter;
+      }
+
+      // End evaluation of splitting kernels and parton densities.
+      needNewPDF = false;
+    }
+    if (kernelPDF < TINYKERNELPDF) return;
+
+    // Pick pT2 (in overestimated z range), for one of three different cases.
+    // Assume form alphas(pT0^2 + pT^2) * dpT^2/(pT0^2 + pT^2).
+    double Q2alphaS;
+
+    // Fixed alpha_strong.
+    if (alphaSorder == 0) {
+      pT2 = (pT2 + pT20) * pow( rndmPtr->flat(), 
+        1. / (alphaS2pi * kernelPDF)) - pT20;
+
+    // First-order alpha_strong.
+    } else if (alphaSorder == 1) {
+      pT2 = Lambda2 * pow( (pT2 + pT20) / Lambda2, 
+        pow(rndmPtr->flat(), b0 / kernelPDF) ) - pT20;
+
+    // For second order reject by second term in alpha_strong expression.
+    } else {
+      do {
+        pT2 = Lambda2 * pow( (pT2 + pT20) / Lambda2,
+          pow(rndmPtr->flat(), b0 / kernelPDF) ) - pT20;
+        Q2alphaS = renormMultFac * max( pT2 + pT20, 
+          pow2(LAMBDA3MARGIN) * Lambda3flav2);
+      } while (alphaS.alphaS2OrdCorr(Q2alphaS) < rndmPtr->flat()
+        && pT2 > pT2minNow);
+    }
+
+    // Check for pT2 values that prompt special action.
+
+    // If fallen into b threshold region, force g -> b + bbar.
+    if (idMassive == 5 && pT2 < m2Threshold) {
+      pT2nearQCDthreshold( beam, m2Massive, m2Threshold, xMaxAbs, 
+        zMinAbs, zMaxMassive );
+      return;
+
+    // If crossed b threshold, continue evolution from this threshold.
+    } else if (nFlavour == 5 && pT2 < m2b) {  
+      needNewPDF = true;
+      pT2 = m2b;
+      continue;
+
+    // If fallen into c threshold region, force g -> c + cbar.
+    } else if (idMassive == 4 && pT2 < m2Threshold) {
+      pT2nearQCDthreshold( beam, m2Massive, m2Threshold, xMaxAbs, 
+        zMinAbs, zMaxMassive );
+      return; 
+
+    // If crossed c threshold, continue evolution from this threshold.
+    } else if (nFlavour == 4 && pT2 < m2c) { 
+      needNewPDF = true;
+      pT2 = m2c;
+      continue;
+
+    // Abort evolution if below cutoff scale, or below another branching.
+    } else if (pT2 < pT2endDip) return; 
+
+    // Select z value of branching to g, and corrective weight.
+    if (isGluon) {
+      // g -> g (+ g). 
+      if (rndmPtr->flat() * kernelPDF < g2gInt) {
+        idMother = 21;
+        idSister = 21;
+        z = 1. / ( 1. + ((1. - zMinAbs) / zMinAbs) * pow( (zMinAbs * 
+          (1. - zMaxAbs)) / (zMaxAbs * (1. - zMinAbs)), rndmPtr->flat() ) );
+        wt = pow2( 1. - z * (1. - z));
+      } else {
+      // q -> g (+ q): also select flavour. 
+        double temp = xPDFmotherSum * rndmPtr->flat();
+        idMother = -nQuarkIn - 1;
+        do { temp -= xPDFmother[(++idMother) + 10]; } 
+        while (temp > 0. && idMother < nQuarkIn);  
+        idSister = idMother;
+        z = (zMinAbs * zMaxAbs) / pow2( sqrt(zMinAbs) + rndmPtr->flat() 
+          * ( sqrt(zMaxAbs)- sqrt(zMinAbs) ));
+        wt = 0.5 * (1. + pow2(1. - z)) * sqrt(z) 
+          * xPDFdaughter / xPDFmother[idMother + 10];
+      } 
+
+    // Select z value of branching to q, and corrective weight.
+    // Include massive kernel corrections for c and b quarks.
+    } else {
+      // q -> q (+ g). 
+      if (isValence || rndmPtr->flat() * kernelPDF < q2qInt) {
+        idMother = idDaughter;
+        idSister = 21;
+        // Valence more peaked at large z.
+        if (isValence) {
+          double zTmp = zRootMin * pow(zRootMax / zRootMin, rndmPtr->flat() );
+          z = pow2( (1. - zTmp) / (1. + zTmp) );
+        } else {
+          z = 1. - (1. - zMinAbs) * pow( (1. - zMaxAbs) / (1. - zMinAbs),
+            rndmPtr->flat() );
+        } 
+        if (!isMassive) { 
+          wt = 0.5 * (1. + pow2(z));
+        } else {
+        //?? Bug?? should be 2 more for massive part??
+        //  wt = 0.5 * (1. + pow2(z) - z * pow2(1.-z) * m2Massive / pT2);
+          wt = 0.5 * (1. + pow2(z)) - z * pow2(1.-z) * m2Massive / pT2;
+        }
+        if (isValence) wt *= sqrt(z);
+      // g -> q (+ qbar). 
+      } else {
+        idMother = 21;
+        idSister = - idDaughter; 
+        z = zMinAbs + rndmPtr->flat() * (zMaxAbs - zMinAbs);
+        if (!isMassive) { 
+          wt = (pow2(z) + pow2(1.-z)) * xPDFdaughter / xPDFgMother ;
+        } else {
+          wt = (pow2(z) + pow2(1.-z) + 2. * z * (1.-z) * m2Massive / pT2) 
+            * xPDFdaughter / (xPDFgMother * g2Qenhance) ;
+        }
+      }
+    }
+
+    // Derive Q2 and x of mother from pT2 and z. 
+    Q2      = pT2 / (1. - z);
+    xMother = xDaughter / z;
+    // Correction to x for massive recoiler from rescattering.
+    if (!dipEndNow->normalRecoil) {
+      if (sideA) xMother += (m2Rec / (x2Now * sCM)) * (1. / z - 1.);
+      else       xMother += (m2Rec / (x1Now * sCM)) * (1. / z - 1.);
+    }
+    if(xMother > xMaxAbs) { wt = 0.; continue; }
+
+    // Forbidden emission if outside allowed z range for given pT2.
+    mSister = particleDataPtr->m0(idSister);
+    m2Sister = pow2(mSister);
+    pT2corr = Q2 - z * (m2Dip + Q2) * (Q2 + m2Sister) / m2Dip;
+    if(pT2corr < TINYPT2) { wt = 0.; continue; }
+
+    // Optionally veto emissions not ordered in rapidity (= angle).
+    if ( doRapidityOrder && dipEndNow->nBranch > 0
+      && pT2 > pow2( (1. - z) / (z * (1. - dipEndNow->zOld)) ) 
+      * dipEndNow->pT2Old ) { wt = 0.; continue; }
+
+    // If creating heavy quark by Q -> g + Q then next need g -> Q + Qbar.
+    // So minimum total mass2 is 4 * m2Sister, but use more to be safe.
+    if ( isGluon && ( abs(idMother) == 4 || abs(idMother) == 5 )) {
+      double m2QQsister =  EXTRASPACEQ * 4. * m2Sister;
+      double pT2QQcorr = Q2 - z * (m2Dip + Q2) * (Q2 + m2QQsister) / m2Dip;
+      if(pT2QQcorr < TINYPT2) { wt = 0.; continue; }
+    }  
+
+    // Evaluation of ME correction.
+    if (doMEcorrections) wt *= calcMEcorr(MEtype, idMother, idDaughter, 
+      m2Dip, z, Q2) / calcMEmax(MEtype, idMother, idDaughter); 
+
+    // Optional dampening of large pT values in first radiation.
+    if (dopTdamp && iSysNow == 0 && MEtype == 0 && nRad == 0) 
+      wt *= pT2damp / (pT2 + pT2damp);
+
+    // Idea suggested by Gosta Gustafson: increased screening in events
+    // with large activity can be simulated by pT0_eff = sqrt(n) * pT0. 
+    if (enhanceScreening == 2) {
+      int nSysNow     = infoPtr->nMPI() + infoPtr->nISR() + 1;
+      double WTscreen = pow2( (pT2 + pT20) / (pT2 + nSysNow * pT20) );
+      wt             *= WTscreen;
+    } 
+
+    // Evaluation of new daughter and mother PDF's.
+    double xPDFdaughterNew = max ( TINYPDF, 
+      beam.xfISR(iSysNow, idDaughter, xDaughter, factorMultFac * pT2) );
+    double xPDFmotherNew = 
+      beam.xfISR(iSysNow, idMother, xMother, factorMultFac * pT2);
+    wt *= xPDFmotherNew / xPDFdaughterNew;
+
+    // Check that valence step does not cause problem.
+    if (wt > 1. && pT2 > PT2MINWARN) infoPtr->errorMsg("Warning in "
+      "SpaceShower::pT2nextQCD: weight above unity"); 
+
+  // Iterate until acceptable pT (or have fallen below pTmin).
+  } while (wt < rndmPtr->flat()) ;
+
+  // Save values for (so far) acceptable branching.
+  dipEndNow->store( idDaughter,idMother, idSister, x1Now, x2Now, m2Dip,
+    pT2, z, xMother, Q2, mSister, m2Sister, pT2corr);  
+
+}
+
+//--------------------------------------------------------------------------
+
+// Evolve a QCD dipole end near threshold, with g -> Q + Qbar enforced.
+// Note: No explicit Sudakov factor formalism here. Instead use that 
+// df_Q(x, pT2) = (alpha_s/2pi) * (dT2/pT2) * ((gluon) * (splitting)).
+// This implies that effects of Q -> Q + g are neglected in this range. 
+
+void SpaceShower::pT2nearQCDthreshold( BeamParticle& beam, 
+  double m2Massive, double m2Threshold, double xMaxAbs, 
+  double zMinAbs, double zMaxMassive) {
+
+  // Initial values, to be used in kinematics and weighting.
+  double Lambda2       = (abs(idDaughter) == 4) ? Lambda4flav2 : Lambda5flav2;
+  Lambda2             /= renormMultFac;
+  double logM2Lambda2  = log( m2Massive / Lambda2 );
+  double xPDFmotherOld = beam.xfISR(iSysNow, 21, xDaughter, 
+    factorMultFac * m2Threshold);
+
+  // Variables used inside evolution loop. (Mainly dummy start values.)
+  int    loop    = 0;
+  double wt      = 0.;
+  double pT2     = 0.; 
+  double z       = 0.; 
+  double Q2      = 0.; 
+  double pT2corr = 0.;
+  double xMother = 0.;
+
+  // Begin loop over tries to find acceptable g -> Q + Qbar branching. 
+  do { 
+    wt = 0.;
+
+    // Check that not caught in infinite loop with impossible kinematics.
+    if (++loop > 100) { 
+      infoPtr->errorMsg("Error in SpaceShower::pT2nearQCDthreshold: "
+        "stuck in loop"); 
+      return; 
+    }
+
+    // Pick dpT2/pT2 in range [m2Massive,thresholdRatio * m2Massive]. 
+    pT2 = m2Massive * pow( m2Threshold / m2Massive, rndmPtr->flat() ); 
+
+    // Pick z flat in allowed range.
+    z = zMinAbs + rndmPtr->flat() * (zMaxMassive - zMinAbs);
+
+    // Check that kinematically possible choice.
+    Q2 = pT2 / (1.-z) - m2Massive;
+    pT2corr = Q2 - z * (m2Dip + Q2) * (Q2 + m2Massive) / m2Dip;
+    if(pT2corr < TINYPT2) continue;
+    
+    // Correction factor for running alpha_s.  ??
+    wt = logM2Lambda2 / log( pT2 / Lambda2 ); 
+
+    // Correction factor for splitting kernel.
+    wt *= pow2(z) + pow2(1.-z) + 2. * z * (1.-z) * m2Massive / pT2;
+
+    // x, including correction for massive recoiler from rescattering.
+    xMother = xDaughter / z;
+    if (!dipEndNow->normalRecoil) {
+      if (sideA) xMother += (m2Rec / (x2Now * sCM)) * (1. / z - 1.);
+      else       xMother += (m2Rec / (x1Now * sCM)) * (1. / z - 1.);
+    }
+    if (xMother > xMaxAbs) { wt = 0.; continue; }
+
+    // Correction factor for gluon density.
+    double xPDFmotherNew = beam.xfISR(iSysNow, 21, xMother, 
+      factorMultFac * pT2);
+    wt *= xPDFmotherNew / xPDFmotherOld;
+
+  // Iterate until acceptable pT and z.
+  } while (wt < rndmPtr->flat()) ;
+
+  // Save values for (so far) acceptable branching.
+  double mSister = (abs(idDaughter) == 4) ? mc : mb;  
+  dipEndNow->store( idDaughter, 21, -idDaughter, x1Now, x2Now, m2Dip,
+    pT2, z, xMother, Q2, mSister, pow2(mSister), pT2corr);  
+
+}
+
+//--------------------------------------------------------------------------
+
+// Evolve a QED dipole end. 
+
+void SpaceShower::pT2nextQED( double pT2begDip, double pT2endDip) { 
+
+  // Type of dipole and starting values.
+  BeamParticle& beam  = (sideA) ? *beamAPtr : *beamBPtr;
+  bool   isLeptonBeam = beam.isLepton();
+  int    MEtype       = dipEndNow->MEtype;
+  bool   isPhoton     = (idDaughter == 22);
+  double pT2          = pT2begDip;
+  double m2Lepton     = (isLeptonBeam) ? pow2(beam.m()) : 0.; 
+  if (isLeptonBeam && pT2begDip < m2Lepton) return;
+
+  // Currently no f -> gamma branching implemented for lepton beams
+  if (isPhoton && isLeptonBeam) return;
+
+  // alpha_em at maximum scale provides upper estimate.
+  double alphaEMmax  = alphaEM.alphaEM(renormMultFac * pT2begDip);
+  double alphaEM2pi  = alphaEMmax / (2. * M_PI);
+
+  // Maximum x of mother implies minimum z = xDaughter / xMother.
+  double xMaxAbs  = (isLeptonBeam) ? LEPTONXMAX : beam.xMax(iSysNow);
+  double zMinAbs  = xDaughter / xMaxAbs;
+  if (xMaxAbs < 0.) {
+    infoPtr->errorMsg("Warning in SpaceShower::pT2nextQED: "
+    "xMaxAbs negative"); 
+    return;
+  }
+
+  // Maximum z from minimum pT and, for lepton, from minimum x_gamma.
+  double zMaxAbs = 1. - 0.5 * (pT2endDip / m2Dip) *
+    ( sqrt( 1. + 4. * m2Dip / pT2endDip ) - 1. );
+  if (isLeptonBeam) {
+    double zMaxLepton = xDaughter / (xDaughter + LEPTONXMIN);
+    if (zMaxLepton < zMaxAbs) zMaxAbs = zMaxLepton;
+  }
+  if (zMaxAbs < zMinAbs) return;
+
+  // Variables used inside evolution loop. (Mainly dummy start values.)
+  int    idMother = 0;
+  int    idSister =22;
+  double z        = 0.; 
+  double xMother  = 0.; 
+  double wt       = 0.; 
+  double Q2       = 0.;
+  double mSister  = 0.; 
+  double m2Sister = 0.;
+  double pT2corr  = 0.;
+  
+  // QED evolution of fermions
+  if (!isPhoton) {
+
+    // Integrals of splitting kernels for fermions: f -> f. Use 1 + z^2 < 2. 
+    // Ansatz f(z) = 2 / (1 - z), with + 2 / (z - xDaughter) for lepton.
+    double f2fInt  = 0.;
+    double f2fIntA = 2. * log( (1. - zMinAbs) / (1. - zMaxAbs) );
+    double f2fIntB = 0.;
+    if (isLeptonBeam) {
+      f2fIntB      = 2. * log( (zMaxAbs - xDaughter) / (zMinAbs - xDaughter) );
+      f2fInt       = f2fIntA + f2fIntB; 
+    } else f2fInt  = pow2(dipEndNow->chgType / 3.) * f2fIntA;
+    
+    // Upper estimate for evolution equation, including fudge factor. 
+    if (doMEcorrections) f2fInt *= calcMEmax(MEtype, 1, 1);
+    double kernelPDF = alphaEM2pi * f2fInt;
+    double fudge = (isLeptonBeam) ? LEPTONFUDGE * log(m2Dip/m2Lepton) : 1.;
+    kernelPDF *= fudge;
+    if (kernelPDF < TINYKERNELPDF) return;
+    
+    // Begin evolution loop towards smaller pT values.
+    do { 
+      
+      // Pick pT2 (in overestimated z range).
+      // For l -> l gamma include extrafactor 1 / ln(pT2 / m2l) in evolution.
+      double shift = pow(rndmPtr->flat(), 1. / kernelPDF);
+      if (isLeptonBeam) pT2 = m2Lepton * pow( pT2 / m2Lepton, shift);
+      else              pT2 = pT2 * shift; 
+      
+      // Abort evolution if below cutoff scale, or below another branching.
+      if (pT2 < pT2endDip) return; 
+      if (isLeptonBeam && pT2 < LEPTONPT2MIN * m2Lepton) return; 
+      
+      // Select z value of branching f -> f + gamma, and corrective weight.
+      idMother = idDaughter;
+      wt = 0.5 * (1. + pow2(z));
+      if (isLeptonBeam) {
+        if (f2fIntA > rndmPtr->flat() * (f2fIntA + f2fIntB)) { 
+          z = 1. - (1. - zMinAbs) 
+            * pow( (1. - zMaxAbs) / (1. - zMinAbs), rndmPtr->flat() );
+        } else {
+          z = xDaughter + (zMinAbs - xDaughter) 
+            * pow( (zMaxAbs - xDaughter) / (zMinAbs - xDaughter), 
+                  rndmPtr->flat() );  
+        }
+        wt *= (z - xDaughter) / (1. - xDaughter); 
+      } else {
+        z = 1. - (1. - zMinAbs) 
+          * pow( (1. - zMaxAbs) / (1. - zMinAbs), rndmPtr->flat() ); 
+      }
+      
+      // Derive Q2 and x of mother from pT2 and z. 
+      Q2      = pT2 / (1. - z);
+      xMother = xDaughter / z;
+      // Correction to x for massive recoiler from rescattering.
+      if (!dipEndNow->normalRecoil) {
+        if (sideA) xMother += (m2Rec / (x2Now * sCM)) * (1. / z - 1.);
+        else       xMother += (m2Rec / (x1Now * sCM)) * (1. / z - 1.);
+      }
+      if(xMother > xMaxAbs) { wt = 0.; continue; }
+      
+      // Forbidden emission if outside allowed z range for given pT2.
+      mSister  = 0.;
+      m2Sister = 0.;
+      pT2corr  = Q2 - z * (m2Dip + Q2) * (Q2 + m2Sister) / m2Dip;
+      if(pT2corr < TINYPT2) { wt = 0.; continue; }
+      
+      // Correct by ln(pT2 / m2l) and fudge factor.  
+      if (isLeptonBeam) wt *= log(pT2 / m2Lepton) / fudge;
+      
+      // Evaluation of ME correction.
+      if (doMEcorrections) wt *= calcMEcorr(MEtype, idMother, idDaughter, 
+         m2Dip, z, Q2) / calcMEmax(MEtype, idMother, idDaughter);
+
+      // Extra QED correction for f fbar -> W+- gamma. Debug??
+      if (doMEcorrections && MEtype == 1 && idDaughter == idMother
+        && ( (iSysNow == 0 && idResFirst  == 24)
+          || (iSysNow == 1 && idResSecond == 24) ) ) {
+        double tHe  = -Q2;
+        double uHe  = Q2 - m2Dip * (1. - z) / z;
+        double chg1 = abs(dipEndNow->chgType / 3.);
+        double chg2 = 1. - chg1;
+        wt *= pow2(chg1 * uHe - chg2 * tHe) 
+          / ( (tHe + uHe) * (pow2(chg1) * uHe + pow2(chg2) * tHe) );  
+      }
+
+      // Optional dampening of large pT values in first radiation.
+      if (dopTdamp && iSysNow == 0 && MEtype == 0 && nRad == 0) 
+        wt *= pT2damp / (pT2 + pT2damp);
+
+      // Correct to current value of alpha_EM.
+      double alphaEMnow = alphaEM.alphaEM(renormMultFac * pT2);
+      wt *= (alphaEMnow / alphaEMmax);
+      
+      // Evaluation of new daughter and mother PDF's.
+      double xPDFdaughterNew = max ( TINYPDF, 
+         beam.xfISR(iSysNow, idDaughter, xDaughter, factorMultFac * pT2) );
+      double xPDFmotherNew   = 
+         beam.xfISR(iSysNow, idMother, xMother, factorMultFac * pT2);
+      wt *= xPDFmotherNew / xPDFdaughterNew;
+
+    // Iterate until acceptable pT (or have fallen below pTmin).
+    } while (wt < rndmPtr->flat()) ;
+  }
+
+  // QED evolution of photons (so far only for hadron beams).
+  else {
+    
+    // Initial values
+    int    nFlavour       = 3;         
+    double kernelPDF      = 0.0;
+    double xPDFdaughter   = 0.;
+    double xPDFmother[21] = {0.};
+    double xPDFmotherSum  = 0.0;
+    double pT2PDF         = pT2;
+    double pT2minNow      = pT2endDip;
+    bool   needNewPDF     = true;
+
+    // Begin evolution loop towards smaller pT values.
+    int    loopTinyPDFdau = 0;
+    bool   hasTinyPDFdau  = false;
+    do { 
+      wt = 0.;
+      
+      // Bad sign if repeated looping with small daughter PDF, so fail.
+      if (hasTinyPDFdau) ++loopTinyPDFdau;  
+      if (loopTinyPDFdau > MAXLOOPTINYPDF) {
+        infoPtr->errorMsg("Warning in SpaceShower::pT2nextQED: "
+                          "small daughter PDF"); 
+        return;
+      }
+
+      // Initialize integrals of splitting kernels and evaluate parton 
+      // densities at the beginning. Reinitialize after long evolution 
+      // in pT2 or when crossing c and b flavour thresholds.
+      if (needNewPDF || pT2 < EVALPDFSTEP * pT2PDF) {
+
+        pT2PDF        = pT2;
+        hasTinyPDFdau = false;
+
+        // Determine overestimated z range; switch at c and b masses.
+        if (pT2 > m2b && nQuarkIn >= 5) {
+          nFlavour  = 5;
+          pT2minNow = max( m2b, pT2endDip);
+        } else if (pT2 > m2c && nQuarkIn >= 4) {
+          nFlavour  = 4;
+          pT2minNow = max( m2c, pT2endDip);
+        } else { 
+          nFlavour  = 3;
+          pT2minNow = pT2endDip;
+        }
+        
+        // Compute upper z limit 
+        zMaxAbs = 1. - 0.5 * (pT2minNow / m2Dip) *
+          ( sqrt( 1. + 4. * m2Dip / pT2minNow ) - 1. );
+
+        // Parton density of daughter at current scale. 
+        xPDFdaughter = beam.xfISR(iSysNow, idDaughter, xDaughter, 
+          factorMultFac * pT2);
+        if (xPDFdaughter < TINYPDF) {
+          xPDFdaughter  = TINYPDF;
+          hasTinyPDFdau = true;
+        }
+        
+        // Integral over f -> gamma f splitting kernel.
+        // Normalized so: 4/3 aS/2pi P(z) -> eq^2 * aEM/2pi P(z).
+        // (Charge-weighting happens below.)
+        double q2gInt = 4. * (1./sqrt(zMinAbs) - 1./sqrt(zMaxAbs));
+        
+        // Charge-weighted Parton density of potential quark mothers.
+        xPDFmotherSum = 0.;
+        for (int i = -nFlavour; i <= nFlavour; ++i) {
+          if (i == 0) {
+            xPDFmother[10] = 0.;
+          } else {
+            xPDFmother[i+10] = pow2((abs(i+1) % 2 + 1)/3.0) 
+              * beam.xfISR(iSysNow, i, xDaughter, factorMultFac * pT2); 
+            xPDFmotherSum += xPDFmother[i+10]; 
+          }
+        } 
+        
+        // Total QED evolution coefficient for a photon.
+        kernelPDF = q2gInt * xPDFmotherSum / xPDFdaughter;
+        
+        // End evaluation of splitting kernels and parton densities.
+        needNewPDF = false;
+      }
+      if (kernelPDF < TINYKERNELPDF) return;
+      
+      // Select pT2 for next trial branching 
+      pT2 *= pow( rndmPtr->flat(), 1. / (alphaEM2pi * kernelPDF));
+
+      // If crossed b threshold, continue evolution from this threshold.
+      if (nFlavour == 5 && pT2 < m2b) {  
+        needNewPDF = true;
+        pT2 = m2b;
+        continue;
+      }
+
+      // If crossed c threshold, continue evolution from this threshold.
+      else if (nFlavour == 4 && pT2 < m2c) { 
+        needNewPDF = true;
+        pT2 = m2c;
+        continue;
+      }
+
+      // Abort evolution if below cutoff scale, or below another branching.
+      else if (pT2 < pT2endDip) return; 
+
+      // Select flavour for trial branching
+      double temp = xPDFmotherSum * rndmPtr->flat();
+      idMother = -nQuarkIn - 1;
+      do { 
+        temp -= xPDFmother[(++idMother) + 10]; 
+      } while (temp > 0. && idMother < nQuarkIn);  
+
+      // Sister is same as mother, but can have m2 > 0
+      idSister = idMother;
+      mSister = particleDataPtr->m0(idSister);
+      m2Sister = pow2(mSister);
+      
+      // Select z for trial branching
+      z = (zMinAbs * zMaxAbs) / pow2( sqrt(zMinAbs) + rndmPtr->flat() 
+                                      * ( sqrt(zMaxAbs)- sqrt(zMinAbs) ));
+      
+      // Trial weight: splitting kernel
+      wt = 0.5 * (1. + pow2(1. - z)) * sqrt(z);
+      
+      // Trial weight: running alpha_EM
+      double alphaEMnow = alphaEM.alphaEM(renormMultFac * pT2);
+      wt *= (alphaEMnow / alphaEMmax);
+      
+      // Derive Q2 and x of mother from pT2 and z
+      Q2      = pT2 / (1. - z);
+      xMother = xDaughter / z;
+      // Correction to x for massive recoiler from rescattering.
+      if (!dipEndNow->normalRecoil) {
+        if (sideA) xMother += (m2Rec / (x2Now * sCM)) * (1. / z - 1.);
+        else       xMother += (m2Rec / (x1Now * sCM)) * (1. / z - 1.);
+      }
+      
+      // Compute pT2corr
+      pT2corr  = Q2 - z * (m2Dip + Q2) * (Q2 + m2Sister) / m2Dip;
+      if(pT2corr < TINYPT2) { wt = 0.; continue; }
+      
+      // If creating heavy quark by Q -> gamma + Q then next g -> Q + Qbar.
+      // So minimum total mass2 is 4 * m2Sister, but use more to be safe.
+      if ( abs(idMother) == 4 || abs(idMother) == 5 ) {
+        double m2QQsister =  EXTRASPACEQ * 4. * m2Sister;
+        double pT2QQcorr = Q2 - z * (m2Dip + Q2) * (Q2 + m2QQsister) / m2Dip;
+        if(pT2QQcorr < TINYPT2) { wt = 0.; continue; }
+      }  
+      
+      // Optional dampening of large pT values in first radiation.
+      if (dopTdamp && iSysNow == 0 && MEtype == 0 && nRad == 0) 
+        wt *= pT2damp / (pT2 + pT2damp);
+
+      // Evaluation of new daughter PDF 
+      double xPDFdaughterNew = beam.xfISR(iSysNow, idDaughter, xDaughter, 
+        factorMultFac * pT2);
+      if (xPDFdaughterNew < TINYPDF) {
+        xPDFdaughterNew = TINYPDF;
+      }
+      
+      // Evaluation of new charge-weighted mother PDF 
+      double xPDFmotherNew = pow2( (abs(idMother+1) % 2 + 1)/3.0 ) 
+        * beam.xfISR(iSysNow, idMother, xMother, factorMultFac * pT2);
+      
+      // Trial weight: divide out old pdf ratio
+      wt *= xPDFdaughter / xPDFmother[idMother + 10];
+      
+      // Trial weight: new pdf ratio
+      wt *= xPDFmotherNew / xPDFdaughterNew;
+
+    // Iterate until acceptable pT (or have fallen below pTmin).
+    } while (wt < rndmPtr->flat()) ;    
+  }
+
+  // Save values for (so far) acceptable branching.
+  dipEndNow->store( idDaughter, idMother, idSister, x1Now, x2Now, m2Dip,
+    pT2, z, xMother, Q2, mSister, m2Sister, pT2corr);  
+
+}
+
+//--------------------------------------------------------------------------
+
+// Kinematics of branching.
+// Construct mother -> daughter + sister, with recoiler on other side. 
+
+bool SpaceShower::branch( Event& event) {
+  
+  // Side on which branching occured.
+  int side          = abs(dipEndSel->side);
+  double sideSign   = (side == 1) ? 1. : -1.;
+
+  // Read in flavour and colour variables.
+  int iDaughter     = partonSystemsPtr->getInA(iSysSel);
+  int iRecoiler     = partonSystemsPtr->getInB(iSysSel);
+  if (side == 2) swap(iDaughter, iRecoiler);
+  int idDaughterNow = dipEndSel->idDaughter;
+  int idMother      = dipEndSel->idMother;
+  int idSister      = dipEndSel->idSister;
+  int colDaughter   = event[iDaughter].col();
+  int acolDaughter  = event[iDaughter].acol();
+
+  // Recoil parton may be rescatterer, requiring special processing. 
+  bool normalRecoil = dipEndSel->normalRecoil; 
+  int iRecoilMother = event[iRecoiler].mother1();
+
+  // Read in kinematical variables.
+  double x1         = dipEndSel->x1;
+  double x2         = dipEndSel->x2;
+  double xMo        = dipEndSel->xMo;
+  double m2         = dipEndSel->m2Dip;
+  double m          = sqrt(m2);
+  double pT2        = dipEndSel->pT2;
+  double z          = dipEndSel->z;
+  double Q2         = dipEndSel->Q2; 
+  double mSister    = dipEndSel->mSister;
+  double m2Sister   = dipEndSel->m2Sister;
+  double pT2corr    = dipEndSel->pT2corr;
+  double x1New      = (side == 1) ? xMo : x1;
+  double x2New      = (side == 2) ? xMo : x2;
+
+  // Rescatter: kinematics may fail; use the rescatterFail flag to tell
+  //            parton level to try again.
+  rescatterFail     = false;
+
+  // Construct kinematics of mother, sister and recoiler in old rest frame.
+  // Normally both mother and recoiler are taken massless.
+  double eNewRec, pzNewRec, pTbranch, pzMother;
+  if (normalRecoil) {
+    eNewRec         = 0.5 * (m2 + Q2) / m;
+    pzNewRec        = -sideSign * eNewRec;
+    pTbranch        = sqrt(pT2corr) * m2 / ( z * (m2 + Q2) );
+    pzMother        = sideSign * 0.5 * m * ( (m2 - Q2) / ( z * (m2 + Q2) )
+                    + (Q2 + m2Sister) / m2 ); 
+  // More complicated kinematics when recoiler not massless. May fail.
+  } else {
+    m2Rec           = event[iRecoiler].m2();
+    double s1Tmp    = m2 + Q2 - m2Rec;
+    double s3Tmp    = m2 / z - m2Rec; 
+    double r1Tmp    = sqrt(s1Tmp * s1Tmp + 4. * Q2 * m2Rec); 
+    eNewRec         = 0.5 * (m2 + m2Rec + Q2) / m;
+    pzNewRec        = -sideSign * 0.5 * r1Tmp / m;
+    double pT2br    = Q2 * s3Tmp * (m2 / z - m2 - Q2) 
+      - m2Sister * s1Tmp * s3Tmp - m2Rec * pow2(Q2 + m2Sister);
+    if (pT2br <= 0.) return false; 
+    pTbranch        = sqrt(pT2br) / r1Tmp;
+    pzMother        = sideSign * (m * s3Tmp 
+      - eNewRec * (m2 / z - Q2 - m2Rec - m2Sister)) / r1Tmp;
+  }
+  // Common final kinematics steps for both normal and rescattering.
+  double eMother    = sqrt( pow2(pTbranch) + pow2(pzMother) );
+  double pzSister   = pzMother + pzNewRec;
+  double eSister    = sqrt( pow2(pTbranch) + pow2(pzSister) + m2Sister );
+  Vec4 pMother( pTbranch, 0., pzMother, eMother );
+  Vec4 pSister( pTbranch, 0., pzSister, eSister ); 
+  Vec4 pNewRec(       0., 0., pzNewRec, eNewRec );
+
+  // Current event and subsystem size.
+  int eventSizeOld  = event.size();
+  int systemSizeOld = partonSystemsPtr->sizeAll(iSysSel);
+
+  // Save properties to be restored in case of user-hook veto of emission.
+  int beamOff1 = 1 + beamOffset;
+  int beamOff2 = 2 + beamOffset;
+  int ev1Dau1V = event[beamOff1].daughter1();
+  int ev2Dau1V = event[beamOff2].daughter1();
+  vector<int> statusV, mother1V, mother2V, daughter1V, daughter2V;
+  if (canVetoEmission) {
+    for ( int iCopy = 0; iCopy < systemSizeOld; ++iCopy) {
+      int iOldCopy    = partonSystemsPtr->getAll(iSysSel, iCopy);
+      statusV.push_back( event[iOldCopy].status());
+      mother1V.push_back( event[iOldCopy].mother1());
+      mother2V.push_back( event[iOldCopy].mother2());
+      daughter1V.push_back( event[iOldCopy].daughter1());
+      daughter2V.push_back( event[iOldCopy].daughter2());
+    }  
+  }
+
+  // Take copy of existing system, to be given modified kinematics.
+  // Incoming negative status. Rescattered also negative, but after copy.
+  for ( int iCopy = 0; iCopy < systemSizeOld; ++iCopy) {
+    int iOldCopy    = partonSystemsPtr->getAll(iSysSel, iCopy);
+    int statusOld   = event[iOldCopy].status();
+    int statusNew   = (iOldCopy == iDaughter 
+      || iOldCopy == iRecoiler) ? statusOld : 44;
+    int iNewCopy    = event.copy(iOldCopy, statusNew);
+    if (statusOld < 0) event[iNewCopy].statusNeg();
+  }
+  // Define colour flow in branching. 
+  // Default corresponds to f -> f + gamma.
+  int colMother     = colDaughter;
+  int acolMother    = acolDaughter;
+  int colSister     = 0;
+  int acolSister    = 0; 
+  if (idSister == 22) ; 
+  // q -> q + g and 50% of g -> g + g; need new colour.
+  else if (idSister == 21 && ( (idMother > 0 && idMother < 9)
+  || (idMother == 21 && rndmPtr->flat() < 0.5) ) ) {  
+    colMother       = event.nextColTag();
+    colSister       = colMother;
+    acolSister      = colDaughter;
+  // qbar -> qbar + g and other 50% of g -> g + g; need new colour.
+  } else if (idSister == 21) {  
+    acolMother      = event.nextColTag();
+    acolSister      = acolMother;
+    colSister       = acolDaughter;
+  // q -> g + q.
+  } else if (idDaughterNow == 21 && idMother > 0) { 
+    colMother       = colDaughter;
+    acolMother      = 0;
+    colSister       = acolDaughter;
+  // qbar -> g + qbar
+  } else if (idDaughterNow == 21) {
+    acolMother      = acolDaughter;
+    colMother       = 0;
+    acolSister      = colDaughter;
+  // g -> q + qbar.
+  } else if (idDaughterNow > 0 && idDaughterNow < 9) {
+    acolMother      = event.nextColTag();
+    acolSister      = acolMother;
+  // g -> qbar + q.
+  } else if (idDaughterNow < 0 && idDaughterNow > -9) {
+    colMother       = event.nextColTag();
+    colSister       = colMother;
+  // q -> gamma + q.
+  } else if (idDaughterNow == 22 && idMother > 0) {
+    colMother       = event.nextColTag();
+    colSister       = colMother; 
+   // qbar -> gamma + qbar.
+  } else if (idDaughterNow == 22) {
+    acolMother      = event.nextColTag();
+    acolSister      = acolMother;
+  }   
+
+  // Indices of partons involved. Add new sister.
+  int iMother       = eventSizeOld + side - 1;
+  int iNewRecoiler  = eventSizeOld + 2 - side;
+  int iSister       = event.append( idSister, 43, iMother, 0, 0, 0,
+     colSister, acolSister, pSister, mSister, sqrt(pT2) );
+
+  // References to the partons involved.
+  Particle& daughter    = event[iDaughter];
+  Particle& mother      = event[iMother];
+  Particle& newRecoiler = event[iNewRecoiler];
+  Particle& sister      = event.back();
+
+  // Replace old by new mother; update new recoiler.
+  mother.id( idMother );
+  mother.status( -41);
+  mother.cols( colMother, acolMother);
+  mother.p( pMother);
+  newRecoiler.status( (normalRecoil) ? -42 : -46 );
+  newRecoiler.p( pNewRec);
+  if (!normalRecoil) newRecoiler.m( event[iRecoiler].m() ); 
+
+  // Update mother and daughter pointers; also for beams.
+  daughter.mothers( iMother, 0);
+  mother.daughters( iSister, iDaughter); 
+  if (iSysSel == 0) {
+    event[beamOff1].daughter1( (side == 1) ? iMother : iNewRecoiler ); 
+    event[beamOff2].daughter1( (side == 2) ? iMother : iNewRecoiler ); 
+  }
+
+  // Find boost to old rest frame.
+  RotBstMatrix Mtot;
+  if (normalRecoil) Mtot.bst(0., 0., (x2 - x1) / (x1 + x2) );
+  else if (side == 1)
+       Mtot.toCMframe( event[iDaughter].p(), event[iRecoiler].p() );
+  else Mtot.toCMframe( event[iRecoiler].p(), event[iDaughter].p() );
+
+  // Initially select phi angle of branching at random.
+  double phi = 2. * M_PI * rndmPtr->flat();
+
+  // Evaluate coefficient of azimuthal asymmetry from gluon polarization.
+  findAsymPol( event, dipEndSel);
+  int    iFinPol = dipEndSel->iFinPol;
+  double cPol    = dipEndSel->asymPol;
+  double phiPol  = (iFinPol == 0) ? 0. : event[iFinPol].phi(); 
+
+  // If interference: try to match sister (anti)colour to final state.
+  int    iFinInt = 0;
+  double cInt    = 0.; 
+  double phiInt  = 0.;
+  if (doPhiIntAsym) {
+    for (int i = 0; i < partonSystemsPtr->sizeOut(iSysSel); ++ i) {
+      int iOut = partonSystemsPtr->getOut(iSysSel, i);
+      if ( (acolSister != 0 && event[iOut].col() == acolSister) 
+        || (colSister != 0 && event[iOut].acol() == colSister) ) 
+        iFinInt = iOut;  
+    }
+    if (iFinInt != 0) {
+      // Boost final-state parton to current frame of new kinematics.
+      Vec4 pFinTmp = event[iFinInt].p();
+      pFinTmp.rotbst(Mtot);
+      double theFin = pFinTmp.theta();
+      if (side == 2) theFin = M_PI - theFin;
+      double theSis = pSister.theta();
+      if (side == 2) theSis = M_PI - theSis;
+      cInt = strengthIntAsym * 2. * theSis * theFin 
+           / (pow2(theSis) + pow2(theFin));
+      phiInt = event[iFinInt].phi();
+    }
+  }
+
+  // Bias phi distribution for polarization and interference.
+  if (iFinPol != 0 || iFinInt != 0) {
+    double cPhiPol, cPhiInt, weight;
+    do {
+      phi     = 2. * M_PI * rndmPtr->flat();
+      weight  = 1.;
+      if (iFinPol !=0 ) {
+        cPhiPol = cos(phi - phiPol);
+        weight *= ( 1. + cPol * (2. * pow2(cPhiPol) - 1.) ) 
+          / ( 1. + abs(cPol) );
+      }
+      if (iFinInt !=0 ) {
+        cPhiInt = cos(phi - phiInt); 
+        weight *= (1. - cInt) * (1. - cInt * cPhiInt)
+          / (1. + pow2(cInt) - 2. * cInt * cPhiInt);
+      }
+    } while (weight < rndmPtr->flat());  
+  }
+
+  // Include rotation -phi on boost to old rest frame.
+  Mtot.rot(0., -phi); 
+
+  // Find boost from old rest frame to event cm frame.
+  RotBstMatrix MfromRest;
+  // The boost to the new rest frame.
+  Vec4 sumNew       = pMother + pNewRec;
+  double betaX      = sumNew.px() / sumNew.e();
+  double betaZ      = sumNew.pz() / sumNew.e();
+  MfromRest.bst( -betaX, 0., -betaZ);
+  // Alignment of  radiator + recoiler to +- z axis, and rotation +phi.
+  // Note: with spacelike (E < 0) recoiler p'_x_mother < 0 can happen!
+  pMother.rotbst(MfromRest);  
+  double theta = pMother.theta();
+  if (pMother.px() < 0.) theta = -theta;
+  if (side == 2) theta += M_PI;
+  MfromRest.rot(-theta, phi); 
+  // Boost to radiator + recoiler in event cm frame.
+  if (normalRecoil) {
+    MfromRest.bst( 0., 0., (x1New - x2New) / (x1New + x2New) );
+  } else if (side == 1) {
+    Vec4 pMotherWanted( 0., 0.,  0.5 * eCM * x1New, 0.5 * eCM * x1New);
+    MfromRest.fromCMframe( pMotherWanted, event[iRecoiler].p() ); 
+
+  } else {
+    Vec4 pMotherWanted( 0., 0., -0.5 * eCM * x2New, 0.5 * eCM * x2New); 
+    MfromRest.fromCMframe( event[iRecoiler].p(), pMotherWanted );
+  }
+  Mtot.rotbst(MfromRest);
+
+  // Perform cumulative rotation/boost operation.
+  // Mother, recoiler and sister from old rest frame to event cm frame.
+  mother.rotbst(MfromRest);
+  newRecoiler.rotbst(MfromRest);
+  sister.rotbst(MfromRest);
+  // The rest from (and to) event cm frame.
+  for ( int i = eventSizeOld + 2; i < eventSizeOld + systemSizeOld; ++i) 
+    event[i].rotbst(Mtot);  
+
+  // Allow veto of branching. If so restore event record to before emission.
+  if ( canVetoEmission 
+    && userHooksPtr->doVetoISREmission(eventSizeOld, event, iSysSel) ) {
+    event.popBack( event.size() - eventSizeOld); 
+    event[beamOff1].daughter1( ev1Dau1V);
+    event[beamOff2].daughter1( ev2Dau1V);
+    for ( int iCopy = 0; iCopy < systemSizeOld; ++iCopy) {
+      int iOldCopy = partonSystemsPtr->getAll(iSysSel, iCopy);
+      event[iOldCopy].status( statusV[iCopy]);
+      event[iOldCopy].mothers( mother1V[iCopy], mother2V[iCopy]);
+      event[iOldCopy].daughters( daughter1V[iCopy], daughter2V[iCopy]);
+    }  
+    return false;
+  }
+
+  // Update list of partons in system; adding newly produced one.
+  partonSystemsPtr->setInA(iSysSel, eventSizeOld);
+  partonSystemsPtr->setInB(iSysSel, eventSizeOld + 1);
+  for (int iCopy = 2; iCopy < systemSizeOld; ++iCopy) 
+    partonSystemsPtr->setOut(iSysSel, iCopy - 2, eventSizeOld + iCopy);
+  partonSystemsPtr->addOut(iSysSel, eventSizeOld + systemSizeOld);
+  partonSystemsPtr->setSHat(iSysSel, m2 / z);
+
+  // Update info on radiating dipole ends (QCD or QED).
+  for (int iDip = 0; iDip < int(dipEnd.size()); ++iDip)
+  if ( dipEnd[iDip].system == iSysSel) {
+    if (abs(dipEnd[iDip].side) == side) {    
+      dipEnd[iDip].iRadiator = iMother;
+      dipEnd[iDip].iRecoiler = iNewRecoiler;
+      if (dipEnd[iDip].side > 0) 
+        dipEnd[iDip].colType = mother.colType();
+      else {
+        dipEnd[iDip].chgType = 0;
+        if ( (mother.isQuark() && doQEDshowerByQ)
+          || (mother.isLepton() && doQEDshowerByL) ) 
+          dipEnd[iDip].chgType = mother.chargeType();
+      }
+      // Kill ME corrections after first emission. 
+      dipEnd[iDip].MEtype = 0;
+
+    // Update info on recoiling dipole ends (QCD or QED).
+    } else {
+      dipEnd[iDip].iRadiator = iNewRecoiler;
+      dipEnd[iDip].iRecoiler = iMother;
+      // Optionally also kill recoiler ME corrections after first emission.
+      if (!doMEafterFirst) dipEnd[iDip].MEtype = 0;
+    }  
+  }
+
+  // Update info on beam remnants.
+  BeamParticle& beamNow = (side == 1) ? *beamAPtr : *beamBPtr;
+  double xNew = (side == 1) ? x1New : x2New;
+  beamNow[iSysSel].update( iMother, idMother, xNew);
+  // Redo choice of companion kind whenever new flavour.
+  if (idMother != idDaughterNow) {
+    beamNow.xfISR( iSysSel, idMother, xNew, factorMultFac * pT2);
+    beamNow.pickValSeaComp();
+  }
+  BeamParticle& beamRec = (side == 1) ? *beamBPtr : *beamAPtr;
+  beamRec[iSysSel].iPos( iNewRecoiler);
+
+  // Store branching values of current dipole. (For rapidity ordering.)
+  ++dipEndSel->nBranch;
+  dipEndSel->pT2Old = pT2;
+  dipEndSel->zOld   = z;
+
+  // Update history if recoiler rescatters. 
+  if (!normalRecoil) 
+    event[iRecoilMother].daughters( iNewRecoiler, iNewRecoiler);
+
+  // Start list of rescatterers that force changed kinematics.
+  vector<int> iRescatterer;
+  for ( int i = 0; i < systemSizeOld - 2; ++i) {
+    int iOutNew = partonSystemsPtr->getOut( iSysSel, i);
+    if (!event[iOutNew].isFinal()) iRescatterer.push_back(iOutNew);
+  }
+
+  // Start iterate over list of such rescatterers.
+  int iRescNow = -1;
+  while (++iRescNow < int(iRescatterer.size())) {
+
+    // Identify partons that induce or are affected by rescatter shift.
+    // In following Old is before change of kinematics, New after,
+    // Out scatterer in outstate and In in instate of another system.
+    // Daughter sequence is (iOutOld ->) iOutNew -> iInNew -> iInOld. 
+    int iOutNew    = iRescatterer[iRescNow];    
+    int iInOld     = event[iOutNew].daughter1();
+    int iSysResc   = partonSystemsPtr->getSystemOf(iInOld, true);
+
+    // Copy incoming partons of rescattered system and hook them up.
+    int iOldA      = partonSystemsPtr->getInA(iSysResc);
+    int iOldB      = partonSystemsPtr->getInB(iSysResc);
+    bool rescSideA = event[iOldA].isRescatteredIncoming();
+    int statusNewA = (rescSideA) ? -45 : -42;
+    int statusNewB = (rescSideA) ? -42 : -45;
+    int iNewA      = event.copy(iOldA, statusNewA);
+    int iNewB      = event.copy(iOldB, statusNewB);
+
+    // Copy outgoing partons of rescattered system and hook them up.
+    int eventSize  = event.size();
+    int sizeOutAB  = partonSystemsPtr->sizeOut(iSysResc);
+    int iOldAB, statusOldAB, iNewAB;       
+    for (int iOutAB = 0; iOutAB < sizeOutAB; ++iOutAB) {
+      iOldAB       = partonSystemsPtr->getOut(iSysResc, iOutAB);
+      statusOldAB  = event[iOldAB].status();
+      iNewAB       = event.copy(iOldAB, 44);
+      // Status could be negative for parton that rescatters in its turn.
+      if (statusOldAB < 0) {
+        event[iNewAB].statusNeg();     
+        iRescatterer.push_back(iNewAB);
+      }
+    } 
+
+    // Hook up new outgoing with new incoming parton.
+    int iInNew     = (rescSideA) ? iNewA : iNewB;
+    event[iOutNew].daughters( iInNew, iInNew);
+    event[iInNew].mothers( iOutNew, iOutNew);
+
+    // Rescale recoiling incoming parton for correct invariant mass.
+    event[iInNew].p( event[iOutNew].p() );
+    double momFac  = (rescSideA) 
+                   ? event[iInOld].pPos() / event[iInNew].pPos()
+                   : event[iInOld].pNeg() / event[iInNew].pNeg();
+    int iInRec     = (rescSideA) ? iNewB : iNewA;
+
+    // Rescatter: A previous boost may cause the light cone momentum of a
+    //            rescattered parton to change sign. If this happens, tell
+    //            parton level to try again.
+    if (momFac < 0.0) {
+      infoPtr->errorMsg("Warning in SpaceShower::branch: "
+      "change in lightcone momentum sign; retrying parton level");
+      rescatterFail = true;
+      return false;
+    }
+
+    event[iInRec].rescale4( momFac);
+
+    // Boost outgoing partons to new frame of incoming.
+    RotBstMatrix MmodResc;
+    MmodResc.toCMframe(  event[iOldA].p(), event[iOldB].p()); 
+    MmodResc.fromCMframe(event[iNewA].p(), event[iNewB].p()); 
+    for (int iOutAB = 0; iOutAB < sizeOutAB; ++iOutAB)
+      event[eventSize + iOutAB].rotbst(MmodResc);
+
+    // Update list of partons in system.
+    partonSystemsPtr->setInA(iSysResc, iNewA);
+    partonSystemsPtr->setInB(iSysResc, iNewB);
+    for (int iCopy = 0; iCopy < sizeOutAB; ++iCopy) 
+      partonSystemsPtr->setOut(iSysResc, iCopy, eventSize + iCopy);
+
+    // Update info on radiating dipole ends (QCD or QED).
+    for (int iDip = 0; iDip < int(dipEnd.size()); ++iDip)
+    if ( dipEnd[iDip].system == iSysResc) {
+      bool sideAnow = (abs(dipEnd[iDip].side) == 1); 
+      dipEnd[iDip].iRadiator = (sideAnow) ? iNewA : iNewB;
+      dipEnd[iDip].iRecoiler = (sideAnow) ? iNewB : iNewA;
+    }
+
+    // Update info on beam remnants.
+    BeamParticle& beamResc = (rescSideA) ? *beamAPtr : *beamBPtr;
+    beamResc[iSysResc].iPos( iInNew); 
+    beamResc[iSysResc].p( event[iInNew].p() );
+    beamResc[iSysResc].scaleX( 1. / momFac  );
+    BeamParticle& beamReco = (rescSideA) ? *beamBPtr : *beamAPtr;
+    beamReco[iSysResc].iPos( iInRec); 
+    beamReco[iSysResc].scaleX( momFac);
+
+  // End iterate over list of rescatterers.
+  }
+
+  // Check that beam momentum not used up by rescattered-system boosts.
+    if (beamAPtr->xMax(-1) < 0.0 || beamBPtr->xMax(-1) < 0.0) {
+      infoPtr->errorMsg("Warning in SpaceShower::branch: "
+      "used up beam momentum; retrying parton level");
+      rescatterFail = true;
+      return false;
+    }
+
+  // Done without any errors.
+  return true;
+
+}
+
+//--------------------------------------------------------------------------
+
+// Find class of ME correction.
+
+int SpaceShower::findMEtype( int iSys, Event& event) {
+
+  // Default values and no action.
+  int MEtype = 0; 
+  if (!doMEcorrections) ;
+
+  // Identify systems producing a single resonance.
+  else if (partonSystemsPtr->sizeOut( iSys) == 1) {
+    int idIn1 = event[partonSystemsPtr->getInA(iSys)].id();
+    int idIn2 = event[partonSystemsPtr->getInA(iSys)].id();
+    int idRes = event[partonSystemsPtr->getOut(iSys, 0)].id();
+    if (iSys == 0) idResFirst  = abs(idRes);
+    if (iSys == 1) idResSecond = abs(idRes);
+
+    // f + fbar -> vector boson. 
+    if ( (idRes == 23 || abs(idRes) == 24 || idRes == 32 
+      || idRes == 33 || abs(idRes) == 34 || abs(idRes) == 41)
+      && abs(idIn1) < 20 && abs(idIn2) < 20 ) MEtype = 1;
+
+    // g + g, gamma + gamma  -> Higgs boson.
+    if ( (idRes == 25 || idRes == 35 || idRes == 36) 
+       && ( ( idIn1 == 21 && idIn2 == 21 ) 
+       || ( idIn1 == 22 && idIn2 == 22 ) ) ) MEtype = 2; 
+
+    // f + fbar  -> Higgs boson.
+    if ( (idRes == 25 || idRes == 35 || idRes == 36) 
+       && abs(idIn1) < 20 && abs(idIn2) < 20 ) MEtype = 3; 
+  }
+
+  // Done.
+  return MEtype;
+
+}
+
+//--------------------------------------------------------------------------
+
+// Provide maximum of expected ME weight; for preweighting of evolution.
+
+double SpaceShower::calcMEmax( int MEtype, int idMother, int idDaughterIn) {
+
+  // Currently only one non-unity case: g(gamma) f -> V f'.
+  if (MEtype == 1 && idMother > 20 && idDaughterIn < 20) return 3.;
+  return 1.;
+
+}  
+
+//--------------------------------------------------------------------------
+
+// Provide actual ME weight for current branching.
+// Note: currently ME corrections are only allowed for first branching 
+// on each side, so idDaughter is essentially known and checks overkill.
+
+double SpaceShower::calcMEcorr(int MEtype, int idMother, int idDaughterIn,
+  double M2, double z, double Q2) {
+
+  // Convert to Mandelstam variables. Sometimes may need to swap later.
+  double sH = M2 / z;
+  double tH = -Q2;
+  double uH = Q2 - M2 * (1. - z) / z;
+  int idMabs = abs(idMother);
+  int idDabs = abs(idDaughterIn);
+
+  // Corrections for f + fbar -> s-channel vector boson.
+  if (MEtype == 1) {
+    if (idMabs < 20 && idDabs < 20) {
+      return (tH*tH + uH*uH + 2. * M2 * sH) / (sH*sH + M2*M2); 
+    } else if (idDabs < 20) {
+      // g(gamma) f -> V f': -Q2 = (p_g - p_f')^2 in PS while 
+      // tHat = (p_f - p_f')^2 in ME so need to swap tHat <-> uHat.  
+      swap( tH, uH); 
+      return (sH*sH + uH*uH + 2. * M2 * tH) / (pow2(sH - M2) + M2*M2); 
+    }
+
+  // Corrections for g + g -> Higgs boson.
+  } else if (MEtype == 2) {
+    if (idMabs < 20 && idDabs > 20) {
+      return (sH*sH + uH*uH) / (sH*sH + pow2(sH - M2)); 
+    } else if (idDabs > 20) {
+      return 0.5 * (pow4(sH) + pow4(tH) + pow4(uH) + pow4(M2)) 
+        / pow2(sH*sH - M2 * (sH - M2)); 
+    }    
+
+  // Corrections for f + fbar -> Higgs boson (f = b mainly).
+  } else if (MEtype == 3) {
+    if (idMabs < 20 && idDabs < 20) {
+      // The PS and ME answers agree for f fbar -> H g/gamma. 
+      return 1.; 
+    } else if (idDabs < 20) {
+      // Need to swap tHat <-> uHat, cf. vector-boson production above. 
+      swap( tH, uH); 
+      return (sH*sH + uH*uH + 2. * (M2 - uH) * (M2 - sH)) 
+             / (pow2(sH - M2) + M2*M2); 
+    }    
+  }
+
+  return 1.;
+
+}
+
+//--------------------------------------------------------------------------
+
+// Find coefficient of azimuthal asymmetry from gluon polarization.
+
+void SpaceShower::findAsymPol( Event& event, SpaceDipoleEnd* dip) {
+
+  // Default is no asymmetry. Only gluons are studied.
+  dip->iFinPol   = 0;
+  dip->asymPol   = 0.;
+  int iRad       = dip->iRadiator;
+  if (!doPhiPolAsym || dip->idDaughter != 21) return;
+
+  // At least two particles in final state, whereof at least one coloured.
+  int systemSizeOut = partonSystemsPtr->sizeOut( iSysSel);
+  if (systemSizeOut < 2) return;
+  bool foundColOut  = false;
+  for (int ii = 0; ii < systemSizeOut; ++ii) {
+    int i = partonSystemsPtr->getOut( iSysSel, ii); 
+    if (event[i].col() != 0 || event[i].acol() != 0) foundColOut = true;
+  }
+  if (!foundColOut) return;
+
+  // Check if granddaughter in final state of hard scattering.
+  // (May need to trace across carbon copies to find granddaughters.)
+  // If so, only accept 2 -> 2 scatterings with gg or qq in final state.
+  int iGrandD1 = event[iRad].daughter1();
+  int iGrandD2 = event[iRad].daughter2();
+  bool traceCopy = false;
+  do {
+    traceCopy = false;
+    if (iGrandD1 > 0 && iGrandD2 == iGrandD1) {
+      iGrandD1 = event[iGrandD2].daughter1();
+      iGrandD2 = event[iGrandD2].daughter2();
+      traceCopy = true;
+    }
+  } while (traceCopy);
+  int statusGrandD1 = event[ iGrandD1 ].statusAbs();
+  bool isHardProc  = (statusGrandD1 == 23 || statusGrandD1 == 33); 
+  if (isHardProc) {
+    if (iGrandD2 != iGrandD1 + 1) return; 
+    if (event[iGrandD1].isGluon() && event[iGrandD2].isGluon());
+    else if (event[iGrandD1].isQuark() && event[iGrandD2].isQuark());
+    else return;
+  }
+  dip->iFinPol = iGrandD1;   
+
+  // Coefficient from gluon production.
+  if (dip->idMother == 21) dip->asymPol = pow2( (1. - dip->z) 
+    / (1. - dip->z * (1. - dip->z) ) );
+  else dip->asymPol = 2. * (1. - dip->z) / (1. + pow2(1. - dip->z) );
+
+  // Coefficients from gluon decay. Put z = 1/2 for hard process.
+  double zDau  = (isHardProc) ? 0.5 : dip->zOld;
+  if (event[iGrandD1].isGluon()) dip->asymPol *= pow2( (1. - zDau) 
+    / (1. - zDau * (1. - zDau) ) );
+  else  dip->asymPol *= -2. * zDau *( 1. - zDau ) 
+    / (1. - 2. * zDau * (1. - zDau) );
+
+}
+
+//--------------------------------------------------------------------------
+
+// Print the list of dipoles.
+
+void SpaceShower::list(ostream& os) const {
+
+  // Header.
+  os << "\n --------  PYTHIA SpaceShower Dipole Listing  -------------- \n"
+     << "\n    i  syst  side   rad   rec       pTmax  col  chg   ME rec \n"
+     << fixed << setprecision(3);
+  
+  // Loop over dipole list and print it.
+  for (int i = 0; i < int(dipEnd.size()); ++i) 
+  os << setw(5) << i << setw(6) << dipEnd[i].system 
+     << setw(6) << dipEnd[i].side << setw(6) << dipEnd[i].iRadiator 
+     << setw(6) << dipEnd[i].iRecoiler << setw(12) << dipEnd[i].pTmax 
+     << setw(5) << dipEnd[i].colType << setw(5) << dipEnd[i].chgType
+     << setw(5) << dipEnd[i].MEtype << setw(4) 
+     << dipEnd[i].normalRecoil << "\n";
+
+  // Done.
+  os << "\n --------  End PYTHIA SpaceShower Dipole Listing  ----------"
+     << endl;
+  
+
+}
+//==========================================================================
+
+} // end namespace Pythia8
+