StRoot  1
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
DireHistory.cc
1 // DireHistory.cc is a part of the PYTHIA event generator.
2 // Copyright (C) 2020 Stefan Prestel, Torbjorn Sjostrand.
3 // PYTHIA is licenced under the GNU GPL v2 or later, see COPYING for details.
4 // Please respect the MCnet Guidelines, see GUIDELINES for details.
5 
6 // Function definitions (not found in the header) for Dire history classes.
7 
8 #include "Pythia8/DireHistory.h"
9 #include "Pythia8/DireSpace.h"
10 #include "Pythia8/DireTimes.h"
11 
12 namespace Pythia8 {
13 
14 //==========================================================================
15 
16 string stringFlavs(const Event& event) {
17  ostringstream os;
18  os << " (";
19  for (int i=0; i < event.size(); ++i)
20  if (event[i].status() == -21) os << " " << event[i].id();
21  os << " ) -->> (";
22  for (int i=0; i < event.size(); ++i) {
23  if (event[i].status() == 23) os << " " << event[i].id();
24  if (event[i].status() == 22) os << " " << event[i].id();
25  }
26  os << " ) ";
27  return os.str();
28 }
29 
30 void listFlavs(const Event& event, bool includeEndl = false) {
31  cout << std::left << setw(30) << stringFlavs(event);
32  if (includeEndl) cout << endl;
33 }
34 
35 //--------------------------------------------------------------------------
36 
37 // Helper class for setEffectiveScales.
38 
40 
41 public:
42 
44  as(asIn), aem(nullptr), asPow(1), aemPow(1) {};
45  DireCouplFunction(AlphaEM* aemIn) :
46  as(nullptr), aem(aemIn), asPow(1), aemPow(1) {};
47  DireCouplFunction(AlphaStrong* asIn, int asPowIn,
48  AlphaEM* aemIn, int aemPowIn) : as(asIn), aem(aemIn), asPow(asPowIn),
49  aemPow(aemPowIn) {};
50  double f(double x) {
51  double ret = (as==nullptr) ? 1. : pow(as->alphaS(x),asPow);
52  ret *= (aem==nullptr) ? 1. : pow(aem->alphaEM(x),aemPow);
53  return ret;
54  }
55  double f(double x, double) {
56  double ret = (as==nullptr) ? 1. : pow(as->alphaS(x),asPow);
57  ret *= (aem==nullptr) ? 1. : pow(aem->alphaEM(x),aemPow);
58  return ret;
59  }
60  double f(double x, vector<double>) {
61  double ret = (as==nullptr) ? 1. : pow(as->alphaS(x),asPow);
62  ret *= (aem==nullptr) ? 1. : pow(aem->alphaEM(x),aemPow);
63  return ret;
64  }
65  AlphaStrong* as;
66  AlphaEM* aem;
67  int asPow, aemPow;
68 
69 };
70 
71 //==========================================================================
72 
73 // The Clustering class.
74 
75 //--------------------------------------------------------------------------
76 
77 // Declaration of Clustering class
78 // This class holds information about one radiator, recoiler,
79 // emitted system.
80 // This class is a container class for DireHistory class use.
81 
82 // print for debug
83 void DireClustering::list() const {
84  cout << " emt " << emitted
85  << " rad " << emittor
86  << " rec " << recoiler
87  << " partner " << partner
88  << " pTscale " << pTscale
89  << " name " << name() << endl;
90 }
91 
92 //==========================================================================
93 
94 // The DireHistory class.
95 
96 // A DireHistory object represents an event in a given step in the CKKW-L
97 // clustering procedure. It defines a tree-like recursive structure,
98 // where the root node represents the state with n jets as given by
99 // the matrix element generator, and is characterized by the member
100 // variable mother being null. The leaves on the tree corresponds to a
101 // fully clustered paths where the original n-jets has been clustered
102 // down to the Born-level state. Also states which cannot be clustered
103 // down to the Born-level are possible - these will be called
104 // incomplete. The leaves are characterized by the vector of children
105 // being empty.
106 
107 //--------------------------------------------------------------------------
108 
109 // Number of trial emission to use for calculating the average number of
110 // emissions
111 const int DireHistory::NTRIAL = 1;
112 
113 const double DireHistory::MCWINDOW = 0.1;
114 const double DireHistory::MBWINDOW = 0.1;
115 const double DireHistory::PROBMAXFAC = 0.0;
116 
117 //--------------------------------------------------------------------------
118 
119 // Declaration of DireHistory class
120 // The only constructor. Default arguments are used when creating
121 // the initial history node. The depth is the maximum number of
122 // clusterings requested. scalein is the scale at which the \a
123 // statein was clustered (should be set to the merging scale for the
124 // initial history node. beamAIn and beamBIn are needed to
125 // calcutate PDF ratios, particleDataIn to have access to the
126 // correct masses of particles. If isOrdered is true, the previous
127 // clusterings has been ordered. is the PDF ratio for this
128 // clustering (=1 for FSR clusterings). probin is the accumulated
129 // probabilities for the previous clusterings, and \ mothin is the
130 // previous history node (null for the initial node).
131 
132 DireHistory::DireHistory( int depthIn,
133  double scalein,
134  Event statein,
135  DireClustering c,
136  MergingHooksPtr mergingHooksPtrIn,
137  BeamParticle beamAIn,
138  BeamParticle beamBIn,
139  ParticleData* particleDataPtrIn,
140  Info* infoPtrIn,
141  PartonLevel* showersIn,
142  shared_ptr<DireTimes> fsrIn,
143  shared_ptr<DireSpace> isrIn,
144  DireWeightContainer* psweightsIn,
145  CoupSM* coupSMPtrIn,
146  bool isOrdered = true,
147  bool isAllowed = true,
148  double clusterProbIn = 1.0,
149  double clusterCouplIn = 1.0,
150  double prodOfProbsIn = 1.0,
151  double prodOfProbsFullIn = 1.0,
152  DireHistory * mothin = 0)
153  : state(statein),
154  generation(depthIn),
155  mother(mothin),
156  selectedChild(-1),
157  sumpath(0.0),
158  sumGoodBranches(0.0),
159  sumBadBranches(0.0),
160  foundOrderedPath(false),
161  foundAllowedPath(false),
162  foundCompletePath(false),
163  foundOrderedChildren(true),
164  scale(scalein),
165  scaleEffective(0.),
166  couplEffective(1.),
167  clusterProb(clusterProbIn),
168  clusterCoupl(clusterCouplIn),
169  prodOfProbs(prodOfProbsIn),
170  prodOfProbsFull(prodOfProbsFullIn),
171  clusterIn(c),
172  iReclusteredOld(0),
173  doInclude(true),
174  hasMEweight(false),
175  MECnum(1.0),
176  MECden(1.0),
177  MECcontrib(1.0),
178  mergingHooksPtr(mergingHooksPtrIn),
179  beamA(beamAIn),
180  beamB(beamBIn),
181  particleDataPtr(particleDataPtrIn),
182  infoPtr(infoPtrIn),
183  showers(showersIn),
184  fsr(fsrIn),
185  isr(isrIn),
186  coupSMPtr(coupSMPtrIn),
187  psweights(psweightsIn),
188  doSingleLegSudakovs(
189  infoPtr->settingsPtr->flag("Dire:doSingleLegSudakovs")),
190  probMaxSave(-1.),
191  depth(depthIn),
192  minDepthSave(-1) {
193 
194  fsr->direInfoPtr->message(1)
195  << scientific << setprecision(15)
196  << __FILE__ << " " << __func__
197  << " " << __LINE__ << " : New history node "
198  << stringFlavs(state) << " at "
199  << clusterIn.name() << " " << clusterIn.pT() << " "
200  << (clusterIn.radSave? clusterIn.radSave->id() : 0) << " "
201  << (clusterIn.emtSave? clusterIn.emtSave->id() : 0) << " "
202  << (clusterIn.recSave? clusterIn.recSave->id() : 0) << " "
203  << clusterProb << " "
204  << clusterCoupl << " "
205  << prodOfProbs << " "
206  << "\t\t bare prob = " << clusterProb*pow2(clusterIn.pT())
207  << " pT = " << clusterIn.pT()
208  << endl;
209 
210  // Initialize.
211  goodBranches.clear();
212  badBranches.clear();
213  paths.clear();
214 
215  // Remember how many steps in total were supposed to be taken.
216  if (!mother) nStepsMax = depth;
217  else nStepsMax = mother->nStepsMax;
218 
219  // Initialise beam particles
220  setupBeams();
221 
222  // Update probability with PDF ratio
223  if (mother && mergingHooksPtr->includeRedundant()) {
224  double pdfFac = pdfForSudakov();
225  clusterProb *= pdfFac;
226  prodOfProbs *= pdfFac;
227  prodOfProbsFull *= pdfFac;
228  }
229 
230  // Remember reclustered radiator in lower multiplicity state
231  if ( mother ) iReclusteredOld = mother->iReclusteredNew;
232 
233  // Check if more steps should be taken.
234  int nFinalHeavy = 0, nFinalLight = 0;
235  for ( int i = 0; i < int(state.size()); ++i )
236  if ( state[i].status() > 0) {
237  if ( state[i].idAbs() == 23
238  || state[i].idAbs() == 24
239  || state[i].idAbs() == 25)
240  nFinalHeavy++;
241  if ( state[i].colType() != 0
242  || state[i].idAbs() == 22
243  || (state[i].idAbs() > 10 && state[i].idAbs() < 20) )
244  nFinalLight++;
245  }
246  if (nFinalHeavy == 1 && nFinalLight == 0) depth = 0;
247 
248  // Update generation index.
249  generation = depth;
250 
251  // If this is not the fully clustered state, try to find possible
252  // QCD clusterings.
253  vector<DireClustering> clusterings;
254  if ( depth > 0 ) clusterings = getAllClusterings(state);
255 
256  if (nFinalHeavy == 0 && nFinalLight == 2 && clusterings.empty()) depth = 0;
257 
258  if ( clusterings.empty() ) {
259  hasMEweight = psweights->hasME(state);
260  if (hasMEweight) MECnum = psweights->getME(state);
261  else MECnum = hardProcessME(state);
262  fsr->direInfoPtr->message(1)
263  << scientific << setprecision(15)
264  << __FILE__ << " " << __func__
265  << " " << __LINE__ << " : Hard ME for "
266  << stringFlavs(state) << " found? " << hasMEweight << " ME "
267  << MECnum << endl;
268  } else {
269  // Check if fixed-order ME calculation for this state exists.
270  hasMEweight = psweights->hasME(state);
271  // Calculate ME
272  if (hasMEweight) MECnum = psweights->getME(state);
273  fsr->direInfoPtr->message(1)
274  << scientific << setprecision(15)
275  << __FILE__ << " " << __func__
276  << " " << __LINE__ << " : Hard ME for "
277  << stringFlavs(state) << " found? " << hasMEweight << " ME "
278  << MECnum << endl;
279  }
280 
281  int na=0, nf = 0;
282  for ( int i = 0; i < int(state.size()); ++i ) {
283  if ( state[i].status() > 0 ) nf++;
284  if ( state[i].status() > 0 && state[i].idAbs() == 22) na++;
285  }
286 
287  // Check if more steps should be taken.
288  int nfqq = 0, nfhh = 0, nfgg = 0;
289  for ( int i = 0; i < int(state.size()); ++i )
290  if ( state[i].status() > 0) {
291  if ( state[i].idAbs() < 10) nfqq++;
292  if ( state[i].idAbs() == 21) nfgg++;
293  if ( state[i].idAbs() == 25) nfhh++;
294  }
295 
296  // If no clusterings were found, the recursion is done and we
297  // register this node.
298  if ( clusterings.empty() ) {
299 
300  // Multiply with hard process matrix element.
301  prodOfProbs *= MECnum;
302  prodOfProbsFull *= MECnum;
303 
304  // Divide out all couplings in hard process matrix element.
305  double MECnumCoupl = hardProcessCouplings(state);
306  if (MECnumCoupl != 0.0) {
307  prodOfProbs /= MECnumCoupl;
308  prodOfProbsFull /= MECnumCoupl;
309  // If the coupling exactly vanishes, force weight to zero.
310  } else {
311  prodOfProbs = 0.0;
312  prodOfProbsFull = 0.0;
313  }
314 
315  // Additional ordering requirement between shower starting scale and
316  // scale of first emission.
317  if ( mergingHooksPtr->orderHistories()
318  || ( infoPtr->settingsPtr->flag("Dire:doMOPS")
319  && infoPtr->settingsPtr->mode("Merging:nRequested") < 2) )
320  isOrdered = isOrdered && (scale < hardStartScale(state) );
321 
322  if (registerPath( *this, isOrdered, isAllowed, depth == 0 ))
323  updateMinDepth(depth);
324 
325  return;
326  }
327 
328  // Now we sort the possible clusterings so that we try the
329  // smallest scale first.
330  multimap<double, DireClustering *> sorted;
331  for ( int i = 0, N = clusterings.size(); i < N; ++i ) {
332  sorted.insert(make_pair(clusterings[i].pT(), &clusterings[i]));
333  }
334 
335  bool foundChild = false;
336  for ( multimap<double, DireClustering *>::iterator it = sorted.begin();
337  it != sorted.end(); ++it ) {
338 
339  // Check if reclustering follows ordered sequence.
340  bool ordered = isOrdered;
341  if ( mergingHooksPtr->orderHistories() ) {
342  // If this path is not ordered in pT and we already have found an
343  // ordered path, then we don't need to continue along this path, unless
344  // we have not yet found an allowed path.
345  if ( !ordered || ( mother && (it->first < scale) ) ) {
346  if ( depth >= minDepth() && onlyOrderedPaths() && onlyAllowedPaths() )
347  continue;
348  ordered = false;
349  }
350  }
351 
352  if ( !ordered || ( mother && (it->first < scale) ) ) ordered = false;
353 
354  Event newState(cluster(*it->second));
355 
356  if ( newState.size() == 0) continue;
357 
358  // Check if reclustered state should be disallowed.
359  bool doCut = mergingHooksPtr->canCutOnRecState()
360  || mergingHooksPtr->allowCutOnRecState();
361  bool allowed = isAllowed;
362  if ( doCut
363  && mergingHooksPtr->doCutOnRecState(newState) ) {
364  if ( onlyAllowedPaths() ) continue;
365  allowed = false;
366  }
367 
368  pair <double,double> probs = getProb(*it->second);
369 
370  // Skip clustering with vanishing probability.
371  if ( probs.second == 0. || hardProcessCouplings(newState) == 0.
372  || (psweights->hasME(newState) && psweights->getME(newState) < 1e-20))
373  continue;
374  // Skip if this branch is already strongly suppressed.
375  if (abs(probs.second)*prodOfProbs < PROBMAXFAC*probMax())
376  continue;
377 
378  // Perform the clustering and recurse and construct the next
379  // history node.
380  children.push_back(new DireHistory(depth - 1,it->first, newState,
381  *it->second, mergingHooksPtr, beamA, beamB, particleDataPtr,
382  infoPtr, showers, fsr, isr, psweights, coupSMPtr, ordered,
383  allowed,
384  probs.second, probs.first, abs(probs.second)*prodOfProbs,
385  probs.second*prodOfProbsFull, this ));
386  foundChild = true;
387  }
388 
389  // Register as valid history if no children allowed.
390  if (!foundChild) {
391 
392  // Multiply with hard process matrix element.
393  prodOfProbs *= MECnum;
394  prodOfProbsFull *= MECnum;
395 
396  // Divide out all couplings in hard process matrix element.
397  double MECnumCoupl = hardProcessCouplings(state);
398  if (MECnumCoupl != 0.0) {
399  prodOfProbs /= MECnumCoupl;
400  prodOfProbsFull /= MECnumCoupl;
401  // If the coupling exactly vanishes, force weight to zero.
402  } else {
403  prodOfProbs = 0.0;
404  prodOfProbsFull = 0.0;
405  }
406 
407  if (registerPath( *this, isOrdered, isAllowed, depth == 0 ))
408  updateMinDepth(depth);
409  }
410 
411 }
412 
413 //--------------------------------------------------------------------------
414 
415 // Function to project all possible paths onto only the desired paths.
416 
417 bool DireHistory::projectOntoDesiredHistories() {
418 
419  bool foundGoodMOPS=true;
420 
421  // In MOPS, discard states that yield clusterings below the shower cut-off.
422  if ( infoPtr->settingsPtr->flag("Dire:doMOPS")) {
423  for ( map<double, DireHistory*>::iterator it = paths.begin();
424  it != paths.end(); ++it ) {
425  if (!it->second->hasScalesAboveCutoff()) { foundGoodMOPS=false; break; }
426  }
427  }
428 
429  // Loop through good branches and set the set of "good" children in mother
430  // nodes.
431  for ( map<double, DireHistory*>::iterator it = paths.begin();
432  it != paths.end(); ++it )
433  it->second->setGoodChildren();
434 
435  // Set good sisters.
436  setGoodSisters();
437 
438  // Multiply couplings and ME corrections to probability.
439  for ( map<double, DireHistory*>::iterator it = paths.begin();
440  it != paths.end(); ++it ) {
441  it->second->setCouplingOrderCount(it->second);
442  }
443 
444  // Loop through the good branches and set their correct probabilities, if
445  // necessary.
446  if (paths.size() > 0) {
447  //paths.begin()->second->mother->setProbabilities();
448  // Set probabilities from next-to-lowest multi --> highest multi. If
449  // lowest multi == highest multi, no need to set probabilities.
450  DireHistory* deepest = nullptr;
451 
452  // Set probabilities from next-to-lowest multi --> highest multi. If
453  // lowest multi == highest multi, no need to set probabilities.
454  int generationMin = 1000000000;
455  for ( map<double, DireHistory*>::iterator it = paths.begin();
456  it != paths.end(); ++it )
457  if (it->second->generation < generationMin) {
458  generationMin = it->second->generation;
459  deepest = it->second;
460  }
461  if (deepest->mother) deepest->mother->setProbabilities();
462  if (deepest->mother) deepest->mother->setEffectiveScales();
463 
464  }
465 
466  // Multiply couplings and ME corrections to probability.
467  for ( map<double, DireHistory*>::iterator it = paths.begin();
468  it != paths.end(); ++it ) {
469  it->second->multiplyMEsToPath(it->second);
470  }
471 
472  // Trim to desirable histories.
473  bool foundGood = trimHistories();
474 
475  //return foundGood;
476  return (infoPtr->settingsPtr->flag("Dire:doMOPS")
477  ? foundGoodMOPS : foundGood);
478 
479 }
480 
481 //--------------------------------------------------------------------------
482 
483 // In the initial history node, select one of the paths according to
484 // the probabilities. This function should be called for the initial
485 // history node.
486 // IN trialShower* : Previously initialised trialShower object,
487 // to perform trial showering and as
488 // repository of pointers to initialise alphaS
489 // PartonSystems* : PartonSystems object needed to initialise
490 // shower objects
491 // OUT double : (Sukadov) , (alpha_S ratios) , (PDF ratios)
492 
493 double DireHistory::weightMOPS(PartonLevel* trial, AlphaStrong * /*as*/,
494  AlphaEM * /*aem*/, double RN) {
495 
496  // Read alpha_S in ME calculation and maximal scale (eCM)
497  double maxScale = (foundCompletePath) ? infoPtr->eCM()
498  : mergingHooksPtr->muFinME();
499 
500  // Select a path of clusterings
501  DireHistory * selected = select(RN);
502 
503  // Set scales in the states to the scales pythia would have set
504  selected->setScalesInHistory();
505 
506  // Keep only unordered paths, since all ordered paths have been corrected
507  // with matrix element corrections.
508  if (foundOrderedPath) { return 0.;}
509 
510  // Calculate no-emission probability with trial shower.
511  bool nZero = false;
512  vector<double> ret(createvector<double>(1.)(1.)(1.));
513  vector<double> noemwt = selected->weightEmissionsVec(trial,1,-1,-1,maxScale);
514  for (size_t i=0; i < ret.size(); ++i) ret[i] *= noemwt[i];
515  for (size_t i=0; i < ret.size(); ++i) if (abs(ret[i]) > 1e-12) nZero = true;
516 
517  double sudakov = noemwt.front();
518 
519  // Calculate PDF ratios.
520  double pdfwt = 1.;
521  if (nZero) pdfwt = selected->weightPDFs( maxScale, selected->clusterIn.pT());
522  for (size_t i=0; i < ret.size(); ++i) ret[i] *= pdfwt;
523  nZero = false;
524  for (size_t i=0; i < ret.size(); ++i) if (abs(ret[i]) > 1e-12) nZero = true;
525 
526  // Calculate coupling ratios.
527  vector<double> couplwt(createvector<double>(1.)(1.)(1.));
528  if (nZero) couplwt = selected->weightCouplingsDenominator();
529  for (size_t i=0; i < ret.size(); ++i) ret[i] *= couplwt[i];
530  nZero = false;
531  for (size_t i=0; i < ret.size(); ++i) if (abs(ret[i]) > 1e-12) nZero = true;
532 
533  double coupwt = couplEffective/couplwt.front();
534 
535  // MPI no-emission probability
536  int njetsMaxMPI = mergingHooksPtr->nMinMPI();
537  double mpiwt = 1.;
538 
539  if (infoPtr->settingsPtr->flag("PartonLevel:MPI")) mpiwt
540  = selected->weightEmissions( trial, -1, 0, njetsMaxMPI, maxScale );
541 
542  // Done
543  return (sudakov*coupwt*pdfwt*mpiwt);
544 
545 }
546 
547 //--------------------------------------------------------------------------
548 
549 vector<double> DireHistory::weightMEM(PartonLevel* trial, AlphaStrong * as,
550  AlphaEM * aem, double RN) {
551 
552  // Read alpha_S in ME calculation and maximal scale (eCM)
553  double maxScale = (foundCompletePath) ? infoPtr->eCM()
554  : mergingHooksPtr->muFinME();
555 
556  // Select a path of clusterings
557  DireHistory * selected = select(RN);
558 
559  // Set scales in the states to the scales pythia would have set
560  selected->setScalesInHistory();
561 
562  // Calculate no-emission probability with trial shower.
563  bool nZero = false;
564  vector<double> ret(createvector<double>(1.)(1.)(1.));
565  vector<double> noemwt = selected->weightEmissionsVec(trial,1,-1,-1,maxScale);
566  for (size_t i=0; i < ret.size(); ++i) ret[i] *= noemwt[i];
567  for (size_t i=0; i < ret.size(); ++i) if (abs(ret[i]) > 1e-12) nZero = true;
568 
569  // Calculate PDF ratios.
570  double pdfwt = 1.;
571  if (nZero) pdfwt = selected->weightPDFs( maxScale, selected->clusterIn.pT());
572  for (size_t i=0; i < ret.size(); ++i) ret[i] *= pdfwt;
573  nZero = false;
574  for (size_t i=0; i < ret.size(); ++i) if (abs(ret[i]) > 1e-12) nZero = true;
575 
576  // Calculate coupling ratios.
577  vector<double> couplwt(createvector<double>(1.)(1.)(1.));
578  if (nZero) couplwt = selected->weightCouplings();
579  for (size_t i=0; i < ret.size(); ++i) ret[i] *= couplwt[i];
580  nZero = false;
581  for (size_t i=0; i < ret.size(); ++i) if (abs(ret[i]) > 1e-12) nZero = true;
582 
583  if (nZero) {
584  vector<double> vars(createvector<double>(1.)(0.25)(4.));
585  double QRen = selected->hardProcessScale(selected->state);
586  double coupl = selected->hardProcessCouplings(selected->state, 1,
587  QRen*QRen, as, aem);
588  for (size_t i=0; i < vars.size(); ++i) {
589  double ratio = selected->hardProcessCouplings(selected->state, 1,
590  vars[i]*QRen*QRen, as, aem) / coupl;
591  ret[i] *= ratio;
592  }
593  }
594  return ret;
595 
596 }
597 
598 //--------------------------------------------------------------------------
599 
600 // In the initial history node, select one of the paths according to
601 // the probabilities. This function should be called for the initial
602 // history node.
603 // IN trialShower* : Previously initialised trialShower object,
604 // to perform trial showering and as
605 // repository of pointers to initialise alphaS
606 // PartonSystems* : PartonSystems object needed to initialise
607 // shower objects
608 // OUT double : (Sukadov) , (alpha_S ratios) , (PDF ratios)
609 
610 double DireHistory::weightTREE(PartonLevel* trial, AlphaStrong * asFSR,
611  AlphaStrong * asISR, AlphaEM * aemFSR, AlphaEM * aemISR, double RN) {
612 
613  if ( mergingHooksPtr->canCutOnRecState() && !foundAllowedPath ) {
614  string message="Warning in DireHistory::weightTREE: No allowed history";
615  message+=" found. Using disallowed history.";
616  infoPtr->errorMsg(message);
617  }
618 
619  if ( mergingHooksPtr->orderHistories() && !foundOrderedPath ) {
620  string message="Warning in DireHistory::weightTREE: No ordered history";
621  message+=" found. Using unordered history.";
622  infoPtr->errorMsg(message);
623  }
624  if ( mergingHooksPtr->canCutOnRecState()
625  && mergingHooksPtr->orderHistories()
626  && !foundAllowedPath && !foundOrderedPath ) {
627  string message="Warning in DireHistory::weightTREE: No allowed or ordered";
628  message+=" history found.";
629  infoPtr->errorMsg(message);
630  }
631 
632  // Read alpha_S in ME calculation and maximal scale (eCM)
633  double asME = infoPtr->alphaS();
634  double aemME = infoPtr->alphaEM();
635  double maxScale = (foundCompletePath) ? infoPtr->eCM()
636  : mergingHooksPtr->muFinME();
637 
638  // Select a path of clusterings
639  DireHistory * selected = select(RN);
640 
641  // Set scales in the states to the scales pythia would have set
642  selected->setScalesInHistory();
643 
644  // Get weight.
645  double sudakov = 1.;
646  double asWeight = 1.;
647  double aemWeight = 1.;
648  double pdfWeight = 1.;
649 
650  // Do trial shower, calculation of alpha_S ratios, PDF ratios
651  sudakov = selected->weight( trial, asME, aemME, maxScale,
652  selected->clusterIn.pT(), asFSR, asISR, aemFSR, aemISR, asWeight,
653  aemWeight, pdfWeight );
654 
655  // MPI no-emission probability
656  int njetsMaxMPI = mergingHooksPtr->nMinMPI();
657  //double mpiwt = selected->weightEmissions( trial, -1, 0, njetsMaxMPI,
658  // maxScale );
659  double mpiwt = 1.;
660 
661  if (infoPtr->settingsPtr->flag("PartonLevel:MPI")) mpiwt
662  = selected->weightEmissions( trial, -1, 0, njetsMaxMPI, maxScale );
663 
664  // Set hard process renormalisation scale to default Pythia value.
665  bool resetScales = mergingHooksPtr->resetHardQRen();
666 
667  // For pure QCD dijet events, evaluate the coupling of the hard process at
668  // a more reasonable pT, rather than evaluation \alpha_s at a fixed
669  // arbitrary scale.
670  if ( resetScales
671  && mergingHooksPtr->getProcessString().compare("pp>jj") == 0) {
672  // Reset to a running coupling. Here we choose FSR for simplicity.
673  double newQ2Ren = pow2( selected->hardRenScale(selected->state) );
674  double runningCoupling = (*asFSR).alphaS(newQ2Ren) / asME;
675  asWeight *= pow2(runningCoupling);
676  } else if (mergingHooksPtr->doWeakClustering()
677  && isQCD2to2(selected->state)) {
678  // Reset to a running coupling. Here we choose FSR for simplicity.
679  double newQ2Ren = pow2( selected->hardRenScale(selected->state) );
680  double runningCoupling = (*asFSR).alphaS(newQ2Ren) / asME;
681  asWeight *= pow2(runningCoupling);
682  }
683 
684  // For W clustering, correct the \alpha_em.
685  if (mergingHooksPtr->doWeakClustering() && isEW2to1(selected->state)) {
686  // Reset to a running coupling. Here we choose FSR for simplicity.
687  double newQ2Ren = pow2( selected->hardRenScale(selected->state) );
688  double runningCoupling = (*aemFSR).alphaEM(newQ2Ren) / aemME;
689  aemWeight *= runningCoupling;
690  }
691 
692  // For prompt photon events, evaluate the coupling of the hard process at
693  // a more reasonable pT, rather than evaluation \alpha_s at a fixed
694  // arbitrary scale.
695  if ( resetScales
696  && mergingHooksPtr->getProcessString().compare("pp>aj") == 0) {
697  // Reset to a running coupling. In prompt photon always ISR.
698  double newQ2Ren = pow2( selected->hardRenScale(selected->state) );
699  double runningCoupling =
700  (*asISR).alphaS( newQ2Ren + pow(mergingHooksPtr->pT0ISR(),2) ) / asME;
701  asWeight *= runningCoupling;
702  }
703 
704  // For DIS, set the hard process scale to Q2.
705  if ( resetScales
706  && ( mergingHooksPtr->getProcessString().compare("e+p>e+j") == 0
707  || mergingHooksPtr->getProcessString().compare("e-p>e-j") == 0)) {
708  double newQ2Ren = pow2( selected->hardRenScale(selected->state) );
709  double pT20 = pow(mergingHooksPtr->pT0ISR(),2);
710  if ( isMassless2to2(selected->state) ) {
711  int nIncP(0), nOutP(0);
712  for ( int i=0; i < selected->state.size(); ++i ) {
713  if ( selected->state[i].isFinal()
714  && selected->state[i].colType() != 0)
715  nOutP++;
716  if ( selected->state[i].status() == -21
717  && selected->state[i].colType() != 0)
718  nIncP++;
719  }
720  if (nIncP == 2 && nOutP == 2)
721  asWeight *= pow2( (*asISR).alphaS(newQ2Ren+pT20) / asME );
722  if (nIncP == 1 && nOutP == 2)
723  asWeight *= (*asISR).alphaS(newQ2Ren+pT20) / asME
724  * (*aemFSR).alphaEM(newQ2Ren) / aemME;
725  }
726  }
727 
728  // Done
729  return (sudakov*asWeight*aemWeight*pdfWeight*mpiwt);
730 
731 }
732 
733 //--------------------------------------------------------------------------
734 
735 // Function to return weight of virtual correction and subtractive events
736 // for NL3 merging
737 
738 double DireHistory::weightLOOP(PartonLevel* trial, double RN ) {
739 
740  if ( mergingHooksPtr->canCutOnRecState() && !foundAllowedPath ) {
741  string message="Warning in DireHistory::weightLOOP: No allowed history";
742  message+=" found. Using disallowed history.";
743  infoPtr->errorMsg(message);
744  }
745 
746  // Select a path of clusterings
747  DireHistory * selected = select(RN);
748  // Set scales in the states to the scales pythia would have set
749  selected->setScalesInHistory();
750 
751  // So far, no reweighting
752  double wt = 1.;
753 
754  // Only reweighting with MPI no-emission probability
755  double maxScale = (foundCompletePath) ? infoPtr->eCM()
756  : mergingHooksPtr->muFinME();
757  int njetsMaxMPI = mergingHooksPtr->nMinMPI();
758  double mpiwt = selected->weightEmissions( trial, -1, 0, njetsMaxMPI,
759  maxScale );
760  wt = mpiwt;
761  // Done
762  return wt;
763 }
764 
765 //--------------------------------------------------------------------------
766 
767 // Function to calculate O(\alpha_s)-term of CKKWL-weight for NLO merging
768 
769 double DireHistory::weightFIRST(PartonLevel* trial, AlphaStrong* asFSR,
770  AlphaStrong* asISR, AlphaEM * aemFSR, AlphaEM * aemISR, double RN,
771  Rndm* rndmPtr ) {
772 
773  // Dummy statement to avoid compiler warnings.
774  if (false) cout << aemFSR << aemISR;
775 
776  // Read alpha_S in ME calculation and maximal scale (eCM)
777  double asME = infoPtr->alphaS();
778  double muR = mergingHooksPtr->muRinME();
779  double maxScale = (foundCompletePath)
780  ? infoPtr->eCM()
781  : mergingHooksPtr->muFinME();
782 
783  // Pick path of clusterings
784  DireHistory * selected = select(RN);
785  // Set scales in the states to the scales pythia would have set
786  selected->setScalesInHistory();
787 
788  int nSteps = mergingHooksPtr->getNumberOfClusteringSteps(state);
789 
790  // Get the lowest order k-factor and add first two terms in expansion
791  double kFactor = asME * mergingHooksPtr->k1Factor(nSteps);
792 
793  // If using Bbar, which includes a tree-level part, subtract an
794  // additional one, i.e. the O(\as^0) contribution as well
795  double wt = 1. + kFactor;
796 
797  // Calculate sum of O(alpha) terms
798  wt += selected->weightFirst(trial,asME, muR, maxScale, asFSR, asISR,
799  rndmPtr );
800 
801  // Get starting scale for trial showers.
802  double startingScale = (selected->mother) ? state.scale() : infoPtr->eCM();
803 
804  // Count emissions: New variant
805  // Generate true average, not only one-point
806  double nWeight1 = 0.;
807  for(int i=0; i < NTRIAL; ++i) {
808  // Get number of emissions
809  vector<double> unresolvedEmissionTerm = countEmissions
810  ( trial, startingScale, mergingHooksPtr->tms(), 2, asME, asFSR, asISR, 3,
811  true, true );
812  nWeight1 += unresolvedEmissionTerm[1];
813  }
814 
815  wt += nWeight1/double(NTRIAL);
816 
817  // Done
818  return wt;
819 
820 }
821 
822 //--------------------------------------------------------------------------
823 
824 double DireHistory::weight_UMEPS_TREE(PartonLevel* trial, AlphaStrong * asFSR,
825  AlphaStrong * asISR, AlphaEM * aemFSR, AlphaEM * aemISR, double RN) {
826  // No difference to CKKW-L. Recycle CKKW-L function.
827  return weightTREE( trial, asFSR, asISR, aemFSR, aemISR, RN);
828 }
829 
830 //--------------------------------------------------------------------------
831 
832 // Function to return weight of virtual correction events for NLO merging
833 
834 double DireHistory::weight_UMEPS_SUBT(PartonLevel* trial, AlphaStrong * asFSR,
835  AlphaStrong * asISR, AlphaEM * aemFSR, AlphaEM * aemISR, double RN ) {
836 
837  // Read alpha_S in ME calculation and maximal scale (eCM)
838  double asME = infoPtr->alphaS();
839  double aemME = infoPtr->alphaEM();
840  double maxScale = (foundCompletePath) ? infoPtr->eCM()
841  : mergingHooksPtr->muFinME();
842  // Select a path of clusterings
843  DireHistory * selected = select(RN);
844  // Set scales in the states to the scales pythia would have set
845  selected->setScalesInHistory();
846 
847  // Get weight.
848  double sudakov = 1.;
849  double asWeight = 1.;
850  double aemWeight = 1.;
851  double pdfWeight = 1.;
852 
853  // Do trial shower, calculation of alpha_S ratios, PDF ratios
854  sudakov = selected->weight(trial, asME, aemME, maxScale,
855  selected->clusterIn.pT(), asFSR, asISR, aemFSR, aemISR, asWeight,
856  aemWeight, pdfWeight);
857 
858  // MPI no-emission probability.
859  int njetsMaxMPI = mergingHooksPtr->nMinMPI()+1;
860  double mpiwt = selected->weightEmissions( trial, -1, 0, njetsMaxMPI,
861  maxScale );
862 
863  // Set hard process renormalisation scale to default Pythia value.
864  bool resetScales = mergingHooksPtr->resetHardQRen();
865  // For pure QCD dijet events, evaluate the coupling of the hard process at
866  // a more reasonable pT, rather than evaluation \alpha_s at a fixed
867  // arbitrary scale.
868  if ( resetScales
869  && mergingHooksPtr->getProcessString().compare("pp>jj") == 0) {
870  // Reset to a running coupling. Here we choose FSR for simplicity.
871  double newQ2Ren = pow2( selected->hardRenScale(selected->state) );
872  double runningCoupling = (*asFSR).alphaS(newQ2Ren) / asME;
873  asWeight *= pow(runningCoupling,2);
874  }
875 
876  // For prompt photon events, evaluate the coupling of the hard process at
877  // a more reasonable pT, rather than evaluation \alpha_s at a fixed
878  // arbitrary scale.
879  if ( resetScales
880  && mergingHooksPtr->getProcessString().compare("pp>aj") == 0) {
881  // Reset to a running coupling. In prompt photon always ISR.
882  double newQ2Ren = pow2( selected->hardRenScale(selected->state) );
883  double runningCoupling =
884  (*asISR).alphaS( newQ2Ren + pow(mergingHooksPtr->pT0ISR(),2) ) / asME;
885  asWeight *= runningCoupling;
886  }
887 
888  // Done
889  return (sudakov*asWeight*aemWeight*pdfWeight*mpiwt);
890 
891 }
892 
893 //--------------------------------------------------------------------------
894 
895 double DireHistory::weight_UNLOPS_TREE(PartonLevel* trial, AlphaStrong * asFSR,
896  AlphaStrong * asISR, AlphaEM * aemFSR, AlphaEM * aemISR, double RN,
897  int depthIn) {
898 
899  // Read alpha_S in ME calculation and maximal scale (eCM)
900  double asME = infoPtr->alphaS();
901  double aemME = infoPtr->alphaEM();
902  double maxScale = (foundCompletePath) ? infoPtr->eCM()
903  : mergingHooksPtr->muFinME();
904  // Select a path of clusterings
905  DireHistory * selected = select(RN);
906  // Set scales in the states to the scales pythia would have set
907  selected->setScalesInHistory();
908 
909  // Get weight.
910  double asWeight = 1.;
911  double aemWeight = 1.;
912  double pdfWeight = 1.;
913 
914  // Do trial shower, calculation of alpha_S ratios, PDF ratios
915  double wt = 1.;
916  if (depthIn < 0) wt = selected->weight(trial, asME, aemME, maxScale,
917  selected->clusterIn.pT(), asFSR, asISR, aemFSR, aemISR, asWeight,
918  aemWeight, pdfWeight);
919  else {
920  wt = selected->weightEmissions( trial, 1, 0, depthIn, maxScale );
921  if (wt != 0.) {
922  asWeight = selected->weightALPHAS( asME, asFSR, asISR, 0, depthIn);
923  aemWeight = selected->weightALPHAEM( aemME, aemFSR, aemISR, 0, depthIn);
924  pdfWeight = selected->weightPDFs
925  ( maxScale, selected->clusterIn.pT(), 0, depthIn);
926  }
927  }
928 
929  // MPI no-emission probability.
930  int njetsMaxMPI = mergingHooksPtr->nMinMPI();
931  double mpiwt = selected->weightEmissions( trial, -1, 0, njetsMaxMPI,
932  maxScale );
933 
934  // Set hard process renormalisation scale to default Pythia value.
935  bool resetScales = mergingHooksPtr->resetHardQRen();
936  // For pure QCD dijet events, evaluate the coupling of the hard process at
937  // a more reasonable pT, rather than evaluation \alpha_s at a fixed
938  // arbitrary scale.
939  if ( resetScales
940  && mergingHooksPtr->getProcessString().compare("pp>jj") == 0) {
941  // Reset to a running coupling. Here we choose FSR for simplicity.
942  double newQ2Ren = pow2( selected->hardRenScale(selected->state) );
943  double runningCoupling = (*asFSR).alphaS(newQ2Ren) / asME;
944  asWeight *= pow(runningCoupling,2);
945  }
946 
947  // For prompt photon events, evaluate the coupling of the hard process at
948  // a more reasonable pT, rather than evaluation \alpha_s at a fixed
949  // arbitrary scale.
950  if ( resetScales
951  && mergingHooksPtr->getProcessString().compare("pp>aj") == 0) {
952  // Reset to a running coupling. In prompt photon always ISR.
953  double newQ2Ren = pow2( selected->hardRenScale(selected->state) );
954  double runningCoupling =
955  (*asISR).alphaS( newQ2Ren + pow(mergingHooksPtr->pT0ISR(),2) ) / asME;
956  asWeight *= runningCoupling;
957  }
958 
959  // Done
960  return (wt*asWeight*aemWeight*pdfWeight*mpiwt);
961 
962 }
963 
964 //--------------------------------------------------------------------------
965 
966 double DireHistory::weight_UNLOPS_LOOP(PartonLevel* trial, AlphaStrong * asFSR,
967  AlphaStrong * asISR, AlphaEM * aemFSR, AlphaEM * aemISR, double RN,
968  int depthIn) {
969  // No difference to default NL3
970  if (depthIn < 0) return weightLOOP(trial, RN);
971  else return weight_UNLOPS_TREE(trial, asFSR,asISR, aemFSR,
972  aemISR, RN, depthIn);
973 }
974 
975 //--------------------------------------------------------------------------
976 
977 double DireHistory::weight_UNLOPS_SUBT(PartonLevel* trial, AlphaStrong * asFSR,
978  AlphaStrong * asISR, AlphaEM * aemFSR, AlphaEM * aemISR, double RN,
979  int depthIn) {
980 
981  // Select a path of clusterings
982  DireHistory * selected = select(RN);
983  // Set scales in the states to the scales pythia would have set
984  selected->setScalesInHistory();
985  // So far, no reweighting
986  double wt = 1.;
987 
988  // Read alpha_S in ME calculation and maximal scale (eCM)
989  double asME = infoPtr->alphaS();
990  double aemME = infoPtr->alphaEM();
991  double maxScale = (foundCompletePath)
992  ? infoPtr->eCM()
993  : mergingHooksPtr->muFinME();
994 
995  // Only allow two clusterings if all intermediate states above the
996  // merging scale.
997  double nSteps = mergingHooksPtr->getNumberOfClusteringSteps(state);
998  if ( nSteps == 2 && mergingHooksPtr->nRecluster() == 2
999  && ( !foundCompletePath
1000  || !selected->allIntermediateAboveRhoMS( mergingHooksPtr->tms() )) )
1001  return 0.;
1002 
1003  // Get weights: alpha_S ratios and PDF ratios
1004  double asWeight = 1.;
1005  double aemWeight = 1.;
1006  double pdfWeight = 1.;
1007  // Do trial shower, calculation of alpha_S ratios, PDF ratios
1008  double sudakov = 1.;
1009  if (depthIn < 0)
1010  sudakov = selected->weight(trial, asME, aemME, maxScale,
1011  selected->clusterIn.pT(), asFSR, asISR, aemFSR, aemISR, asWeight,
1012  aemWeight, pdfWeight);
1013  else {
1014  sudakov = selected->weightEmissions( trial, 1, 0, depthIn, maxScale );
1015  if (sudakov > 0.) {
1016  asWeight = selected->weightALPHAS( asME, asFSR, asISR, 0, depthIn);
1017  aemWeight = selected->weightALPHAEM( aemME, aemFSR, aemISR, 0, depthIn);
1018  pdfWeight = selected->weightPDFs
1019  ( maxScale, selected->clusterIn.pT(), 0, depthIn);
1020  }
1021  }
1022 
1023  // MPI no-emission probability.
1024  int njetsMaxMPI = mergingHooksPtr->nMinMPI()+1;
1025  double mpiwt = selected->weightEmissions( trial, -1, 0, njetsMaxMPI,
1026  maxScale );
1027 
1028  // Set weight
1029  wt = ( mergingHooksPtr->nRecluster() == 2 ) ? 1.
1030  : asWeight*aemWeight*pdfWeight*sudakov*mpiwt;
1031 
1032  // Done
1033  return wt;
1034 
1035 }
1036 
1037 //--------------------------------------------------------------------------
1038 
1039 double DireHistory::weight_UNLOPS_SUBTNLO(PartonLevel* trial,
1040  AlphaStrong * asFSR,
1041  AlphaStrong * asISR, AlphaEM * aemFSR, AlphaEM * aemISR, double RN,
1042  int depthIn) {
1043 
1044  if (depthIn < 0) {
1045 
1046  // Select a path of clusterings
1047  DireHistory * selected = select(RN);
1048  // Set scales in the states to the scales pythia would have set
1049  selected->setScalesInHistory();
1050  // So far, no reweighting
1051  double wt = 1.;
1052  // Only reweighting with MPI no-emission probability
1053  double maxScale = (foundCompletePath) ? infoPtr->eCM()
1054  : mergingHooksPtr->muFinME();
1055  int njetsMaxMPI = mergingHooksPtr->nMinMPI()+1;
1056  double mpiwt = selected->weightEmissions( trial, -1, 0, njetsMaxMPI,
1057  maxScale );
1058  wt = mpiwt;
1059  // Done
1060  return wt;
1061 
1062  } else return weight_UNLOPS_SUBT(trial, asFSR, asISR, aemFSR, aemISR, RN,
1063  depthIn);
1064 
1065 }
1066 
1067 //--------------------------------------------------------------------------
1068 
1069 // Function to calculate O(\alpha_s)-term of CKKWL-weight for NLO merging
1070 
1071 double DireHistory::weight_UNLOPS_CORRECTION( int order, PartonLevel* trial,
1072  AlphaStrong* asFSR, AlphaStrong* asISR, AlphaEM * aemFSR, AlphaEM * aemISR,
1073  double RN, Rndm* rndmPtr ) {
1074 
1075  // Dummy statement to avoid compiler warnings.
1076  if (false) cout << aemFSR << aemISR;
1077 
1078  // Already done if no correction should be calculated
1079  if ( order < 0 ) return 0.;
1080 
1081  // Read alpha_S in ME calculation and maximal scale (eCM)
1082  double asME = infoPtr->alphaS();
1083  //double aemME = infoPtr->alphaEM();
1084  double muR = mergingHooksPtr->muRinME();
1085  double maxScale = (foundCompletePath)
1086  ? infoPtr->eCM()
1087  : mergingHooksPtr->muFinME();
1088 
1089  // Pick path of clusterings
1090  DireHistory * selected = select(RN);
1091  // Set scales in the states to the scales pythia would have set
1092  selected->setScalesInHistory();
1093 
1094  double nSteps = mergingHooksPtr->getNumberOfClusteringSteps(state);
1095 
1096  // Get the lowest order k-factor and add first two terms in expansion
1097  double kFactor = asME * mergingHooksPtr->k1Factor(nSteps);
1098 
1099  // If using Bbar, which includes a tree-level part, subtract an
1100  // additional one, i.e. the O(\as^0) contribution as well
1101  double wt = 1.;
1102 
1103  // If only O(\alpha_s^0)-term is to be calculated, done already.
1104  if ( order == 0 ) return wt;
1105 
1106  // Start by adding the O(\alpha_s^1)-term of the k-factor.
1107  wt += kFactor;
1108 
1109  // Calculate sum of O(\alpha_s^1)-terms of the ckkw-l weight WITHOUT
1110  // the O(\alpha_s^1)-term of the last no-emission probability.
1111  // Get first term in expansion of alpha_s ratios.
1112  double wA = selected->weightFirstALPHAS( asME, muR, asFSR, asISR );
1113  // Add logarithm from \alpha_s expansion to weight.
1114  wt += wA;
1115  // Generate true average, not only one-point.
1116  double nWeight = 0.;
1117  for ( int i = 0; i < NTRIAL; ++i ) {
1118  // Get average number of emissions.
1119  double wE = selected->weightFirstEmissions
1120  ( trial,asME, maxScale, asFSR, asISR, true, true );
1121  // Add average number of emissions off reconstructed states to weight.
1122  nWeight += wE;
1123  // Get first term in expansion of PDF ratios.
1124  double pscale = selected->clusterIn.pT();
1125  double wP = selected->weightFirstPDFs(asME, maxScale, pscale, rndmPtr);
1126  // Add integral of DGLAP shifted PDF ratios from \alpha_s expansion to wt.
1127  nWeight += wP;
1128  }
1129  wt += nWeight/double(NTRIAL);
1130 
1131  // If O(\alpha_s^1)-term + O(\alpha_s^1)-term is to be calculated, done.
1132  if ( order == 1 ) return wt;
1133 
1134  // So far, no calculation of O(\alpha_s^2)-term
1135  return 0.;
1136 
1137 }
1138 
1139 //--------------------------------------------------------------------------
1140 
1141 // Function to set the state with complete scales for evolution.
1142 
1143 void DireHistory::getStartingConditions( const double RN, Event& outState ) {
1144 
1145  // Select the history
1146  DireHistory * selected = select(RN);
1147 
1148  // Set scales in the states to the scales pythia would have set
1149  selected->setScalesInHistory();
1150 
1151  // Get number of clustering steps.
1152  int nSteps = mergingHooksPtr->getNumberOfClusteringSteps(state);
1153 
1154  // Update the lowest order process.
1155  if (!selected->mother) {
1156  int nFinal = 0;
1157  for(int i=0; i < int(state.size()); ++i)
1158  if ( state[i].isFinal()) nFinal++;
1159 
1160  if (nSteps == 0) {
1161  double startingScale = hardStartScale(state);
1162  state.scale(startingScale);
1163  for (int i = 3;i < state.size();++i)
1164  state[i].scale(startingScale);
1165  }
1166  }
1167 
1168  // Save information on last splitting, to allow the next
1169  // emission in the shower to have smaller rapidity with
1170  // respect to the last ME splitting.
1171  infoPtr->zNowISR(0.5);
1172  infoPtr->pT2NowISR(pow(state[0].e(),2));
1173  infoPtr->hasHistory(true);
1174 
1175  // Copy the output state.
1176  outState = state;
1177 
1178  // Save MPI starting scale.
1179  if (nSteps == 0)
1180  mergingHooksPtr->muMI(infoPtr->eCM());
1181  else
1182  mergingHooksPtr->muMI(outState.scale());
1183 
1184  mergingHooksPtr->setShowerStoppingScale(0.0);
1185 
1186 }
1187 
1188 //--------------------------------------------------------------------------
1189 
1190 // Function to print the history that would be chosen from the number RN.
1191 
1192 void DireHistory::printHistory( const double RN ) {
1193  DireHistory * selected = select(RN);
1194  selected->printStates();
1195  // Done
1196 }
1197 
1198 //--------------------------------------------------------------------------
1199 
1200 // Function to print the states in a history, starting from the hard process.
1201 
1202 void DireHistory::printStates() {
1203  if ( !mother ) {
1204  cout << scientific << setprecision(4) << "Probability="
1205  << prodOfProbs << endl;
1206  cout << "State:\t\t\t"; listFlavs(state,true);
1207  return;
1208  }
1209 
1210  // Print.
1211  double p = prodOfProbs/mother->prodOfProbs;
1212  cout << scientific << setprecision(4) << "Probabilities:"
1213  << "\n\t Product = "
1214  << prodOfProbs << " " << prodOfProbsFull
1215  << "\n\t Single with coupling = " << p
1216  << "\n\t Cluster probability = " << clusterProb << "\t\t"
1217  << clusterIn.name()
1218  << "\nScale=" << clusterIn.pT() << endl;
1219  cout << "State:\t\t\t"; listFlavs(state,true);
1220  cout << "rad=" << clusterIn.radPos()
1221  << " emt=" << clusterIn.emtPos()
1222  << " rec=" << clusterIn.recPos() << endl;
1223  // Recurse
1224  mother->printStates();
1225  // Done
1226  return;
1227 }
1228 
1229 //--------------------------------------------------------------------------
1230 
1231 // Function to set the state with complete scales for evolution.
1232 
1233 bool DireHistory::getClusteredEvent( const double RN, int nSteps,
1234  Event& outState) {
1235 
1236  // Select history
1237  DireHistory * selected = select(RN);
1238  // Set scales in the states to the scales pythia would have set
1239  // (Only needed if not done before in calculation of weights or
1240  // setting of starting conditions)
1241  selected->setScalesInHistory();
1242  // If the history does not allow for nSteps clusterings (e.g. because the
1243  // history is incomplete), return false
1244  if (nSteps > selected->nClusterings()) return false;
1245  // Return event with nSteps-1 additional partons (i.e. recluster the last
1246  // splitting) and copy the output state
1247  outState = selected->clusteredState(nSteps-1);
1248  // Done.
1249  return true;
1250 
1251 }
1252 
1253 //--------------------------------------------------------------------------
1254 
1255 bool DireHistory::getFirstClusteredEventAboveTMS( const double RN,
1256  int nDesired, Event& process, int& nPerformed, bool doUpdate ) {
1257 
1258  // Do reclustering (looping) steps. Remember process scale.
1259  int nTried = nDesired - 1;
1260  // Get number of clustering steps.
1261  int nSteps = select(RN)->nClusterings();
1262  // Set scales in the states to the scales pythia would have set.
1263  select(RN)->setScalesInHistory();
1264 
1265  // Recluster until reclustered event is above the merging scale.
1266  Event dummy = Event();
1267  do {
1268  // Initialise temporary output of reclustering.
1269  dummy.clear();
1270  dummy.init( "(hard process-modified)", particleDataPtr );
1271  dummy.clear();
1272  // Recluster once more.
1273  nTried++;
1274  // If reclustered event does not exist, exit.
1275  if ( !getClusteredEvent( RN, nSteps-nTried+1, dummy ) ) return false;
1276  if ( nTried >= nSteps ) break;
1277 
1278  // Continue loop if reclustered event has unresolved partons.
1279  } while ( mergingHooksPtr->getNumberOfClusteringSteps(dummy) > 0
1280  && mergingHooksPtr->tmsNow( dummy) < mergingHooksPtr->tms() );
1281 
1282  // Update the hard process.
1283  if ( doUpdate ) process = dummy;
1284 
1285  // Failed to produce output state.
1286  if ( nTried > nSteps ) return false;
1287 
1288  nPerformed = nTried;
1289  if ( doUpdate ) {
1290  // Update to the actual number of steps.
1291  mergingHooksPtr->nReclusterSave = nPerformed;
1292  // Save MPI starting scale
1293  if (mergingHooksPtr->getNumberOfClusteringSteps(state) == 0)
1294  mergingHooksPtr->muMI(infoPtr->eCM());
1295  else
1296  mergingHooksPtr->muMI(state.scale());
1297  }
1298 
1299  // Done
1300  return true;
1301 
1302 }
1303 
1304 //--------------------------------------------------------------------------
1305 
1306 // Calculate and return pdf ratio.
1307 
1308 double DireHistory::getPDFratio( int side, bool forSudakov, bool useHardPDFs,
1309  int flavNum, double xNum, double muNum,
1310  int flavDen, double xDen, double muDen) {
1311 
1312  // Do nothing for e+e- beams
1313  if ( particleDataPtr->colType(flavNum) == 0) return 1.0;
1314  if ( particleDataPtr->colType(flavDen) == 0) return 1.0;
1315 
1316  // Now calculate PDF ratio if necessary
1317  double pdfRatio = 1.0;
1318 
1319  // Get mother and daughter pdfs
1320  double pdfNum = 0.0;
1321  double pdfDen = 0.0;
1322 
1323  // Use hard process PDFs (i.e. PDFs NOT used in ISR, FSR or MPI).
1324  if ( useHardPDFs ) {
1325  if (side == 1) {
1326  if (forSudakov)
1327  pdfNum = mother->beamA.xfHard( flavNum, xNum, muNum*muNum);
1328  else pdfNum = beamA.xfHard( flavNum, xNum, muNum*muNum);
1329  pdfDen = max(1e-10, beamA.xfHard( flavDen, xDen, muDen*muDen));
1330  } else {
1331  if (forSudakov)
1332  pdfNum = mother->beamB.xfHard( flavNum, xNum, muNum*muNum);
1333  else pdfNum = beamB.xfHard( flavNum, xNum, muNum*muNum);
1334  pdfDen = max(1e-10,beamB.xfHard( flavDen, xDen, muDen*muDen));
1335  }
1336 
1337  // Use rescaled PDFs in the presence of multiparton interactions
1338  } else {
1339  if (side == 1) {
1340  if (forSudakov)
1341  pdfNum = mother->beamA.xfISR(0, flavNum, xNum, muNum*muNum);
1342  else pdfNum = beamA.xfISR(0, flavNum, xNum, muNum*muNum);
1343  pdfDen = max(1e-10, beamA.xfISR(0, flavDen, xDen, muDen*muDen));
1344  } else {
1345  if (forSudakov)
1346  pdfNum = mother->beamB.xfISR(0, flavNum, xNum, muNum*muNum);
1347  else pdfNum = beamB.xfISR(0, flavNum, xNum, muNum*muNum);
1348  pdfDen = max(1e-10,beamB.xfISR(0, flavDen, xDen, muDen*muDen));
1349  }
1350  }
1351 
1352  // Cut out charm threshold.
1353  if ( forSudakov && abs(flavNum) ==4 && abs(flavDen) == 4 && muDen == muNum
1354  && muNum < particleDataPtr->m0(4))
1355  pdfDen = pdfNum = 1.0;
1356 
1357  // Return ratio of pdfs
1358  if ( pdfNum > 1e-15 && pdfDen > 1e-10 ) {
1359  pdfRatio *= pdfNum / pdfDen;
1360  } else if ( pdfNum < pdfDen ) {
1361  pdfRatio = 0.;
1362  } else if ( pdfNum > pdfDen ) {
1363  pdfRatio = 1.;
1364  }
1365 
1366  // Done
1367  return pdfRatio;
1368 
1369 }
1370 
1371 //--------------------------------------------------------------------------
1372 
1373 // Methods used for only one path of history nodes.
1374 
1375 // Function to set all scales in the sequence of states. This is a
1376 // wrapper routine for setScales and setEventScales methods
1377 
1378 void DireHistory::setScalesInHistory() {
1379  // Find correct links from n+1 to n states (mother --> child), as
1380  // needed for enforcing ordered scale sequences
1381  vector<int> ident;
1382  findPath(ident);
1383 
1384  // Set production scales in the states to the scales pythia would
1385  // have set and enforce ordering
1386  setScales(ident,true);
1387 
1388  // Set the overall event scales to the scale of the last branching
1389  setEventScales();
1390 
1391 }
1392 
1393 //--------------------------------------------------------------------------
1394 
1395 // Function to find the index (in the mother histories) of the
1396 // child history, thus providing a way access the path from both
1397 // initial history (mother == 0) and final history (all children == 0)
1398 // IN vector<int> : The index of each child in the children vector
1399 // of the current history node will be saved in
1400 // this vector
1401 // NO OUTPUT
1402 
1403 void DireHistory::findPath(vector<int>& out) {
1404 
1405  // If the initial and final nodes are identical, return
1406  if (!mother && int(children.size()) < 1) return;
1407 
1408  // Find the child by checking the children vector for the perfomed
1409  // clustering
1410  int iChild=-1;
1411  if ( mother ) {
1412  int size = int(mother->children.size());
1413  // Loop through children and identify child chosen
1414  for ( int i=0; i < size; ++i) {
1415  if ( mother->children[i]->scale == scale
1416  && mother->children[i]->prodOfProbs == prodOfProbs
1417  && equalClustering(mother->children[i]->clusterIn,clusterIn)) {
1418  iChild = i;
1419  break;
1420  }
1421  }
1422  // Save the index of the child in the children vector and recurse
1423  if (iChild >-1)
1424  out.push_back(iChild);
1425  mother->findPath(out);
1426  }
1427 }
1428 
1429 //--------------------------------------------------------------------------
1430 
1431 // Functions to set the parton production scales and enforce
1432 // ordering on the scales of the respective clusterings stored in
1433 // the History node:
1434 // Method will start from lowest multiplicity state and move to
1435 // higher states, setting the production scales the shower would
1436 // have used.
1437 // When arriving at the highest multiplicity, the method will switch
1438 // and go back in direction of lower states to check and enforce
1439 // ordering for unordered histories.
1440 // IN vector<int> : Vector of positions of the chosen child
1441 // in the mother history to allow to move
1442 // in direction initial->final along path
1443 // bool : True: Move in direction low->high
1444 // multiplicity and set production scales
1445 // False: Move in direction high->low
1446 // multiplicity and check and enforce
1447 // ordering
1448 // NO OUTPUT
1449 
1450 void DireHistory::setScales( vector<int> index, bool forward) {
1451 
1452  // Scale setting less conventional for MOPS --> separate code.
1453 
1454  // CKKW-L scale setting.
1455  if ( !infoPtr->settingsPtr->flag("Dire:doMOPS")) {
1456  // First, set the scales of the hard process to the kinematial
1457  // limit (=s)
1458  if ( children.empty() && forward ) {
1459  // New "incomplete" configurations showered from mu
1460  if (!mother) {
1461  double scaleNew = 1.;
1462  if (mergingHooksPtr->incompleteScalePrescip()==0) {
1463  scaleNew = mergingHooksPtr->muF();
1464  } else if (mergingHooksPtr->incompleteScalePrescip()==1) {
1465  Vec4 pOut;
1466  pOut.p(0.,0.,0.,0.);
1467  for(int i=0; i<int(state.size()); ++i)
1468  if (state[i].isFinal())
1469  pOut += state[i].p();
1470  scaleNew = pOut.mCalc();
1471  } else if (mergingHooksPtr->incompleteScalePrescip()==2) {
1472  scaleNew = state[0].e();
1473  }
1474 
1475  scaleNew = max( mergingHooksPtr->pTcut(), scaleNew);
1476 
1477  state.scale(scaleNew);
1478  for(int i=3; i < int(state.size());++i)
1479  if (state[i].colType() != 0)
1480  state[i].scale(scaleNew);
1481  } else {
1482  // 2->2 with non-parton particles showered from eCM
1483  state.scale( state[0].e() );
1484  // Count final partons
1485  bool isLEP = ( state[3].isLepton() && state[4].isLepton() );
1486  int nFinal = 0;
1487  int nFinalPartons = 0;
1488  int nFinalPhotons = 0;
1489  for ( int i=0; i < int(state.size()); ++i ) {
1490  if ( state[i].isFinal() ) {
1491  nFinal++;
1492  if ( state[i].colType() != 0 ) nFinalPartons++;
1493  if ( state[i].id() == 22 ) nFinalPhotons++;
1494  }
1495  }
1496  bool isQCD = ( nFinal == 2 && nFinal == nFinalPartons );
1497  bool isPPh = ( nFinal == 2 && nFinalPartons == 1 && nFinalPhotons == 1);
1498  // If 2->2, purely partonic, set event scale to kinematic pT
1499  if ( !isLEP && ( isQCD || isPPh ) ) {
1500  double scaleNew = hardFacScale(state);
1501  state.scale( scaleNew );
1502  }
1503 
1504  // For DIS, set the hard process scale to Q2.
1505  if ( ( isDIS2to2(state) || isMassless2to2(state) )
1506  && ( mergingHooksPtr->getProcessString().compare("e+p>e+j") == 0
1507  || mergingHooksPtr->getProcessString().compare("e-p>e-j") == 0) )
1508  state.scale( hardFacScale(state) );
1509 
1510  }
1511  }
1512  // Set all particle production scales, starting from lowest
1513  // multiplicity (final) state
1514  if (mother && forward) {
1515  // When choosing splitting scale, beware of unordered splittings:
1516  double scaleNew = 1.;
1517  if ( mergingHooksPtr->unorderedScalePrescip() == 0) {
1518  // Use larger scale as common splitting scale for mother and child
1519  scaleNew = max( mergingHooksPtr->pTcut(), max(scale,mother->scale));
1520  } else if ( mergingHooksPtr->unorderedScalePrescip() == 1) {
1521  // Use smaller scale as common splitting scale for mother and child
1522  if (scale < mother->scale)
1523  scaleNew = max( mergingHooksPtr->pTcut(), min(scale,mother->scale));
1524  else
1525  scaleNew = max( mergingHooksPtr->pTcut(), max(scale,mother->scale));
1526  }
1527 
1528  // Rescale the mother state partons to the clustering scales
1529  // that have been found along the path
1530  mother->state[clusterIn.emtPos()].scale(scaleNew);
1531  mother->state[clusterIn.radPos()].scale(scaleNew);
1532  mother->state[clusterIn.recPos()].scale(scaleNew);
1533 
1534  // Find unchanged copies of partons in higher multiplicity states
1535  // and rescale those
1536  mother->scaleCopies(clusterIn.emtPos(), mother->state, scaleNew);
1537  mother->scaleCopies(clusterIn.radPos(), mother->state, scaleNew);
1538  mother->scaleCopies(clusterIn.recPos(), mother->state, scaleNew);
1539 
1540  // Recurse
1541  mother->setScales(index,true);
1542  }
1543 
1544  // Now, check and correct ordering from the highest multiplicity
1545  // state backwards to all the clustered states
1546  if (!mother || !forward) {
1547  // Get index of child along the path
1548  int iChild = -1;
1549  if ( int(index.size()) > 0 ) {
1550  iChild = index.back();
1551  index.pop_back();
1552  }
1553 
1554  // Check that the reclustered scale is above the shower cut
1555  if (mother) {
1556  scale = max(mergingHooksPtr->pTcut(), scale);
1557  }
1558  // If this is NOT the 2->2 process, check and enforce ordering
1559  if (iChild != -1 && !children.empty()) {
1560  if (scale > children[iChild]->scale ) {
1561 
1562  if ( mergingHooksPtr->unorderedScalePrescip() == 0) {
1563  // Use larger scale as common splitting scale for mother and child
1564  double scaleNew = max( mergingHooksPtr->pTcut(),
1565  max(scale,children[iChild]->scale));
1566  // Enforce ordering in particle production scales
1567  for( int i = 0; i < int(children[iChild]->state.size()); ++i)
1568  if (children[iChild]->state[i].scale() == children[iChild]->scale)
1569  children[iChild]->state[i].scale(scaleNew);
1570  // Enforce ordering in saved clustering scale
1571  children[iChild]->scale = scaleNew;
1572 
1573  } else if ( mergingHooksPtr->unorderedScalePrescip() == 1) {
1574  // Use smaller scale as common splitting scale for mother & child
1575  double scaleNew = max(mergingHooksPtr->pTcut(),
1576  min(scale,children[iChild]->scale));
1577  // Enforce ordering in particle production scales
1578  for( int i = 0; i < int(state.size()); ++i)
1579  if (state[i].scale() == scale)
1580  state[i].scale(scaleNew);
1581  // Enforce ordering in saved clustering scale
1582  scale = scaleNew;
1583  }
1584 
1585  // Just set the overall event scale to the minimal scale
1586  } else {
1587 
1588  double scalemin = state[0].e();
1589  for( int i = 0; i < int(state.size()); ++i)
1590  if (state[i].colType() != 0)
1591  scalemin = max(mergingHooksPtr->pTcut(),
1592  min(scalemin,state[i].scale()));
1593  state.scale(scalemin);
1594  scale = max(mergingHooksPtr->pTcut(), scale);
1595  }
1596  //Recurse
1597  children[iChild]->setScales(index, false);
1598  }
1599  }
1600 
1601  // Done with CKKW-L scale setting.
1602  // MOPS scale setting.
1603  } else {
1604 
1605  // First, set the scales of the hard process to the kinematial
1606  // limit (=s)
1607  if ( children.empty() && forward ) {
1608  // New "incomplete" configurations showered from mu
1609  if (!mother) {
1610  double scaleNew = 1.;
1611  if (mergingHooksPtr->incompleteScalePrescip()==0) {
1612  scaleNew = mergingHooksPtr->muF();
1613  } else if (mergingHooksPtr->incompleteScalePrescip()==1) {
1614  Vec4 pOut;
1615  pOut.p(0.,0.,0.,0.);
1616  for(int i=0; i<int(state.size()); ++i)
1617  if (state[i].isFinal())
1618  pOut += state[i].p();
1619  scaleNew = pOut.mCalc();
1620  } else if (mergingHooksPtr->incompleteScalePrescip()==2) {
1621  scaleNew = state[0].e();
1622  }
1623 
1624  scaleNew = max( mergingHooksPtr->pTcut(), scaleNew);
1625 
1626  state.scale(scaleNew);
1627  for(int i=3; i < int(state.size());++i)
1628  if (state[i].colType() != 0)
1629  state[i].scale(scaleNew);
1630  } else {
1631  // 2->2 with non-parton particles showered from eCM
1632  state.scale( state[0].e() );
1633  // Count final partons
1634  bool isLEP = ( state[3].isLepton() && state[4].isLepton() );
1635  int nFinal = 0;
1636  int nFinalPartons = 0;
1637  int nFinalPhotons = 0;
1638  for ( int i=0; i < int(state.size()); ++i ) {
1639  if ( state[i].isFinal() ) {
1640  nFinal++;
1641  if ( state[i].colType() != 0 ) nFinalPartons++;
1642  if ( state[i].id() == 22 ) nFinalPhotons++;
1643  }
1644  }
1645  bool isQCD = ( nFinal == 2 && nFinal == nFinalPartons );
1646  bool isPPh = ( nFinal == 2 && nFinalPartons == 1 && nFinalPhotons == 1);
1647  // If 2->2, purely partonic, set event scale to kinematic pT
1648  if ( !isLEP && ( isQCD || isPPh ) ) {
1649  double scaleNew = hardFacScale(state);
1650  state.scale( scaleNew );
1651  }
1652 
1653  // For DIS, set the hard process scale to Q2.
1654  if ( ( isDIS2to2(state) || isMassless2to2(state) )
1655  && ( mergingHooksPtr->getProcessString().compare("e+p>e+j") == 0
1656  || mergingHooksPtr->getProcessString().compare("e-p>e-j") == 0) )
1657  state.scale( hardFacScale(state) );
1658 
1659  double hardScale = hardStartScale(state);
1660  state.scale(hardScale);
1661 
1662 
1663  }
1664  }
1665 
1666  // Set all particle production scales, starting from lowest
1667  // multiplicity (final) state
1668  if (mother && forward) {
1669  double scaleNew = (scaleEffective > 0.) ? scaleEffective : scale;
1670  scale = max(mergingHooksPtr->pTcut(), scaleNew);
1671 
1672  double scaleProduction = max( mergingHooksPtr->pTcut(),
1673  mother->scaleEffective);
1674  scaleProduction = max(scaleProduction,scaleNew);
1675 
1676  // Rescale the mother state partons to the clustering scales
1677  // that have been found along the path
1678  mother->state[clusterIn.emtPos()].scale(scaleProduction);
1679  mother->state[clusterIn.radPos()].scale(scaleProduction);
1680  mother->state[clusterIn.recPos()].scale(scaleProduction);
1681 
1682  // Find unchanged copies of partons in higher multiplicity states
1683  // and rescale those
1684  mother->scaleCopies(clusterIn.emtPos(), mother->state, scaleProduction);
1685  mother->scaleCopies(clusterIn.radPos(), mother->state, scaleProduction);
1686  mother->scaleCopies(clusterIn.recPos(), mother->state, scaleProduction);
1687 
1688  // Recurse
1689  mother->setScales(index,true);
1690  }
1691 
1692  // Now, check and correct ordering from the highest multiplicity
1693  // state backwards to all the clustered states
1694  if (!mother || !forward) {
1695 
1696  // Get index of child along the path
1697  int iChild = -1;
1698  if ( int(index.size()) > 0 ) {
1699  iChild = index.back();
1700  index.pop_back();
1701  }
1702 
1703  // Check that the reclustered scale is above the shower cut
1704  if (mother) {
1705  scale = max(mergingHooksPtr->pTcut(), scale);
1706  if (infoPtr->settingsPtr->flag("Dire:doMOPS"))
1707  scale = max(scale,mother->scaleEffective);
1708  }
1709  // If this is NOT the 2->2 process, check and enforce ordering
1710  if (iChild != -1 && !children.empty()) {
1711  if (scale > children[iChild]->scale ) {
1712 
1713  double scaleNew = max( mergingHooksPtr->pTcut(),
1714  max(children[iChild]->scale, scaleEffective));
1715  if (mother) scaleNew = max(scaleNew, mother->scaleEffective);
1716 
1717  // Enforce ordering in particle production scales
1718  for( int i = 0; i < int(children[iChild]->state.size()); ++i) {
1719  if (children[iChild]->state[i].scale() == children[iChild]->scale)
1720  children[iChild]->state[i].scale(scaleNew);
1721  }
1722  // Enforce ordering in saved clustering scale
1723  children[iChild]->scale = scaleNew;
1724 
1725  } else {
1726  double scalemin = state[0].e();
1727  for( int i = 0; i < int(state.size()); ++i)
1728  if (state[i].colType() != 0)
1729  scalemin = max(mergingHooksPtr->pTcut(),
1730  min(scalemin,state[i].scale()));
1731  state.scale(scalemin);
1732  scale = max(mergingHooksPtr->pTcut(), scale);
1733  }
1734  //Recurse
1735  children[iChild]->setScales(index, false);
1736  }
1737  }
1738 
1739  // Done with MOPS scale setting.
1740  }
1741 
1742 
1743 }
1744 
1745 //--------------------------------------------------------------------------
1746 
1747 // Function to find a particle in all higher multiplicity events
1748 // along the history path and set its production scale to the input
1749 // scale
1750 // IN int iPart : Parton in refEvent to be checked / rescaled
1751 // Event& refEvent : Reference event for iPart
1752 // double scale : Scale to be set as production scale for
1753 // unchanged copies of iPart in subsequent steps
1754 
1755 void DireHistory::scaleCopies(int iPart, const Event& refEvent, double rho) {
1756 
1757  // Check if any parton recently rescaled is found unchanged:
1758  // Same charge, colours in mother->state
1759  if ( mother ) {
1760  for( int i=0; i < mother->state.size(); ++i) {
1761  if ( ( mother->state[i].id() == refEvent[iPart].id()
1762  && mother->state[i].colType() == refEvent[iPart].colType()
1763  && mother->state[i].chargeType() == refEvent[iPart].chargeType()
1764  && mother->state[i].col() == refEvent[iPart].col()
1765  && mother->state[i].acol() == refEvent[iPart].acol() )
1766  ) {
1767  // Rescale the unchanged parton
1768  mother->state[i].scale(rho);
1769  // Recurse
1770  if (mother->mother)
1771  mother->scaleCopies( iPart, refEvent, rho );
1772  } // end if found unchanged parton case
1773  } // end loop over particle entries in event
1774  }
1775 }
1776 
1777 //--------------------------------------------------------------------------
1778 
1779 // Functions to set the OVERALL EVENT SCALES [=state.scale()] to
1780 // the scale of the last clustering
1781 // NO INPUT
1782 // NO OUTPUT
1783 
1784 void DireHistory::setEventScales() {
1785  // Set the event scale to the scale of the last clustering,
1786  // except for the very lowest multiplicity state
1787  if (mother) {
1788  mother->state.scale(scale);
1789  // Recurse
1790  mother->setEventScales();
1791  }
1792 }
1793 
1794 //--------------------------------------------------------------------------
1795 
1796 // Function to return the depth of the history (i.e. the number of
1797 // reclustered splittings)
1798 // NO INPUT
1799 // OUTPUT int : Depth of history
1800 
1801 int DireHistory::nClusterings() {
1802  if (!mother) return 0;
1803  int w = mother->nClusterings();
1804  w += 1;
1805  return w;
1806 }
1807 
1808 //--------------------------------------------------------------------------
1809 
1810 // Functions to return the event after nSteps splittings of the 2->2 process
1811 // Example: nSteps = 1 -> return event with one additional parton
1812 // INPUT int : Number of splittings in the event,
1813 // as counted from core 2->2 process
1814 // OUTPUT Event : event with nSteps additional partons
1815 
1816 Event DireHistory::clusteredState(int nSteps) {
1817 
1818  // Save state
1819  Event outState = state;
1820  // As long as there are steps to do, recursively save state
1821  if (mother && nSteps > 0)
1822  outState = mother->clusteredState(nSteps - 1);
1823  // Done
1824  return outState;
1825 
1826 }
1827 
1828 //--------------------------------------------------------------------------
1829 
1830 // Function to choose a path from all paths in the tree
1831 // according to their splitting probabilities
1832 // IN double : Random number
1833 // OUT DireHistory* : Leaf of history path chosen
1834 
1835 DireHistory * DireHistory::select(double rnd) {
1836 
1837  // No need to choose if no paths have been constructed.
1838  if ( goodBranches.empty() && badBranches.empty() ) return this;
1839 
1840  // Choose amongst paths allowed by projections.
1841  double sum = 0.;
1842  map<double, DireHistory*> selectFrom;
1843  if ( !goodBranches.empty() ) {
1844  selectFrom = goodBranches;
1845  sum = sumGoodBranches;
1846  } else {
1847  selectFrom = badBranches;
1848  sum = sumBadBranches;
1849  }
1850 
1851  // Choose history according to probability, be careful about upper bound
1852  if ( rnd != 1. ) {
1853  return selectFrom.upper_bound(sum*rnd)->second;
1854  } else {
1855  return selectFrom.lower_bound(sum*rnd)->second;
1856  }
1857 
1858  // Done
1859 }
1860 
1861 //--------------------------------------------------------------------------
1862 
1863 // Function to project paths onto desired paths.
1864 
1865 bool DireHistory::trimHistories() {
1866  // Do nothing if no paths have been constructed.
1867  if ( paths.empty() ) return false;
1868  // Loop through all constructed paths. Check all removal conditions.
1869  for ( map<double, DireHistory*>::iterator it = paths.begin();
1870  it != paths.end(); ++it ) {
1871  // Check if history is allowed.
1872  if ( it->second->keep() && !it->second->keepHistory() )
1873  it->second->remove();
1874  }
1875 
1876  // Project onto desired / undesired branches.
1877  double sumold(0.), sumnew(0.), mismatch(0.);
1878  // Loop through all constructed paths and store allowed paths.
1879  // Skip undesired paths.
1880  for ( map<double, DireHistory*>::iterator it = paths.begin();
1881  it != paths.end(); ++it ) {
1882  // Update index
1883  sumnew = it->second->prodOfProbs;
1884  if ( it->second->keep() ) {
1885  // Fill branches with allowed paths.
1886  goodBranches.insert( make_pair( sumnew - mismatch, it->second) );
1887  // Add probability of this path.
1888  sumGoodBranches = sumnew - mismatch;
1889  } else {
1890  // Update mismatch in probabilities resulting from not including this
1891  // path
1892  double mismatchOld = mismatch;
1893  mismatch += sumnew - sumold;
1894  // Fill branches with allowed paths.
1895  badBranches.insert( make_pair( mismatchOld + sumnew - sumold,
1896  it->second ) );
1897  // Add probability of this path.
1898  sumBadBranches = mismatchOld + sumnew - sumold;
1899  }
1900  // remember index of this path in order to caclulate probability of
1901  // subsequent path.
1902  sumold = it->second->prodOfProbs;
1903  }
1904 
1905  // Done
1906  return !goodBranches.empty();
1907 }
1908 
1909 //--------------------------------------------------------------------------
1910 
1911 // Function implementing checks on a paths, deciding if the path is valid.
1912 
1913 bool DireHistory::keepHistory() {
1914  bool keepPath = true;
1915 
1916  double hardScale = hardStartScale(state);
1917 
1918  // Tag unordered paths for removal.
1919  if ( mergingHooksPtr->getProcessString().compare("pp>jj") == 0
1920  || mergingHooksPtr->getProcessString().compare("pp>aj") == 0
1921  || isQCD2to2(state) ) {
1922  // Tag unordered paths for removal. Include scale of hard 2->2 process
1923  // into the ordering definition.
1924  hardScale = hardStartScale(state);
1925  }
1926 
1927  // Set starting scale to mass of Drell-Yan for 2->1.
1928  if (isEW2to1(state)) {
1929  Vec4 pSum(0,0,0,0);
1930  for (int i = 0;i < state.size(); ++i)
1931  if (state[i].isFinal()) pSum += state[i].p();
1932  hardScale = pSum.mCalc();
1933  }
1934 
1935  // For DIS, set the hard process scale to Q2.
1936  if ( mergingHooksPtr->getProcessString().compare("e+p>e+j") == 0
1937  || mergingHooksPtr->getProcessString().compare("e-p>e-j") == 0 ) {
1938  // Tag unordered paths for removal. Include scale of hard 2->2 process
1939  // into the ordering definition.
1940  hardScale = hardFacScale(state);
1941  }
1942 
1943  keepPath = isOrderedPath( hardScale );
1944 
1945  if ( !mergingHooksPtr->orderHistories() ) keepPath = true;
1946 
1947  //Done
1948  return keepPath;
1949 }
1950 
1951 //--------------------------------------------------------------------------
1952 
1953 // Function to check if a path is ordered in evolution pT.
1954 
1955 bool DireHistory::isOrderedPath( double maxscale ) {
1956  double newscale = clusterIn.pT();
1957  if ( !mother ) return true;
1958  bool ordered = mother->isOrderedPath(newscale);
1959  if ( !ordered || maxscale < newscale) return false;
1960  return ordered;
1961 }
1962 
1963 //--------------------------------------------------------------------------
1964 
1965 // Function to check if all reconstucted states in a path pass the merging
1966 // scale cut.
1967 
1968 bool DireHistory::allIntermediateAboveRhoMS( double rhoms, bool good ) {
1969  // If one state below the merging scale has already been found, no need to
1970  // check further.
1971  if ( !good ) return false;
1972  // Check merging scale for states with more than 0 jets
1973  int nFinal = 0;
1974  for ( int i = 0; i < state.size(); ++i )
1975  if ( state[i].isFinal() && state[i].colType() != 0 )
1976  nFinal++;
1977  double rhoNew = (nFinal > 0 ) ? mergingHooksPtr->tmsNow( state )
1978  : state[0].e();
1979  // Assume state from ME generator passes merging scale cut.
1980  if ( !mother ) return good;
1981  // Recurse.
1982  return mother->allIntermediateAboveRhoMS( rhoms, (rhoNew > rhoms) );
1983 }
1984 
1985 //--------------------------------------------------------------------------
1986 
1987 // Function to check if any ordered paths were found (and kept).
1988 
1989 bool DireHistory::foundAnyOrderedPaths() {
1990  // Do nothing if no paths were found
1991  if ( paths.empty() ) return false;
1992  double maxscale = hardStartScale(state);
1993  // Loop through paths. Divide probability into ordered and unordered pieces.
1994  for ( map<double, DireHistory*>::iterator it = paths.begin();
1995  it != paths.end(); ++it )
1996  if ( it->second->isOrderedPath(maxscale) )
1997  return true;
1998  // Done
1999  return false;
2000 }
2001 
2002 //--------------------------------------------------------------------------
2003 
2004 // Function to check if a path contains any clustering scales below the
2005 // shower cut-off.
2006 
2007 bool DireHistory::hasScalesAboveCutoff() {
2008  if ( !mother ) return true;
2009  return ( clusterIn.pT() > mergingHooksPtr->pTcut()
2010  && mother->hasScalesAboveCutoff() );
2011 }
2012 
2013 //--------------------------------------------------------------------------
2014 
2015 // For a full path, find the weight calculated from the ratio of
2016 // couplings, the no-emission probabilities, and possible PDF
2017 // ratios. This function should only be called for the last history
2018 // node of a full path.
2019 // IN TimeShower : Already initialised shower object to be used as
2020 // trial shower
2021 // double : alpha_s value used in ME calculation
2022 // double : Maximal mass scale of the problem (e.g. E_CM)
2023 // AlphaStrong: Initialised shower alpha_s object for FSR
2024 // alpha_s ratio calculation
2025 // AlphaStrong: Initialised shower alpha_s object for ISR
2026 // alpha_s ratio calculation (can be different from previous)
2027 
2028 double DireHistory::weight(PartonLevel* trial, double as0, double aem0,
2029  double maxscale, double pdfScale, AlphaStrong * asFSR, AlphaStrong * asISR,
2030  AlphaEM * aemFSR, AlphaEM * aemISR, double& asWeight, double& aemWeight,
2031  double& pdfWeight) {
2032 
2033  // Use correct scale
2034  double newScale = scale;
2035 
2036  // For ME state, just multiply by PDF ratios
2037  if ( !mother ) {
2038 
2039  int sideRad = (state[3].pz() > 0) ? 1 :-1;
2040  int sideRec = (state[4].pz() > 0) ? 1 :-1;
2041 
2042  // Calculate PDF first leg
2043  if (state[3].colType() != 0) {
2044  // Find x value and flavour
2045  double x = 2.*state[3].e() / state[0].e();
2046  int flav = state[3].id();
2047  // Find numerator/denominator scale
2048  double scaleNum = (children.empty()) ? hardFacScale(state) : maxscale;
2049  double scaleDen = mergingHooksPtr->muFinME();
2050  // For initial parton, multiply by PDF ratio
2051  double ratio = getPDFratio(sideRad, false, false, flav, x, scaleNum,
2052  flav, x, scaleDen);
2053  pdfWeight *= ratio;
2054  }
2055 
2056  // Calculate PDF ratio for second leg
2057  if (state[4].colType() != 0) {
2058  // Find x value and flavour
2059  double x = 2.*state[4].e() / state[0].e();
2060  int flav = state[4].id();
2061  // Find numerator/denominator scale
2062  double scaleNum = (children.empty()) ? hardFacScale(state) : maxscale;
2063  double scaleDen = mergingHooksPtr->muFinME();
2064  // For initial parton, multiply with PDF ratio
2065  double ratio = getPDFratio(sideRec, false, false, flav, x, scaleNum,
2066  flav, x, scaleDen);
2067  pdfWeight *= ratio;
2068  }
2069 
2070  return 1.0;
2071  }
2072 
2073  // Remember new PDF scale n case true scale should be used for un-ordered
2074  // splittings.
2075  double newPDFscale = newScale;
2076  if ( !infoPtr->settingsPtr->flag("Dire:doMOPS")
2077  && mergingHooksPtr->unorderedPDFscalePrescip() == 1)
2078  newPDFscale = clusterIn.pT();
2079 
2080  // Recurse
2081  double w = mother->weight(trial, as0, aem0, newScale, newPDFscale,
2082  asFSR, asISR, aemFSR, aemISR, asWeight, aemWeight, pdfWeight);
2083 
2084  // Do nothing for empty state
2085  if (state.size() < 3) return 1.0;
2086  // If up to now, trial shower was not successful, return zero
2087  // Do trial shower on current state, return zero if not successful
2088  w *= doTrialShower(trial, 1, maxscale).front();
2089 
2090  int emtType = mother->state[clusterIn.emtPos()].colType();
2091  bool isQCD = emtType != 0;
2092  bool isQED = emtType == 0;
2093 
2094  pair<int,double> coup = getCoupling(mother->state, clusterIn.emittor,
2095  clusterIn.emtPos(), clusterIn.recoiler, clusterIn.name());
2096 
2097  if (coup.first > 0) {
2098  isQCD = isQED = false;
2099  if (coup.first == 1)
2100  asWeight *= coup.second * 2.*M_PI / as0;
2101  if (coup.first == 2 || coup.first == 3)
2102  aemWeight *= coup.second * 2.*M_PI / aem0;
2103  }
2104 
2105  // Calculate alpha_s ratio for current state.
2106  if ( asFSR && asISR && isQCD) {
2107  double asScale = pow2( newScale );
2108  if ( !infoPtr->settingsPtr->flag("Dire:doMOPS")
2109  && mergingHooksPtr->unorderedASscalePrescip() == 1)
2110  asScale = pow2( clusterIn.pT() );
2111 
2112  // Add regularisation scale to initial state alpha_s.
2113  bool FSR = mother->state[clusterIn.emittor].isFinal();
2114  if (!FSR) asScale += pow2(mergingHooksPtr->pT0ISR());
2115 
2116  // Directly get argument of running alpha_s from shower plugin.
2117  asScale = getShowerPluginScale(mother->state, clusterIn.emittor,
2118  clusterIn.emtPos(), clusterIn.recoiler, clusterIn.name(),
2119  "scaleAS", asScale);
2120 
2121  if (infoPtr->settingsPtr->flag("Dire:doMOPS"))
2122  asScale = pow2(newScale);
2123 
2124  double alphaSinPS = (FSR) ? (*asFSR).alphaS(asScale)
2125  : (*asISR).alphaS(asScale);
2126  asWeight *= alphaSinPS / as0;
2127  }
2128 
2129  // Calculate alpha_em ratio for current state.
2130  if ( aemFSR && aemISR && isQED ) {
2131  double aemScale = pow2( newScale );
2132  if ( !infoPtr->settingsPtr->flag("Dire:doMOPS")
2133  && mergingHooksPtr->unorderedASscalePrescip() == 1)
2134  aemScale = pow2( clusterIn.pT() );
2135 
2136  // Add regularisation scale to initial state alpha_s.
2137  bool FSR = mother->state[clusterIn.emittor].isFinal();
2138  if (!FSR) aemScale += pow2(mergingHooksPtr->pT0ISR());
2139 
2140  // Directly get argument of running alpha_em from shower plugin.
2141  aemScale = getShowerPluginScale(mother->state, clusterIn.emittor,
2142  clusterIn.emtPos(), clusterIn.recoiler, clusterIn.name(),
2143  "scaleEM", aemScale);
2144 
2145  double alphaEMinPS = (FSR) ? (*aemFSR).alphaEM(aemScale)
2146  : (*aemISR).alphaEM(aemScale);
2147  aemWeight *= alphaEMinPS / aem0;
2148  }
2149 
2150  // Calculate pdf ratios: Get both sides of event
2151  int inP = 3;
2152  int inM = 4;
2153  int sideP = (mother->state[inP].pz() > 0) ? 1 :-1;
2154  int sideM = (mother->state[inM].pz() > 0) ? 1 :-1;
2155 
2156  if ( mother->state[inP].colType() != 0 ) {
2157  // Find x value and flavour
2158  double x = getCurrentX(sideP);
2159  int flav = getCurrentFlav(sideP);
2160  // Find numerator scale
2161  double scaleNum = (children.empty())
2162  ? hardFacScale(state)
2163  : ( (!infoPtr->settingsPtr->flag("Dire:doMOPS")
2164  && mergingHooksPtr->unorderedPDFscalePrescip() == 1)
2165  ? pdfScale : maxscale );
2166  double scaleDen = ( !infoPtr->settingsPtr->flag("Dire:doMOPS")
2167  && mergingHooksPtr->unorderedPDFscalePrescip() == 1)
2168  ? clusterIn.pT() : newScale;
2169  // Multiply PDF ratio
2170  double ratio = getPDFratio(sideP, false, false, flav, x, scaleNum,
2171  flav, x, scaleDen);
2172 
2173  pdfWeight *= ratio;
2174  }
2175 
2176  if ( mother->state[inM].colType() != 0 ) {
2177  // Find x value and flavour
2178  double x = getCurrentX(sideM);
2179  int flav = getCurrentFlav(sideM);
2180  // Find numerator scale
2181  double scaleNum = (children.empty())
2182  ? hardFacScale(state)
2183  : ( (!infoPtr->settingsPtr->flag("Dire:doMOPS")
2184  && mergingHooksPtr->unorderedPDFscalePrescip() == 1)
2185  ? pdfScale : maxscale );
2186  double scaleDen = ( !infoPtr->settingsPtr->flag("Dire:doMOPS")
2187  && mergingHooksPtr->unorderedPDFscalePrescip() == 1)
2188  ? clusterIn.pT() : newScale;
2189  // Multiply PDF ratio
2190  double ratio = getPDFratio(sideM, false, false, flav, x, scaleNum,
2191  flav, x, scaleDen);
2192 
2193  pdfWeight *= ratio;
2194  }
2195 
2196  // Done
2197  return w;
2198 }
2199 
2200 //--------------------------------------------------------------------------
2201 
2202 // Function to return the \alpha_s-ratio part of the CKKWL weight of a path.
2203 
2204 double DireHistory::weightALPHAS( double as0, AlphaStrong * asFSR,
2205  AlphaStrong * asISR, int njetMin, int njetMax ) {
2206 
2207  // For ME state, do nothing.
2208  if ( !mother ) return 1.;
2209  // Recurse
2210  double w = mother->weightALPHAS( as0, asFSR, asISR, njetMin, njetMax );
2211  // Do nothing for empty state
2212  if (state.size() < 3) return w;
2213 
2214  // If this node has too many jets, no not calculate no-emission probability.
2215  int njetNow = mergingHooksPtr->getNumberOfClusteringSteps( state) ;
2216  if (njetNow >= njetMax) return 1.0;
2217 
2218  // Store variables for easy use.
2219  bool FSR = mother->state[clusterIn.emittor].isFinal();
2220  int emtID = mother->state[clusterIn.emtPos()].id();
2221 
2222  // Do not correct alphaS if it is an EW emission.
2223  if (abs(emtID) == 22 || abs(emtID) == 23 || abs(emtID) == 24) return w;
2224 
2225  if (njetNow < njetMin ) w *= 1.0;
2226  else {
2227  // Calculate alpha_s ratio for current state
2228  if ( asFSR && asISR ) {
2229  double asScale = pow2( scale );
2230  if (!infoPtr->settingsPtr->flag("Dire:doMOPS")
2231  && mergingHooksPtr->unorderedASscalePrescip() == 1)
2232  asScale = pow2( clusterIn.pT() );
2233 
2234  // Add regularisation scale to initial state alpha_s.
2235  if (!FSR) asScale += pow2(mergingHooksPtr->pT0ISR());
2236 
2237  // Directly get argument of running alpha_s from shower plugin.
2238  asScale = getShowerPluginScale(mother->state, clusterIn.emittor,
2239  clusterIn.emtPos(), clusterIn.recoiler, clusterIn.name(),
2240  "scaleAS", asScale);
2241 
2242  double alphaSinPS = (FSR) ? (*asFSR).alphaS(asScale)
2243  : (*asISR).alphaS(asScale);
2244  w *= alphaSinPS / as0;
2245  }
2246  }
2247 
2248  // Done
2249  return w;
2250 }
2251 
2252 //--------------------------------------------------------------------------
2253 
2254 // Function to return the \alpha_s-ratio part of the CKKWL weight of a path.
2255 
2256 vector<double> DireHistory::weightCouplings() {
2257 
2258  // For ME state, do nothing.
2259  if ( !mother ) return createvector<double>(1.)(1.)(1.);
2260  // Recurse
2261  vector<double> w = mother->weightCouplings();
2262  // Do nothing for empty state
2263  if (state.size() < 3) return w;
2264 
2265  // Get local copies of input system
2266  int rad = clusterIn.radPos();
2267  int rec = clusterIn.recPos();
2268  int emt = clusterIn.emtPos();
2269  string name = clusterIn.name();
2270 
2271  if (!(fsr && isr)) return createvector<double>(1.)(1.)(1.);
2272  bool isFSR = fsr->isTimelike(mother->state, rad, emt, rec, "");
2273  bool isISR = isr->isSpacelike(mother->state, rad, emt, rec, "");
2274  double mu2Ren = pow2(mergingHooksPtr->muR());
2275  double t = pow2(scale);
2276  double renormMultFacFSR
2277  = infoPtr->settingsPtr->parm("TimeShower:renormMultFac");
2278  double renormMultFacISR
2279  = infoPtr->settingsPtr->parm("SpaceShower:renormMultFac");
2280  if (isFSR) t *= renormMultFacFSR;
2281  else if (isISR) t *= renormMultFacISR;
2282 
2283  double couplingOld(1.), couplingNew(1.);
2284  if (isFSR) couplingOld = fsr->getCoupling( mu2Ren, name);
2285  if (isISR) couplingOld = isr->getCoupling( mu2Ren, name);
2286  vector<double> variations(createvector<double>(1.)(0.25)(4.));
2287  for (size_t i=0; i<variations.size(); ++i) {
2288  if (isFSR) couplingNew = fsr->getCoupling( variations[i]*t, name);
2289  if (isISR) couplingNew = fsr->getCoupling( variations[i]*t, name);
2290  w[i] *= couplingNew / couplingOld;
2291  }
2292 
2293  // Done
2294  return w;
2295 }
2296 
2297 //--------------------------------------------------------------------------
2298 
2299 // Function to return the \alpha_s-ratio part of the CKKWL weight of a path.
2300 
2301 vector<double> DireHistory::weightCouplingsDenominator() {
2302 
2303  // For ME state, do nothing.
2304  if ( !mother ) return createvector<double>(1.)(1.)(1.);
2305  // Recurse
2306  vector<double> w = mother->weightCouplingsDenominator();
2307  // Do nothing for empty state
2308  if (state.size() < 3) return w;
2309  // Get local copies of input system
2310  if (!(fsr && isr)) return createvector<double>(1.)(1.)(1.);
2311  for (size_t i=0; i<w.size(); ++i) {
2312  w[i] *= clusterCoupl*2.*M_PI;
2313  }
2314 
2315  // Done
2316  return w;
2317 }
2318 
2319 //--------------------------------------------------------------------------
2320 
2321 // Function to return the \alpha_em-ratio part of the CKKWL weight of a path.
2322 
2323 double DireHistory::weightALPHAEM( double aem0, AlphaEM * aemFSR,
2324  AlphaEM * aemISR, int njetMin, int njetMax ) {
2325 
2326  // For ME state, do nothing.
2327  if ( !mother ) return 1.;
2328  // Recurse
2329  double w = mother->weightALPHAEM( aem0, aemFSR, aemISR, njetMin, njetMax);
2330  // Do nothing for empty state
2331  if (state.size() < 3) return w;
2332 
2333  // If this node has too many jets, no not calculate no-emission probability.
2334  int njetNow = mergingHooksPtr->getNumberOfClusteringSteps( state) ;
2335  if (njetNow >= njetMax) return 1.0;
2336 
2337  // Store variables for easy use.
2338  bool FSR = mother->state[clusterIn.emittor].isFinal();
2339  int emtID = mother->state[clusterIn.emtPos()].id();
2340 
2341  // Do not correct alpha EM if it not an EW emission.
2342  if (!(abs(emtID) == 22 || abs(emtID) == 23 || abs(emtID) == 24)) return w;
2343 
2344  if (njetNow < njetMin ) w *= 1.0;
2345  else {
2346  // Calculate alpha_s ratio for current state
2347  if ( aemFSR && aemISR ) {
2348  double aemScale = pow2( scale );
2349  if (!infoPtr->settingsPtr->flag("Dire:doMOPS")
2350  && mergingHooksPtr->unorderedASscalePrescip() == 1)
2351  aemScale = pow2( clusterIn.pT() );
2352 
2353  // Add regularisation scale to initial state alpha_em.
2354  if (!FSR) aemScale += pow2(mergingHooksPtr->pT0ISR());
2355 
2356  // Directly get argument of running alpha_em from shower plugin.
2357  aemScale = getShowerPluginScale(mother->state, clusterIn.emittor,
2358  clusterIn.emtPos(), clusterIn.recoiler, clusterIn.name(),
2359  "scaleEM", aemScale);
2360 
2361  double alphaEMinPS = (FSR) ? (*aemFSR).alphaEM(aemScale)
2362  : (*aemISR).alphaEM(aemScale);
2363  w *= alphaEMinPS / aem0;
2364  }
2365  }
2366 
2367  // Done
2368  return w;
2369 }
2370 
2371 //--------------------------------------------------------------------------
2372 
2373 // Function to return the PDF-ratio part of the CKKWL weight of a path.
2374 
2375 double DireHistory::weightPDFs( double maxscale, double pdfScale,
2376  int njetMin, int njetMax ) {
2377 
2378  // Use correct scale
2379  double newScale = scale;
2380  int njetNow = mergingHooksPtr->getNumberOfClusteringSteps( state);
2381 
2382  // For ME state, just multiply by PDF ratios
2383  if ( !mother ) {
2384 
2385  // If this node has too many jets, no not calculate PDF ratio.
2386  if (njetMax > -1 && njetNow > njetMax) return 1.0;
2387 
2388  double wt = 1.;
2389  int sideRad = (state[3].pz() > 0) ? 1 :-1;
2390  int sideRec = (state[4].pz() > 0) ? 1 :-1;
2391 
2392  // Calculate PDF first leg
2393  if (state[3].colType() != 0) {
2394  // Find x value and flavour
2395  double x = 2.*state[3].e() / state[0].e();
2396  int flav = state[3].id();
2397  // Find numerator/denominator scale
2398  double scaleNum = (children.empty()) ? hardFacScale(state) : maxscale;
2399  double scaleDen = mergingHooksPtr->muFinME();
2400  // For initial parton, multiply by PDF ratio
2401  if (njetMin > -1 && njetNow >= njetMin ) wt *= getPDFratio(sideRad,
2402  false, false, flav, x, scaleNum, flav, x, scaleDen);
2403  else if (njetMin == -1) wt *= getPDFratio(sideRad,
2404  false, false, flav, x, scaleNum, flav, x, scaleDen);
2405  }
2406 
2407  // Calculate PDF ratio for second leg
2408  if (state[4].colType() != 0) {
2409  // Find x value and flavour
2410  double x = 2.*state[4].e() / state[0].e();
2411  int flav = state[4].id();
2412  // Find numerator/denominator scale
2413  double scaleNum = (children.empty()) ? hardFacScale(state) : maxscale;
2414  double scaleDen = mergingHooksPtr->muFinME();
2415  if (njetMin > -1 && njetNow >= njetMin ) wt *= getPDFratio(sideRec,
2416  false, false, flav, x, scaleNum, flav, x, scaleDen);
2417  else if (njetMin == -1) wt *= getPDFratio(sideRec,
2418  false, false, flav, x, scaleNum, flav, x, scaleDen);
2419  }
2420 
2421  return wt;
2422  }
2423 
2424  // Remember new PDF scale n case true scale should be used for un-ordered
2425  // splittings.
2426  double newPDFscale = newScale;
2427  if ( !infoPtr->settingsPtr->flag("Dire:doMOPS")
2428  && mergingHooksPtr->unorderedPDFscalePrescip() == 1)
2429  newPDFscale = clusterIn.pT();
2430 
2431  // Recurse
2432  double w = mother->weightPDFs( newScale, newPDFscale, njetMin, njetMax);
2433 
2434  // Do nothing for empty state
2435  if (state.size() < 3) return w;
2436 
2437  // Calculate pdf ratios: Get both sides of event
2438  int inP = 3;
2439  int inM = 4;
2440  int sideP = (mother->state[inP].pz() > 0) ? 1 :-1;
2441  int sideM = (mother->state[inM].pz() > 0) ? 1 :-1;
2442 
2443  if ( mother->state[inP].colType() != 0 ) {
2444  // Find x value and flavour
2445  double x = getCurrentX(sideP);
2446  int flav = getCurrentFlav(sideP);
2447  // Find numerator scale
2448  double scaleNum = (children.empty())
2449  ? hardFacScale(state)
2450  : ( (!infoPtr->settingsPtr->flag("Dire:doMOPS")
2451  && mergingHooksPtr->unorderedPDFscalePrescip() == 1)
2452  ? pdfScale : maxscale );
2453  double scaleDen = ( !infoPtr->settingsPtr->flag("Dire:doMOPS")
2454  && mergingHooksPtr->unorderedPDFscalePrescip() == 1)
2455  ? clusterIn.pT() : newScale;
2456  double xDen = (njetMax > -1 && njetNow == njetMax)
2457  ? mother->getCurrentX(sideP) : x;
2458  int flavDen = (njetMax > -1 && njetNow == njetMax)
2459  ? mother->getCurrentFlav(sideP) : flav;
2460  double sDen = (njetMax > -1 && njetNow == njetMax)
2461  ? mergingHooksPtr->muFinME() : scaleDen;
2462  if (njetMin > -1 && njetNow >= njetMin ) w *= getPDFratio(sideP,
2463  false, false, flav, x, scaleNum, flavDen, xDen, sDen);
2464  else if (njetMin == -1) w *= getPDFratio(sideP,
2465  false, false, flav, x, scaleNum, flavDen, xDen, sDen);
2466  }
2467 
2468  if ( mother->state[inM].colType() != 0 ) {
2469  // Find x value and flavour
2470  double x = getCurrentX(sideM);
2471  int flav = getCurrentFlav(sideM);
2472  // Find numerator scale
2473  double scaleNum = (children.empty())
2474  ? hardFacScale(state)
2475  : ( (!infoPtr->settingsPtr->flag("Dire:doMOPS")
2476  && mergingHooksPtr->unorderedPDFscalePrescip() == 1)
2477  ? pdfScale : maxscale );
2478  double scaleDen = ( !infoPtr->settingsPtr->flag("Dire:doMOPS")
2479  && mergingHooksPtr->unorderedPDFscalePrescip() == 1)
2480  ? clusterIn.pT() : newScale;
2481  double xDen = (njetMax > -1 && njetNow == njetMax)
2482  ? mother->getCurrentX(sideM) : x;
2483  int flavDen = (njetMax > -1 && njetNow == njetMax)
2484  ? mother->getCurrentFlav(sideM) : flav;
2485  double sDen = (njetMax > -1 && njetNow == njetMax)
2486  ? mergingHooksPtr->muFinME() : scaleDen;
2487  if (njetMin > -1 && njetNow >= njetMin ) w *= getPDFratio(sideM,
2488  false, false, flav, x, scaleNum, flavDen, xDen, sDen);
2489  else if (njetMin == -1) w *= getPDFratio(sideM,
2490  false, false, flav, x, scaleNum, flavDen, xDen, sDen);
2491  }
2492 
2493  // Done
2494  return w;
2495 }
2496 
2497 //--------------------------------------------------------------------------
2498 
2499 // Function to return the no-emission probability part of the CKKWL weight.
2500 
2501 double DireHistory::weightEmissions( PartonLevel* trial, int type,
2502  int njetMin, int njetMax, double maxscale ) {
2503 
2504  // Use correct scale
2505  double newScale = scale;
2506  // For ME state, just multiply by PDF ratios
2507 
2508  if ( !mother ) return 1.0;
2509  // Recurse
2510  double w = mother->weightEmissions(trial,type,njetMin,njetMax,newScale);
2511  // Do nothing for empty state
2512  if (state.size() < 3) return 1.0;
2513  // If up to now, trial shower was not successful, return zero
2514  if ( w < 1e-12 ) return 0.0;
2515  // If this node has too many jets, no not calculate no-emission probability.
2516  int njetNow = mergingHooksPtr->getNumberOfClusteringSteps( state) ;
2517  if (njetMax > -1 && njetNow >= njetMax) return 1.0;
2518  if (njetMin > -1 && njetNow < njetMin ) w *= 1.0;
2519  // Do trial shower on current state, return zero if not successful
2520  else w *= doTrialShower(trial, type, maxscale).front();
2521 
2522  if ( abs(w) < 1e-12 ) return 0.0;
2523  // Done
2524  return w;
2525 
2526 }
2527 
2528 //--------------------------------------------------------------------------
2529 
2530 // Function to return the no-emission probability part of the CKKWL weight.
2531 
2532 vector<double> DireHistory::weightEmissionsVec( PartonLevel* trial, int type,
2533  int njetMin, int njetMax, double maxscale ) {
2534 
2535  // Use correct scale
2536  double newScale = scale;
2537 
2538  // Done if at the highest multiplicity node.
2539  if (!mother) return createvector<double>(1.)(1.)(1.);
2540 
2541  // Recurse
2542  vector<double> w = mother->weightEmissionsVec(trial, type, njetMin, njetMax,
2543  newScale);
2544  // Do nothing for empty state
2545  if (state.size() < 3) return createvector<double>(1.)(1.)(1.);
2546  // If up to now, trial shower was not successful, return zero
2547  bool nonZero = false;
2548  for (size_t i=0; i < w.size(); ++i) if (abs(w[i]) > 1e-12) nonZero = true;
2549  if (!nonZero) return createvector<double>(0.)(0.)(0.);
2550  // If this node has too many jets, no not calculate no-emission probability.
2551  int njetNow = mergingHooksPtr->getNumberOfClusteringSteps(state);
2552  if (njetMax > -1 && njetNow >= njetMax)
2553  return createvector<double>(1.)(1.)(1.);
2554 
2555  // Do nothing for too few jets.
2556  if (njetMin > -1 && njetNow < njetMin ) ;
2557  // Do trial shower on current state, return zero if not successful
2558  else {
2559  vector<double> wem = doTrialShower(trial, type, maxscale);
2560  for (size_t i=0; i < w.size(); ++i) w[i] *= wem[i];
2561  }
2562 
2563  nonZero = false;
2564  for (size_t i=0; i < w.size(); ++i) if (abs(w[i]) > 1e-12) nonZero = true;
2565  if (!nonZero) return createvector<double>(0.)(0.)(0.);
2566 
2567  // Done
2568  return w;
2569 
2570 }
2571 
2572 //--------------------------------------------------------------------------
2573 
2574 // Function to generate the O(\alpha_s)-term of the CKKWL-weight.
2575 
2576 double DireHistory::weightFirst(PartonLevel* trial, double as0, double muR,
2577  double maxscale, AlphaStrong * asFSR, AlphaStrong * asISR, Rndm* rndmPtr ) {
2578 
2579  // Use correct scale
2580  double newScale = scale;
2581 
2582  if ( !mother ) {
2583 
2584  double wt = 0.;
2585 
2586  // Calculate PDF first leg
2587  if (state[3].colType() != 0) {
2588  // Find x value and flavour
2589  double x = 2.*state[3].e() / state[0].e();
2590  int flav = state[3].id();
2591  // Find numerator/denominator scale
2592  double scaleNum = (children.empty()) ? hardFacScale(state) : maxscale;
2593  double scaleDen = mergingHooksPtr->muFinME();
2594  // Monte Carlo integrand.
2595  double intPDF4 = monteCarloPDFratios(flav, x, scaleNum, scaleDen,
2596  mergingHooksPtr->muFinME(), as0, rndmPtr);
2597  wt += intPDF4;
2598  }
2599 
2600  // Calculate PDF ratio for second leg
2601  if (state[4].colType() != 0) {
2602  // Find x value and flavour
2603  double x = 2.*state[4].e() / state[0].e();
2604  int flav = state[4].id();
2605  // Find numerator/denominator scale
2606  double scaleNum = (children.empty()) ? hardFacScale(state) : maxscale;
2607  double scaleDen = mergingHooksPtr->muFinME();
2608  // Monte Carlo integrand.
2609  double intPDF4 = monteCarloPDFratios(flav, x, scaleNum, scaleDen,
2610  mergingHooksPtr->muFinME(), as0, rndmPtr);
2611  wt += intPDF4;
2612  }
2613 
2614  return wt;
2615  }
2616 
2617  // Recurse
2618  double w = mother->weightFirst(trial, as0, muR, newScale, asFSR, asISR,
2619  rndmPtr );
2620 
2621  // Do nothing for empty state
2622  if (state.size() < 3) return 0.0;
2623 
2624  // Find right scale
2625  double b = 1.;
2626  double asScale2 = newScale*newScale;
2627  int showerType = (mother->state[clusterIn.emittor].isFinal() ) ? 1 : -1;
2628  if (showerType == -1) asScale2 += pow(mergingHooksPtr->pT0ISR(),2);
2629 
2630  // Directly get argument of running alpha_s from shower plugin.
2631  asScale2 = getShowerPluginScale(mother->state, clusterIn.emittor,
2632  clusterIn.emtPos(), clusterIn.recoiler, clusterIn.name(),
2633  "scaleAS", asScale2);
2634 
2635  // Find summand beta_0 / 2 * ln(muR^2/t_i) due to as expansion.
2636  double NF = 4.;
2637  double BETA0 = 11. - 2./3.* NF;
2638  // For fixed \alpha_s in matrix element
2639  w += as0 / (2.*M_PI) * 0.5 * BETA0 * log( (muR*muR) / (b*asScale2) );
2640 
2641  // Count emissions: New variant
2642  // Generate true average, not only one-point.
2643  bool fixpdf = true;
2644  bool fixas = true;
2645  double nWeight1 = 0.;
2646  double nWeight2 = 0.;
2647 
2648  for(int i=0; i < NTRIAL; ++i) {
2649  // Get number of emissions
2650  vector<double> unresolvedEmissionTerm = countEmissions(trial, maxscale,
2651  newScale, 2, as0, asFSR, asISR, 3, fixpdf, fixas);
2652  nWeight1 += unresolvedEmissionTerm[1];
2653  }
2654  w += nWeight1/double(NTRIAL) + nWeight2/double(NTRIAL);
2655 
2656  // Calculate pdf ratios: Get both sides of event
2657  int inP = 3;
2658  int inM = 4;
2659  int sideP = (mother->state[inP].pz() > 0) ? 1 :-1;
2660  int sideM = (mother->state[inM].pz() > 0) ? 1 :-1;
2661 
2662  if ( mother->state[inP].colType() != 0 ) {
2663  // Find x value and flavour
2664  double x = getCurrentX(sideP);
2665  int flav = getCurrentFlav(sideP);
2666  // Find numerator scale
2667  double scaleNum = (children.empty()) ? hardFacScale(state) : maxscale;
2668  // Monte Carlo integrand.
2669  double intPDF4 = monteCarloPDFratios(flav, x, scaleNum, newScale,
2670  mergingHooksPtr->muFinME(), as0, rndmPtr);
2671  w += intPDF4;
2672 
2673  }
2674 
2675  if ( mother->state[inM].colType() != 0 ) {
2676  // Find x value and flavour
2677  double x = getCurrentX(sideM);
2678  int flav = getCurrentFlav(sideM);
2679  // Find numerator scale
2680  double scaleNum = (children.empty()) ? hardFacScale(state) : maxscale;
2681  // Monte Carlo integrand.
2682  double intPDF4 = monteCarloPDFratios(flav, x, scaleNum, newScale,
2683  mergingHooksPtr->muFinME(), as0, rndmPtr);
2684  w += intPDF4;
2685 
2686  }
2687 
2688  // Done
2689  return w;
2690 
2691 }
2692 
2693 //--------------------------------------------------------------------------
2694 
2695 // Function to generate the O(\alpha_s)-term of the \alpha_s-ratios
2696 // appearing in the CKKWL-weight.
2697 
2698 double DireHistory::weightFirstALPHAS( double as0, double muR,
2699  AlphaStrong * asFSR, AlphaStrong * asISR ) {
2700 
2701  // Use correct scale
2702  double newScale = scale;
2703  // Done
2704  if ( !mother ) return 0.;
2705  // Recurse
2706  double w = mother->weightFirstALPHAS( as0, muR, asFSR, asISR );
2707  // Find right scale
2708  int showerType = (mother->state[clusterIn.emittor].isFinal() ) ? 1 : -1;
2709  double b = 1.;
2710  double asScale = pow2( newScale );
2711  if ( mergingHooksPtr->unorderedASscalePrescip() == 1 )
2712  asScale = pow2( clusterIn.pT() );
2713  if (showerType == -1)
2714  asScale += pow2( mergingHooksPtr->pT0ISR() );
2715 
2716  // Directly get argument of running alpha_s from shower plugin.
2717  asScale = getShowerPluginScale(mother->state, clusterIn.emittor,
2718  clusterIn.emtPos(), clusterIn.recoiler, clusterIn.name(),
2719  "scaleAS", asScale);
2720 
2721  // Find summand beta_0 / 2 * ln(muR^2/t_i) due to as expansion.
2722  double NF = 4.;
2723  double BETA0 = 11. - 2./3.* NF;
2724  // For fixed \alpha_s in matrix element
2725  w += as0 / (2.*M_PI) * 0.5 * BETA0 * log( (muR*muR) / (b*asScale) );
2726 
2727  // Done
2728  return w;
2729 
2730 }
2731 
2732 //--------------------------------------------------------------------------
2733 
2734 // Function to generate the O(\alpha_s)-term of the PDF-ratios
2735 // appearing in the CKKWL-weight.
2736 
2737 double DireHistory::weightFirstPDFs( double as0, double maxscale,
2738  double pdfScale, Rndm* rndmPtr ) {
2739 
2740  // Use correct scale
2741  double newScale = scale;
2742 
2743  if ( !mother ) {
2744 
2745  double wt = 0.;
2746 
2747  // Calculate PDF first leg
2748  if (state[3].colType() != 0) {
2749  // Find x value and flavour
2750  double x = 2.*state[3].e() / state[0].e();
2751  int flav = state[3].id();
2752  // Find numerator/denominator scale
2753  double scaleNum = (children.empty()) ? hardFacScale(state) : maxscale;
2754  double scaleDen = mergingHooksPtr->muFinME();
2755  // Monte Carlo integrand.
2756  wt += monteCarloPDFratios(flav, x, scaleNum, scaleDen,
2757  mergingHooksPtr->muFinME(), as0, rndmPtr);
2758  }
2759  // Calculate PDF ratio for second leg
2760  if (state[4].colType() != 0) {
2761  // Find x value and flavour
2762  double x = 2.*state[4].e() / state[0].e();
2763  int flav = state[4].id();
2764  // Find numerator/denominator scale
2765  double scaleNum = (children.empty()) ? hardFacScale(state) : maxscale;
2766  double scaleDen = mergingHooksPtr->muFinME();
2767  // Monte Carlo integrand.
2768  wt += monteCarloPDFratios(flav, x, scaleNum, scaleDen,
2769  mergingHooksPtr->muFinME(), as0, rndmPtr);
2770  }
2771 
2772  // Done
2773  return wt;
2774  }
2775 
2776  // Remember new PDF scale n case true scale should be used for un-ordered
2777  // splittings.
2778  double newPDFscale = newScale;
2779  if (mergingHooksPtr->unorderedPDFscalePrescip() == 1)
2780  newPDFscale = clusterIn.pT();
2781 
2782  // Recurse
2783  double w = mother->weightFirstPDFs( as0, newScale, newPDFscale, rndmPtr);
2784 
2785  // Calculate pdf ratios: Get both sides of event
2786  int inP = 3;
2787  int inM = 4;
2788  int sideP = (mother->state[inP].pz() > 0) ? 1 :-1;
2789  int sideM = (mother->state[inM].pz() > 0) ? 1 :-1;
2790 
2791  if ( mother->state[inP].colType() != 0 ) {
2792  // Find x value and flavour
2793  double x = getCurrentX(sideP);
2794  int flav = getCurrentFlav(sideP);
2795  // Find numerator / denominator scales
2796  double scaleNum = (children.empty())
2797  ? hardFacScale(state)
2798  : ( (mergingHooksPtr->unorderedPDFscalePrescip() == 1)
2799  ? pdfScale : maxscale );
2800  double scaleDen = (mergingHooksPtr->unorderedPDFscalePrescip() == 1)
2801  ? clusterIn.pT() : newScale;
2802  // Monte Carlo integrand.
2803  w += monteCarloPDFratios(flav, x, scaleNum, scaleDen,
2804  mergingHooksPtr->muFinME(), as0, rndmPtr);
2805  }
2806 
2807  if ( mother->state[inM].colType() != 0 ) {
2808  // Find x value and flavour
2809  double x = getCurrentX(sideM);
2810  int flav = getCurrentFlav(sideM);
2811  // Find numerator / denominator scales
2812  double scaleNum = (children.empty())
2813  ? hardFacScale(state)
2814  : ( (mergingHooksPtr->unorderedPDFscalePrescip() == 1)
2815  ? pdfScale : maxscale );
2816  double scaleDen = (mergingHooksPtr->unorderedPDFscalePrescip() == 1)
2817  ? clusterIn.pT() : newScale;
2818  // Monte Carlo integrand.
2819  w += monteCarloPDFratios(flav, x, scaleNum, scaleDen,
2820  mergingHooksPtr->muFinME(), as0, rndmPtr);
2821  }
2822 
2823  // Done
2824  return w;
2825 
2826 }
2827 
2828 
2829 //--------------------------------------------------------------------------
2830 
2831 // Function to generate the O(\alpha_s)-term of the no-emission
2832 // probabilities appearing in the CKKWL-weight.
2833 
2834 double DireHistory::weightFirstEmissions(PartonLevel* trial, double as0,
2835  double maxscale, AlphaStrong * asFSR, AlphaStrong * asISR,
2836  bool fixpdf, bool fixas ) {
2837 
2838  // Use correct scale
2839  double newScale = scale;
2840  if ( !mother ) return 0.0;
2841  // Recurse
2842  double w = mother->weightFirstEmissions(trial, as0, newScale, asFSR, asISR,
2843  fixpdf, fixas );
2844  // Do nothing for empty state
2845  if (state.size() < 3) return 0.0;
2846  // Generate true average.
2847  double nWeight1 = 0.;
2848  double nWeight2 = 0.;
2849  for(int i=0; i < NTRIAL; ++i) {
2850  // Get number of emissions
2851  vector<double> unresolvedEmissionTerm = countEmissions(trial, maxscale,
2852  newScale, 2, as0, asFSR, asISR, 3, fixpdf, fixas);
2853  nWeight1 += unresolvedEmissionTerm[1];
2854  }
2855 
2856  w += nWeight1/double(NTRIAL) + nWeight2/double(NTRIAL);
2857 
2858  // Done
2859  return w;
2860 
2861 }
2862 
2863 //--------------------------------------------------------------------------
2864 
2865 // Function to return the factorisation scale of the hard process in Pythia.
2866 
2867 double DireHistory::hardFacScale(const Event& event) {
2868 
2869  // Declare output scale.
2870  double hardscale = 0.;
2871  // If scale should not be reset, done.
2872  if ( !mergingHooksPtr->resetHardQFac() ) return mergingHooksPtr->muF();
2873 
2874  // For pure QCD dijet events, calculate the hadronic cross section
2875  // of the hard process at the pT of the dijet system, rather than at fixed
2876  // arbitrary scale.
2877  if ( mergingHooksPtr->getProcessString().compare("pp>jj") == 0
2878  || mergingHooksPtr->getProcessString().compare("pp>aj") == 0
2879  || isQCD2to2(event)) {
2880  // Find the mT in the hard sub-process.
2881  vector <double> mT;
2882  for ( int i=0; i < event.size(); ++i)
2883  if ( event[i].isFinal() && event[i].colType() != 0 )
2884  mT.push_back( abs(event[i].mT2()) );
2885  if ( int(mT.size()) != 2 )
2886  hardscale = infoPtr->QFac();
2887  else
2888  hardscale = sqrt( min( mT[0], mT[1] ) );
2889 
2890  // For DIS, set the hard process scale to Q2.
2891  } else if ( mergingHooksPtr->getProcessString().compare("e+p>e+j") == 0
2892  || mergingHooksPtr->getProcessString().compare("e-p>e-j") == 0) {
2893  // Use Q2 as core scale.
2894  if ( isDIS2to2(event)) {
2895  int iInEl(0), iOutEl(0);
2896  for ( int i=0; i < event.size(); ++i )
2897  if ( event[i].idAbs() == 11 ) {
2898  if ( event[i].status() == -21 ) iInEl = i;
2899  if ( event[i].isFinal() ) iOutEl = i;
2900  }
2901  hardscale = sqrt( -(event[iInEl].p()-event[iOutEl].p()).m2Calc() );
2902 
2903  // Use pT2 as core scale.
2904  } else if (isMassless2to2(event)) {
2905 
2906  // Find the mT in the hard sub-process.
2907  vector <double> mT;
2908  for ( int i=0; i < event.size(); ++i)
2909  if ( event[i].isFinal() && event[i].colType() != 0 )
2910  mT.push_back( abs(event[i].mT2()) );
2911  if ( int(mT.size()) != 2 )
2912  hardscale = infoPtr->QFac();
2913  else
2914  hardscale = sqrt( min( mT[0], mT[1] ) );
2915 
2916  } else hardscale = mergingHooksPtr->muF();
2917 
2918  } else {
2919  hardscale = mergingHooksPtr->muF();
2920  }
2921  // Done
2922  return hardscale;
2923 }
2924 
2925 //--------------------------------------------------------------------------
2926 
2927 // Function to return the factorisation scale of the hard process in Pythia.
2928 
2929 double DireHistory::hardRenScale(const Event& event) {
2930  // Declare output scale.
2931  double hardscale = 0.;
2932  // If scale should not be reset, done.
2933  if ( !mergingHooksPtr->resetHardQRen() ) return mergingHooksPtr->muR();
2934  // For pure QCD dijet events, calculate the hadronic cross section
2935  // of the hard process at the pT of the dijet system, rather than at fixed
2936  // arbitrary scale.
2937  if ( mergingHooksPtr->getProcessString().compare("pp>jj") == 0
2938  || mergingHooksPtr->getProcessString().compare("pp>aj") == 0
2939  || isQCD2to2(event)) {
2940  // Find the mT in the hard sub-process.
2941  vector <double> mT;
2942  for ( int i=0; i < event.size(); ++i)
2943  if ( event[i].isFinal()
2944  && ( event[i].colType() != 0 || event[i].id() == 22 ) )
2945  mT.push_back( abs(event[i].mT()) );
2946  if ( int(mT.size()) != 2 )
2947  hardscale = infoPtr->QRen();
2948  else
2949  hardscale = sqrt( mT[0]*mT[1] );
2950 
2951  // For DIS, set the hard process scale to Q2.
2952  } else if ( mergingHooksPtr->getProcessString().compare("e+p>e+j") == 0
2953  || mergingHooksPtr->getProcessString().compare("e-p>e-j") == 0) {
2954  // Use Q2 as core scale.
2955  if ( isDIS2to2(event)) {
2956  int iInEl(0), iOutEl(0);
2957  for ( int i=0; i < state.size(); ++i )
2958  if ( state[i].idAbs() == 11 ) {
2959  if ( state[i].status() == -21 ) iInEl = i;
2960  if ( state[i].isFinal() ) iOutEl = i;
2961  }
2962  hardscale = sqrt( -(state[iInEl].p()-state[iOutEl].p()).m2Calc() );
2963 
2964  // Use pT2 as core scale.
2965  } else if (isMassless2to2(event)) {
2966 
2967  // Find the mT in the hard sub-process.
2968  vector <double> mT;
2969  for ( int i=0; i < event.size(); ++i)
2970  if ( event[i].isFinal() && event[i].colType() != 0 )
2971  mT.push_back( abs(event[i].mT2()) );
2972  if ( int(mT.size()) != 2 )
2973  hardscale = infoPtr->QFac();
2974  else
2975  hardscale = sqrt( min( mT[0], mT[1] ) );
2976 
2977  } else hardscale = mergingHooksPtr->muF();
2978 
2979  } else {
2980  hardscale = mergingHooksPtr->muR();
2981  }
2982  // Done
2983  return hardscale;
2984 }
2985 
2986 //--------------------------------------------------------------------------
2987 
2988 // Function to return the factorisation scale of the hard process in Pythia.
2989 
2990 double DireHistory::hardStartScale(const Event& event) {
2991 
2992  // Starting scale of initial state showers.
2993  map<string,double> stateVarsISR;
2994 
2995  if ( showers && showers->spacePtr) stateVarsISR
2996  = showers->spacePtr->getStateVariables(event,0,0,0,"");
2997  if (!showers && isr) stateVarsISR
2998  = isr->getStateVariables(event,0,0,0,"");
2999 
3000  // Starting scale of final state showers.
3001  map<string,double> stateVarsFSR;
3002  if ( showers && showers->timesPtr ) stateVarsFSR
3003  = showers->timesPtr->getStateVariables(event,0,0,0,"");
3004  if (!showers && fsr) stateVarsFSR
3005  = fsr->getStateVariables(event,0,0,0,"");
3006 
3007  // Find maximal scale.
3008  double hardscale = 0.;
3009  for ( map<string,double>::iterator it = stateVarsISR.begin();
3010  it != stateVarsISR.end(); ++it )
3011  if ( it->first.find("scalePDF") != string::npos )
3012  hardscale = max( hardscale, sqrt(it->second) );
3013  for ( map<string,double>::iterator it = stateVarsFSR.begin();
3014  it != stateVarsFSR.end(); ++it )
3015  if ( it->first.find("scalePDF") != string::npos )
3016  hardscale = max( hardscale, sqrt(it->second) );
3017 
3018  // Done
3019  return hardscale;
3020 }
3021 
3022 //--------------------------------------------------------------------------
3023 
3024 // Perform a trial shower using the pythia object between
3025 // maxscale down to this scale and return the corresponding Sudakov
3026 // form factor.
3027 // IN trialShower : Shower object used as trial shower
3028 // double : Maximum scale for trial shower branching
3029 // OUT 0.0 : trial shower emission outside allowed pT range
3030 // 1.0 : trial shower successful (any emission was below
3031 // the minimal scale )
3032 
3033 vector<double> DireHistory::doTrialShower( PartonLevel* trial, int type,
3034  double maxscaleIn, double minscaleIn ) {
3035 
3036  // Copy state to local process
3037  Event process = state;
3038  // Set starting scale.
3039  double startingScale = maxscaleIn;
3040  // Careful when setting shower starting scale for pure QCD and prompt
3041  // photon case.
3042  if ( mergingHooksPtr->getNumberOfClusteringSteps(process) == 0
3043  && ( mergingHooksPtr->getProcessString().compare("pp>jj") == 0
3044  || mergingHooksPtr->getProcessString().compare("pp>aj") == 0
3045  || isQCD2to2(state) ) )
3046  startingScale = min( startingScale, hardFacScale(process) );
3047 
3048  // For DIS, set starting scale to Q2 or pT2.
3049  if ( mergingHooksPtr->getNumberOfClusteringSteps(process) == 0
3050  && ( mergingHooksPtr->getProcessString().compare("e+p>e+j") == 0
3051  || mergingHooksPtr->getProcessString().compare("e-p>e-j") == 0))
3052  //startingScale = min( startingScale, hardFacScale(process) );
3053  startingScale = hardFacScale(process);
3054 
3055  if ( mergingHooksPtr->getNumberOfClusteringSteps(process) == 0 )
3056  startingScale = hardStartScale(process);
3057 
3058  // Set output.
3059  double wt = 1.;
3060  vector <double> wtv(createvector<double>(1.)(1.)(1.));
3061  int nFSRtry(0), nISRtry(0), nMPItry(0);
3062 
3063  while (true) {
3064 
3065  // Reset trialShower object
3066  psweights->reset();
3067  trial->resetTrial();
3068  // Construct event to be showered
3069  Event event = Event();
3070  event.init("(hard process-modified)", particleDataPtr);
3071  event.clear();
3072 
3073  // Reset process scale so that shower starting scale is correctly set.
3074  process.scale(startingScale);
3075  //doVeto = false;
3076 
3077  // Get pT before reclustering
3078  double minScale = (minscaleIn > 0.) ? minscaleIn : scale;
3079 
3080  mergingHooksPtr->setShowerStoppingScale(minScale);
3081 
3082  // Give up generating no-MPI probability if ISR completely dominates.
3083  //if (type == -1 && nFSRtry+nISRtry > 500) {doVeto=false; break;}
3084  if (type == -1 && nFSRtry+nISRtry > 500) { break;}
3085 
3086  // If the maximal scale and the minimal scale coincide (as would
3087  // be the case for the corrected scales of unordered histories),
3088  // do not generate Sudakov
3089  if (minScale >= startingScale) break;
3090 
3091  // Find z and pT values at which the current state was formed, to
3092  // ensure that the showers can order the next emission correctly in
3093  // rapidity, if required.
3094  // NOT CORRECTLY SET FOR HIGHEST MULTIPLICITY STATE!
3095  double z = ( mergingHooksPtr->getNumberOfClusteringSteps(state) == 0
3096  || !mother )
3097  ? 0.5
3098  : mother->getCurrentZ(clusterIn.emittor,clusterIn.recoiler,
3099  clusterIn.emtPos(), clusterIn.flavRadBef);
3100  // Store z and pT values at which the current state was formed.
3101  infoPtr->zNowISR(z);
3102  infoPtr->pT2NowISR(pow(startingScale,2));
3103  infoPtr->hasHistory(true);
3104 
3105  // Perform trial shower emission
3106  trial->next(process,event);
3107  // Get trial shower pT.
3108  double pTtrial = trial->pTLastInShower();
3109  int typeTrial = trial->typeLastInShower();
3110 
3111  if (typeTrial == 1) nMPItry++;
3112  else if (typeTrial == 2) nISRtry++;
3113  else nFSRtry++;
3114 
3115  // Clear parton systems.
3116  trial->resetTrial();
3117 
3118  double t = (pTtrial <= 0.) ? pow2(minScale) : pow2(pTtrial);
3119  pair<double,double> wtShower = psweights->getWeight(t);
3120  pair<double,double> wt_isr_1 = psweights->getWeight
3121  (t, "Variations:muRisrDown");
3122  pair<double,double> wt_isr_2 = psweights->getWeight
3123  (t, "Variations:muRisrUp");
3124  pair<double,double> wt_fsr_1 = psweights->getWeight
3125  (t, "Variations:muRfsrDown");
3126  pair<double,double> wt_fsr_2 = psweights->getWeight
3127  (t, "Variations:muRfsrUp");
3128 
3129  double enhancement = 1.;
3130  if ( pTtrial > minScale) enhancement
3131  = psweights->getTrialEnhancement( pow2(pTtrial));
3132  psweights->reset();
3133  if (pTtrial>0.) psweights->init();
3134  psweights->clearTrialEnhancements();
3135 
3136  // Get veto (merging) scale value
3137  double vetoScale = (mother) ? 0. : mergingHooksPtr->tms();
3138  // Get merging scale in current event
3139  double tnow = mergingHooksPtr->tmsNow( event );
3140 
3141  // Done if evolution scale has fallen below minimum
3142  if ( pTtrial < minScale ) {
3143  wt *= wtShower.second;
3144  wtv[0] *= wtShower.second;
3145  wtv[1] *= wt_isr_1.second*wt_fsr_1.second;
3146  wtv[2] *= wt_isr_2.second*wt_fsr_2.second;
3147  break;
3148  }
3149 
3150  // Reset starting scale.
3151  startingScale = pTtrial;
3152 
3153  // Continue if this state is below the veto scale
3154  if ( tnow < vetoScale && vetoScale > 0. ) continue;
3155 
3156  // Retry if the trial emission was not allowed.
3157  if ( mergingHooksPtr->canVetoTrialEmission()
3158  && mergingHooksPtr->doVetoTrialEmission( process, event) ) continue;
3159 
3160  int iRecAft = event.size() - 1;
3161  int iEmt = event.size() - 2;
3162  int iRadAft = event.size() - 3;
3163  if ( (event[iRecAft].status() != 52 && event[iRecAft].status() != -53) ||
3164  event[iEmt].status() != 51 || event[iRadAft].status() != 51)
3165  iRecAft = iEmt = iRadAft = -1;
3166  for (int i = event.size() - 1; i > 0; i--) {
3167  if (iRadAft == -1 && event[i].status() == -41) iRadAft = i;
3168  else if (iEmt == -1 && event[i].status() == 43) iEmt = i;
3169  else if (iRecAft == -1 && event[i].status() == -42) iRecAft = i;
3170  if (iRadAft != -1 && iEmt != -1 && iRecAft != -1) break;
3171  }
3172 
3173  // Check if the splitting occured in a small window around a flavour
3174  // threshold.
3175  bool onCthreshold(false), onBthreshold(false);
3176  if (process[3].colType() != 0 || process[4].colType() != 0 ) {
3177  bool usePDFalphas
3178  = infoPtr->settingsPtr->flag("ShowerPDF:usePDFalphas");
3179  BeamParticle* beam = (particleDataPtr->isHadron(beamA.id())) ? &beamA
3180  : (particleDataPtr->isHadron(beamB.id())) ? &beamB
3181  : nullptr;
3182  double m2cPhys = (usePDFalphas) ? pow2(max(0.,beam->mQuarkPDF(4)))
3183  : mergingHooksPtr->AlphaS_ISR()->muThres2(4);
3184  double m2bPhys = (usePDFalphas) ? pow2(max(0.,beam->mQuarkPDF(5)))
3185  : mergingHooksPtr->AlphaS_ISR()->muThres2(5);
3186  if ( event[iEmt].idAbs() == 4 && minScale < sqrt(m2cPhys)
3187  && pTtrial > (1. - MCWINDOW)*sqrt(m2cPhys)
3188  && pTtrial < (1. + MCWINDOW)*sqrt(m2cPhys)) onCthreshold = true;
3189  if ( event[iEmt].idAbs() == 5 && minScale < sqrt(m2bPhys)
3190  && pTtrial > (1. - MBWINDOW)*sqrt(m2bPhys)
3191  && pTtrial < (1. + MBWINDOW)*sqrt(m2bPhys)) onBthreshold = true;
3192  }
3193 
3194  // Only consider allowed emissions for veto:
3195  // Only allow MPI for MPI no-emission probability.
3196  if ( type == -1 && typeTrial != 1 ) {
3197  // If an initial-state splitting occured because of a flavour threshold,
3198  // then the showers will always win competition against MPI, meaning that
3199  // no MPI emission will be produced, i.e. the no-MPI-probability = 1
3200  //if (onCthreshold || onBthreshold) { doVeto=false; break; }
3201  if (onCthreshold || onBthreshold) { break; }
3202  continue;
3203  }
3204  // Only allow ISR or FSR for radiative no-emission probability.
3205  if ( type == 1 && !(typeTrial == 2 || typeTrial >= 3) ) continue;
3206 
3207  if (pTtrial > minScale) {
3208  wt *= wtShower.first*wtShower.second * (1.-1./enhancement);
3209  wtv[0] *= wtShower.first*wtShower.second * (1.-1./enhancement);
3210  wtv[1] *= wt_isr_1.first*wt_isr_1.second*wt_fsr_1.first*wt_fsr_1.second
3211  *(1.-1./enhancement);
3212  wtv[2] *= wt_isr_2.first*wt_isr_2.second*wt_fsr_2.first*wt_fsr_2.second
3213  *(1.-1./enhancement);
3214  }
3215  if (wt == 0.) break;
3216 
3217  if (pTtrial > minScale) continue;
3218 
3219  // For 2 -> 2 pure QCD state, do not allow multiparton interactions
3220  // above the kinematical pT of the 2 -> 2 state.
3221  if ( type == -1
3222  && typeTrial == 1
3223  && mergingHooksPtr->getNumberOfClusteringSteps(process) == 0
3224  && ( mergingHooksPtr->getProcessString().compare("pp>jj") == 0
3225  || mergingHooksPtr->getProcessString().compare("pp>aj") == 0
3226  || isQCD2to2(state))
3227  && pTtrial > hardFacScale(process) )
3228  return createvector<double>(0.)(0.)(0.);
3229 
3230  // Done
3231  break;
3232 
3233  }
3234 
3235  // Reset trialShower object
3236  psweights->reset();
3237  trial->resetTrial();
3238 
3239  // Done
3240  return wtv;
3241 
3242 }
3243 
3244 //--------------------------------------------------------------------------
3245 
3246 // Assume we have a vector of i elements containing indices into
3247 // another vector with N elements. Update the indices so that all
3248 // unique combinations (starting from 0,1,2,3, ...) are
3249 // covered. Return false when all combinations have been ehausted.
3250 
3251 bool DireHistory::updateind(vector<int> & ind, int i, int N) {
3252  if ( i < 0 ) return false;
3253  if ( ++ind[i] < N ) return true;
3254  if ( !updateind(ind, i - 1, N - 1) ) return false;
3255  ind[i] = ind[i - 1] + 1;
3256  return true;
3257 }
3258 
3259 //--------------------------------------------------------------------------
3260 
3261 // Return the expansion of the no-emission probability up to the Nth
3262 // term. Optionally calculate the the terms using fixed alphaS
3263 // and/or PDF ratios.
3264 
3265 vector<double>
3266 DireHistory::countEmissions(PartonLevel* trial, double maxscale,
3267  double minscale, int showerType, double as0,
3268  AlphaStrong * asFSR, AlphaStrong * asISR, int N = 1,
3269  bool fixpdf = true, bool fixas = true) {
3270 
3271  if ( N < 0 ) return vector<double>();
3272  vector<double> result(N+1);
3273  result[0] = 1.0;
3274  if ( N < 1 ) return result;
3275 
3276  // Copy state to local process
3277  Event process = state;
3278 
3279  double startingScale = maxscale;
3280  // Careful when setting shower starting scale for pure QCD and prompt
3281  // photon case.
3282  if ( mergingHooksPtr->getNumberOfClusteringSteps(process) == 0
3283  && ( mergingHooksPtr->getProcessString().compare("pp>jj") == 0
3284  || mergingHooksPtr->getProcessString().compare("pp>aj") == 0
3285  || isQCD2to2(state) ) )
3286  startingScale = min( startingScale, hardFacScale(process) );
3287 
3288  vector<double> wts;
3289  bool canEnhanceTrial = trial->canEnhanceTrial();
3290 
3291  while ( true ) {
3292 
3293  // Reset trialShower object
3294  psweights->reset();
3295  trial->resetTrial();
3296  // Construct event to be showered
3297  Event event = Event();
3298  event.init("(hard process-modified)", particleDataPtr);
3299  event.clear();
3300 
3301  // Reset process scale
3302  process.scale(startingScale);
3303 
3304  // If the maximal scale and the minimal scale coincide (as would
3305  // be the case for the corrected scales of unordered histories),
3306  // do not generate Sudakov
3307  if (minscale >= startingScale) return result;
3308 
3309  // Find z and pT values at which the current state was formed, to
3310  // ensure that the showers can order the next emission correctly in
3311  // rapidity, if required
3312  if ( mother ) {
3313  double z = ( mergingHooksPtr->getNumberOfClusteringSteps(state) == 0)
3314  ? 0.5
3315  : mother->getCurrentZ(clusterIn.emittor,clusterIn.recoiler,
3316  clusterIn.emtPos());
3317  // Store z and pT values at which the current state was formed
3318  infoPtr->zNowISR(z);
3319  infoPtr->pT2NowISR(pow(startingScale,2));
3320  infoPtr->hasHistory(true);
3321  }
3322 
3323  // Perform trial shower emission
3324  trial->next(process,event);
3325 
3326  // Get trial shower pT
3327  double pTtrial = trial->pTLastInShower();
3328  int typeTrial = trial->typeLastInShower();
3329 
3330  // Clear parton systems.
3331  trial->resetTrial();
3332 
3333  // Get enhanced trial emission weight.
3334  double pTEnhanced = trial->getEnhancedTrialPT();
3335  double wtEnhanced = trial->getEnhancedTrialWeight();
3336  if ( canEnhanceTrial && pTEnhanced > 0.) pTtrial = pTEnhanced;
3337 
3338  // Get veto (merging) scale value
3339  double vetoScale = (mother) ? 0. : mergingHooksPtr->tms();
3340  // Get merging scale in current event
3341  double tnow = mergingHooksPtr->tmsNow( event );
3342 
3343  // Save scale of current state.
3344  startingScale = pTtrial;
3345  // If the scale of the current state is below the minimal scale, exit.
3346  if ( pTtrial < minscale ) break;
3347  // If this state is below the merging scale, do not count emission.
3348  if ( tnow < vetoScale && vetoScale > 0. ) continue;
3349  // Retry if the trial emission was not allowed.
3350  if ( mergingHooksPtr->canVetoTrialEmission()
3351  && mergingHooksPtr->doVetoTrialEmission( process, event) ) continue;
3352 
3353  // Set weight of enhanced emission.
3354  double enhance = (canEnhanceTrial && pTtrial > minscale) ? wtEnhanced : 1.;
3355 
3356  // Check if a new emission should be generated, either because
3357  // the latest emission was not of the desired kind or if the
3358  // emission was above the minimal scale
3359  double alphaSinPS = as0;
3360  double pdfs = 1.0;
3361 
3362  double asScale2 = pTtrial*pTtrial;
3363  // Directly get argument of running alpha_s from shower plugin.
3364  asScale2 = getShowerPluginScale(mother->state, clusterIn.emittor,
3365  clusterIn.emtPos(), clusterIn.recoiler, clusterIn.name(),
3366  "scaleAS", asScale2);
3367 
3368  // Initial state splittings.
3369  if ( (showerType == -1 || showerType == 2) && typeTrial == 2 ) {
3370  // Get weight to translate to alpha_s at fixed renormalisation scale.
3371  if ( fixas ) alphaSinPS = (*asISR).alphaS(asScale2);
3372  // Get weight to translate to PDFs at fixed factorisation scale.
3373  if ( fixpdf )
3374  //pdfs = pdfFactor( event, typeTrial, pTtrial,
3375  // mergingHooksPtr->muFinME() );
3376  pdfs = pdfFactor( process, event, typeTrial, pTtrial,
3377  mergingHooksPtr->muFinME() );
3378  // Final state splittings.
3379  } else if ( (showerType == 1 || showerType == 2) && typeTrial >= 3 ) {
3380  // Get weight to translate to alpha_s at fixed renormalisation scale.
3381  if ( fixas ) alphaSinPS = (*asFSR).alphaS(asScale2);
3382  // Get weight to translate to PDFs at fixed factorisation scale. Needed
3383  // for final state splittings with initial state recoiler.
3384  if ( fixpdf )
3385  pdfs = pdfFactor( process, event, typeTrial, pTtrial,
3386  mergingHooksPtr->muFinME() );
3387  }
3388 
3389  // Save weight correcting to emission generated with fixed scales.
3390  if ( typeTrial == 2 || typeTrial >= 3 )
3391  wts.push_back(as0/alphaSinPS * pdfs * 1./enhance);
3392 
3393  }
3394 
3395  for ( int n = 1; n <= min(N, int(wts.size())); ++n ) {
3396  vector<int> ind(N);
3397  for ( int i = 0; i < N; ++i ) ind[i] = i;
3398  do {
3399  double x = 1.0;
3400  for ( int j = 0; j < n; ++j ) x *= wts[ind[j]];
3401  result[n] += x;
3402  } while ( updateind(ind, n - 1, wts.size()) );
3403  if ( n%2 ) result[n] *= -1.0;
3404  }
3405 
3406  // Reset trialShower object
3407  psweights->reset();
3408  trial->resetTrial();
3409 
3410  // Done
3411  return result;
3412 }
3413 
3414 //--------------------------------------------------------------------------
3415 
3416 // Function to integrate PDF ratios between two scales over x and t,
3417 // where the PDFs are always evaluated at the lower t-integration limit
3418 
3419 double DireHistory::monteCarloPDFratios(int flav, double x, double maxScale,
3420  double minScale, double pdfScale, double asME, Rndm* rndmPtr) {
3421 
3422  // Perform numerical integration for PDF ratios
3423  // Prefactor is as/2PI
3424  double factor = asME / (2.*M_PI);
3425  // Scale integration just produces a multiplicative logarithm
3426  factor *= log(maxScale/minScale);
3427 
3428  // For identical scales, done
3429  if (factor == 0.) return 0.;
3430 
3431  // Declare constants
3432  double CF = 4./3.;
3433  double CA = 3.;
3434  double NF = 4.;
3435  double TR = 1./2.;
3436 
3437  double integral = 0.;
3438  double RN = rndmPtr->flat();
3439 
3440  if (flav == 21) {
3441  double zTrial = pow(x,RN);
3442  integral = -log(x) * zTrial *
3443  integrand(flav, x, pdfScale, zTrial);
3444  integral += 1./6.*(11.*CA - 4.*NF*TR)
3445  + 2.*CA*log(1.-x);
3446  } else {
3447  double zTrial = x + RN*(1. - x);
3448  integral = (1.-x) *
3449  integrand(flav, x, pdfScale, zTrial);
3450  integral += 3./2.*CF
3451  + 2.*CF*log(1.-x);
3452  }
3453 
3454  // Done
3455  return (factor*integral);
3456 }
3457 
3458 //--------------------------------------------------------------------------
3459 
3460 // Methods used for construction of all histories.
3461 
3462 // Check if a ordered (and complete) path has been found in the
3463 // initial node, in which case we will no longer be interested in
3464 // any unordered paths.
3465 
3466 bool DireHistory::onlyOrderedPaths() {
3467  if ( !mother || foundOrderedPath ) return foundOrderedPath;
3468  return foundOrderedPath = mother->onlyOrderedPaths();
3469 }
3470 
3471 //--------------------------------------------------------------------------
3472 
3473 // Check if an allowed (according to user-criterion) path has been found in
3474 // the initial node, in which case we will no longer be interested in
3475 // any forbidden paths.
3476 
3477 bool DireHistory::onlyAllowedPaths() {
3478  if ( !mother || foundAllowedPath ) return foundAllowedPath;
3479  return foundAllowedPath = mother->onlyAllowedPaths();
3480 }
3481 
3482 //--------------------------------------------------------------------------
3483 
3484 // When a full path has been found, register it with the initial
3485 // history node.
3486 // IN History : History to be registered as path
3487 // bool : Specifying if clusterings so far were ordered
3488 // bool : Specifying if path is complete down to 2->2 process
3489 // OUT true if History object forms a plausible path (eg prob>0 ...)
3490 
3491 bool DireHistory::registerPath(DireHistory & l, bool isOrdered,
3492  bool isAllowed, bool isComplete) {
3493 
3494  // We are not interested in improbable paths.
3495  if ( l.prodOfProbs <= 0.0)
3496  return false;
3497  // We only register paths in the initial node.
3498  if ( mother ) return mother->registerPath(l, isOrdered,
3499  isAllowed, isComplete);
3500 
3501  // Again, we are not interested in improbable paths.
3502  if ( sumpath == sumpath + l.prodOfProbs )
3503  return false;
3504  if ( mergingHooksPtr->canCutOnRecState()
3505  && foundAllowedPath && !isAllowed )
3506  return false;
3507  if ( mergingHooksPtr->orderHistories()
3508  && foundOrderedPath && !isOrdered ) {
3509  // Prefer complete or allowed paths to ordered paths.
3510  if ( (!foundCompletePath && isComplete)
3511  || (!foundAllowedPath && isAllowed) ) ;
3512  else return false;
3513  }
3514 
3515  if ( foundCompletePath && !isComplete)
3516  return false;
3517  if ( !mergingHooksPtr->canCutOnRecState()
3518  && !mergingHooksPtr->allowCutOnRecState() )
3519  foundAllowedPath = true;
3520 
3521  if ( mergingHooksPtr->canCutOnRecState() && isAllowed && isComplete) {
3522  if ( !foundAllowedPath || !foundCompletePath ) {
3523  // If this is the first complete, allowed path, discard the
3524  // old, disallowed or incomplete ones.
3525  paths.clear();
3526  sumpath = 0.0;
3527  }
3528  foundAllowedPath = true;
3529 
3530  }
3531 
3532  if ( mergingHooksPtr->orderHistories() && isOrdered && isComplete ) {
3533  if ( !foundOrderedPath || !foundCompletePath ) {
3534  // If this is the first complete, ordered path, discard the
3535  // old, non-ordered or incomplete ones.
3536  paths.clear();
3537  sumpath = 0.0;
3538  }
3539  foundOrderedPath = true;
3540  foundCompletePath = true;
3541 
3542  }
3543 
3544  if ( isComplete ) {
3545  if ( !foundCompletePath ) {
3546  // If this is the first complete path, discard the old,
3547  // incomplete ones.
3548  paths.clear();
3549  sumpath = 0.0;
3550  }
3551  foundCompletePath = true;
3552  }
3553 
3554  if ( isOrdered ) foundOrderedPath = true;
3555 
3556  // Index path by probability
3557  sumpath += l.prodOfProbs;
3558  paths[sumpath] = &l;
3559 
3560  updateProbMax(l.prodOfProbs, isComplete);
3561 
3562  return true;
3563 }
3564 
3565 //--------------------------------------------------------------------------
3566 
3567 // For one given state, find all possible clusterings.
3568 // IN Event : state to be investigated
3569 // OUT vector of all (rad,rec,emt) systems in the state
3570 
3571 vector<DireClustering> DireHistory::getAllClusterings( const Event& event) {
3572 
3573  vector<DireClustering> ret;
3574  vector<DireClustering> systems;
3575 
3576  for (int i=0; i < event.size(); ++i) {
3577  if ( event[i].isFinal() ) {
3578  for (int j=0; j < event.size(); ++j) {
3579  if ( i == j) continue;
3580  bool isInitial = (event[j].status() == -21
3581  || event[j].status() == -41 || event[j].status() == -42
3582  || event[j].status() == -53
3583  || event[j].status() == -31 || event[j].status() == -34);
3584  if (!isInitial && !event[j].isFinal() ) continue;
3585  systems = getClusterings( i, j, event);
3586  ret.insert(ret.end(), systems.begin(), systems.end());
3587  systems.resize(0);
3588  }
3589  }
3590  }
3591 
3592  // Now remove any clustering that appears more than once.
3593  vector<int> iRemove;
3594  for (unsigned int i=0; i < ret.size(); ++i) {
3595  for (unsigned int j=i; j < ret.size(); ++j) {
3596  if (i == j) continue;
3597  if (find(iRemove.begin(), iRemove.end(), j) != iRemove.end()) continue;
3598  if ( equalClustering(ret[i], ret[j])) iRemove.push_back(j);
3599  }
3600  }
3601  sort (iRemove.begin(), iRemove.end());
3602  for (int i = iRemove.size()-1; i >= 0; --i) {
3603  ret[iRemove[i]] = ret.back();
3604  ret.pop_back();
3605  }
3606 
3607  return ret;
3608 }
3609 
3610 //--------------------------------------------------------------------------
3611 
3612 // Function to attach (spin-dependent duplicates of) a clustering.
3613 
3614 void DireHistory::attachClusterings (vector<DireClustering>& clus, int iEmt,
3615  int iRad,
3616  int iRec, int iPartner, double pT, string name, const Event& event) {
3617 
3618  // Do nothing for unphysical clustering.
3619  if (pT <= 0.) return;
3620 
3621  if ( !mergingHooksPtr->doWeakClustering() ) {
3622 
3623  clus.push_back( DireClustering(iEmt, iRad, iRec, iPartner, pT,
3624  &event[iRad], &event[iEmt], &event[iRec], name, 0, 0, 0, 0));
3625 
3626  } else {
3627 
3628  // Get ID of radiator before the splitting.
3629  map<string,double> stateVars;
3630  bool hasPartonLevel(showers && showers->timesPtr && showers->spacePtr),
3631  hasShowers(fsr && isr);
3632  if (hasPartonLevel) {
3633  bool isFSR = showers->timesPtr->isTimelike(event, iRad, iEmt, iRec, "");
3634  if (isFSR) stateVars = showers->timesPtr->getStateVariables(event,iRad,
3635  iEmt,iRec,name);
3636  else stateVars = showers->spacePtr->getStateVariables(event,iRad,
3637  iEmt,iRec,name);
3638  } else if (hasShowers) {
3639  bool isFSR = fsr->isTimelike(event, iRad, iEmt, iRec, "");
3640  if (isFSR) stateVars = fsr->getStateVariables(event,iRad,iEmt,iRec,name);
3641  else stateVars = isr->getStateVariables(event,iRad,iEmt,iRec,name);
3642  }
3643 
3644  // Get flavour of radiator after potential clustering
3645  int radBeforeFlav = int(stateVars["radBefID"]);
3646 
3647  clus.push_back( DireClustering(iEmt, iRad, iRec, iPartner, pT,
3648  &event[iRad], &event[iEmt], &event[iRec], name, radBeforeFlav, 0, 0, 0));
3649 
3650  } // doWeakClustering
3651 
3652  return;
3653 
3654 }
3655 
3656 
3657 //--------------------------------------------------------------------------
3658 
3659 // Function to construct (rad,rec,emt) triples from the event
3660 // IN int : Position of Emitted in event record for which
3661 // dipoles should be constructed
3662 // int : Colour topogy to be tested
3663 // 1= g -> qqbar, causing 2 -> 2 dipole splitting
3664 // 2= q(bar) -> q(bar) g && g -> gg,
3665 // causing a 2 -> 3 dipole splitting
3666 // Event : event record to be checked for ptential partners
3667 // OUT vector of all allowed radiator+recoiler+emitted triples
3668 
3669 vector<DireClustering> DireHistory::getClusterings (int emt, int rad,
3670  const Event& event ) {
3671 
3672  vector<DireClustering> clus;
3673 
3674  // Check if this configuration is result of a splitting.
3675  bool isFSR(false), isISR(false), hasShowers(fsr && isr),
3676  hasPartonLevel(showers && showers->timesPtr && showers->spacePtr);
3677  if (hasPartonLevel) {
3678  isFSR = showers->timesPtr->allowedSplitting(event, rad, emt);
3679  isISR = showers->spacePtr->allowedSplitting(event, rad, emt);
3680  } else if (hasShowers) {
3681  isFSR = fsr->allowedSplitting(event, rad, emt);
3682  isISR = isr->allowedSplitting(event, rad, emt);
3683  }
3684 
3685  if ( isFSR ) {
3686  vector<string> names = hasPartonLevel
3687  ? showers->timesPtr->getSplittingName(event,rad,emt,0)
3688  : hasShowers ? fsr->getSplittingName(event,rad,emt,0) : vector<string>();
3689  for ( int iName=0; iName < int(names.size()); ++iName) {
3690  vector<int> recsNow = hasPartonLevel
3691  ? showers->timesPtr->getRecoilers(event, rad, emt, names[iName])
3692  : (hasShowers ? fsr->getRecoilers(event, rad, emt, names[iName])
3693  : vector<int>());
3694  for ( int i = 0; i < int(recsNow.size()); ++i ) {
3695  if ( allowedClustering( rad, emt, recsNow[i], recsNow[i],
3696  names[iName], event) ) {
3697  double pT = pTLund(event, rad, emt, recsNow[i], names[iName]);
3698  attachClusterings (clus, emt, rad, recsNow[i], recsNow[i], pT,
3699  names[iName], event);
3700  }
3701  }
3702  }
3703  }
3704 
3705  if ( isISR ) {
3706  vector<string> names = hasPartonLevel
3707  ? showers->spacePtr->getSplittingName(event,rad,emt,0)
3708  : hasShowers ? isr->getSplittingName(event,rad,emt,0) : vector<string>();
3709 
3710  for ( int iName=0; iName < int(names.size()); ++iName) {
3711  vector<int> recsNow = hasPartonLevel
3712  ? showers->spacePtr->getRecoilers(event, rad, emt, names[iName])
3713  : (hasShowers ? isr->getRecoilers(event, rad, emt, names[iName])
3714  : vector<int>());
3715  for ( int i = 0; i < int(recsNow.size()); ++i ) {
3716  if ( allowedClustering( rad, emt, recsNow[i], recsNow[i],
3717  names[iName], event) ) {
3718  attachClusterings (clus, emt, rad, recsNow[i], recsNow[i],
3719  pTLund(event, rad, emt, recsNow[i], names[iName]),
3720  names[iName], event);
3721  }
3722  }
3723  }
3724  }
3725 
3726  // Done
3727  return clus;
3728 }
3729 
3730 //--------------------------------------------------------------------------
3731 
3732 // Calculate and return the probability of a clustering.
3733 // IN Clustering : rad,rec,emt - System for which the splitting
3734 // probability should be calcuated
3735 // OUT splitting probability
3736 
3737 pair<double,double> DireHistory::getProb(const DireClustering & SystemIn) {
3738 
3739  // Get local copies of input system
3740  int rad = SystemIn.radPos();
3741  int rec = SystemIn.recPos();
3742  int emt = SystemIn.emtPos();
3743  string name = SystemIn.name();
3744 
3745  // If the splitting resulted in disallowed evolution variable,
3746  // disallow the splitting
3747  if (SystemIn.pT() <= 0.) { return make_pair(1.,0.);}
3748 
3749  double pr(0.), coupling(1.);
3750 
3751  bool isFSR(false), isISR(false), hasShowers(fsr && isr),
3752  hasPartonLevel(showers && showers->timesPtr && showers->spacePtr);
3753  if (hasPartonLevel) {
3754  isFSR = showers->timesPtr->isTimelike(state, rad, emt, rec, "");
3755  isISR = showers->spacePtr->isSpacelike(state, rad, emt, rec, "");
3756  } else if (hasShowers) {
3757  isFSR = fsr->isTimelike(state, rad, emt, rec, "");
3758  isISR = isr->isSpacelike(state, rad, emt, rec, "");
3759  }
3760 
3761  name += "-0";
3762 
3763  if (isFSR) {
3764 
3765  // Ask shower for splitting probability.
3766  pr += hasPartonLevel
3767  ? showers->timesPtr->getSplittingProb( state, rad, emt, rec, name)
3768  : hasShowers ? fsr->getSplittingProb( state, rad, emt, rec, name) : 0.;
3769 
3770  // Scale with correct coupling factor.
3771  double mu2Ren = pow2(mergingHooksPtr->muR());
3772  name=name.substr( 0, name.size()-2);
3773  coupling = fsr->getCoupling( mu2Ren, name);
3774 
3775  }
3776 
3777  if (isISR) {
3778 
3779  // Ask shower for splitting probability.
3780  pr += hasPartonLevel
3781  ? showers->spacePtr->getSplittingProb( state, rad, emt, rec, name)
3782  : hasShowers ? isr->getSplittingProb( state, rad, emt, rec, name) : 0.;
3783 
3784  // Scale with correct coupling factor.
3785  double mu2Ren = pow2(mergingHooksPtr->muR());
3786  name=name.substr( 0, name.size()-2);
3787  coupling = isr->getCoupling( mu2Ren, name);
3788 
3789  }
3790 
3791  // Done.
3792  return make_pair(coupling,pr);
3793 
3794 }
3795 
3796 //--------------------------------------------------------------------------
3797 
3798 // Set up the beams (fill the beam particles with the correct
3799 // current incoming particles) to allow calculation of splitting
3800 // probability.
3801 // For interleaved evolution, set assignments dividing PDFs into
3802 // sea and valence content. This assignment is, until a history path
3803 // is chosen and a first trial shower performed, not fully correct
3804 // (since content is chosen form too high x and too low scale). The
3805 // assignment used for reweighting will be corrected after trial
3806 // showering
3807 
3808 void DireHistory::setupBeams() {
3809 
3810  // Do nothing for empty event, possible if sequence of
3811  // clusterings was ill-advised in that it results in
3812  // colour-disconnected states
3813  if (state.size() < 4) return;
3814 
3815  // Do nothing for e+e- beams
3816  if ( state[3].colType() == 0 && state[4].colType() == 0 ) return;
3817 
3818  // Incoming partons to hard process are stored in slots 3 and 4.
3819  int inS = 0;
3820  int inP = 0;
3821  int inM = 0;
3822  for(int i=0;i< int(state.size()); ++i) {
3823  if (state[i].mother1() == 1) inP = i;
3824  if (state[i].mother1() == 2) inM = i;
3825  }
3826 
3827  // Save some info before clearing beams
3828  // Mothers of incoming partons companion code
3829  int motherPcompRes = -1;
3830  int motherMcompRes = -1;
3831 
3832  bool sameFlavP = false;
3833  bool sameFlavM = false;
3834 
3835  if (mother) {
3836  int inMotherP = 0;
3837  int inMotherM = 0;
3838  for(int i=0;i< int(mother->state.size()); ++i) {
3839  if (mother->state[i].mother1() == 1) inMotherP = i;
3840  if (mother->state[i].mother1() == 2) inMotherM = i;
3841  }
3842  sameFlavP = (state[inP].id() == mother->state[inMotherP].id());
3843  sameFlavM = (state[inM].id() == mother->state[inMotherM].id());
3844 
3845  motherPcompRes = (sameFlavP) ? beamA[0].companion() : -2;
3846  motherMcompRes = (sameFlavM) ? beamB[0].companion() : -2;
3847  }
3848 
3849  // Append the current incoming particles to the beam
3850  beamA.clear();
3851  beamB.clear();
3852 
3853  // Get energy of incoming particles
3854  double Ep = 2. * state[inP].e();
3855  double Em = 2. * state[inM].e();
3856 
3857  // If incoming partons are massive then recalculate to put them massless.
3858  if (state[inP].m() != 0. || state[inM].m() != 0.) {
3859  Ep = state[inP].pPos() + state[inM].pPos();
3860  Em = state[inP].pNeg() + state[inM].pNeg();
3861  }
3862 
3863  // Add incoming hard-scattering partons to list in beam remnants.
3864  double x1 = Ep / state[inS].m();
3865  beamA.append( inP, state[inP].id(), x1);
3866  double x2 = Em / state[inS].m();
3867  beamB.append( inM, state[inM].id(), x2);
3868 
3869  // Scale. For ME multiplicity history, put scale to mu_F
3870  // (since sea/valence quark content is chosen from this scale)
3871  double scalePDF = (mother) ? scale : infoPtr->QFac();
3872  // Find whether incoming partons are valence or sea. Store.
3873  // Can I do better, e.g. by setting the scale to the hard process
3874  // scale (= M_W) or by replacing one of the x values by some x/z??
3875  beamA.xfISR( 0, state[inP].id(), x1, scalePDF*scalePDF);
3876  if (!mother) {
3877  beamA.pickValSeaComp();
3878  } else {
3879  beamA[0].companion(motherPcompRes);
3880  }
3881  beamB.xfISR( 0, state[inM].id(), x2, scalePDF*scalePDF);
3882  if (!mother) {
3883  beamB.pickValSeaComp();
3884  } else {
3885  beamB[0].companion(motherMcompRes);
3886  }
3887 
3888 }
3889 
3890 //--------------------------------------------------------------------------
3891 
3892 // Calculate the PDF ratio used in the argument of the no-emission
3893 // probability
3894 
3895 double DireHistory::pdfForSudakov() {
3896 
3897  // Do nothing for e+e- beams
3898  if ( state[3].colType() == 0 ) return 1.0;
3899  if ( state[4].colType() == 0 ) return 1.0;
3900 
3901  // Check if splittings was ISR or FSR
3902  bool FSR = ( mother->state[clusterIn.emittor].isFinal()
3903  && mother->state[clusterIn.recoiler].isFinal());
3904  bool FSRinRec = ( mother->state[clusterIn.emittor].isFinal()
3905  && !mother->state[clusterIn.recoiler].isFinal());
3906 
3907  // Done for pure FSR
3908  if (FSR) return 1.0;
3909 
3910  int iInMother = (FSRinRec)? clusterIn.recoiler : clusterIn.emittor;
3911  // Find side of event that was reclustered
3912  int side = ( mother->state[iInMother].pz() > 0 ) ? 1 : -1;
3913 
3914  int inP = 0;
3915  int inM = 0;
3916  for(int i=0;i< int(state.size()); ++i) {
3917  if (state[i].mother1() == 1) inP = i;
3918  if (state[i].mother1() == 2) inM = i;
3919  }
3920 
3921  // Save mother id
3922  int idMother = mother->state[iInMother].id();
3923  // Find daughter position and id
3924  int iDau = (side == 1) ? inP : inM;
3925  int idDaughter = state[iDau].id();
3926  // Get mother x value
3927  double xMother = 2. * mother->state[iInMother].e() / mother->state[0].e();
3928  // Get daughter x value of daughter
3929  double xDaughter = 2.*state[iDau].e() / state[0].e(); // x1 before isr
3930 
3931  // Calculate pdf ratio
3932  double ratio = getPDFratio(side, true, false, idMother, xMother, scale,
3933  idDaughter, xDaughter, scale);
3934 
3935  // For FSR with incoming recoiler, maximally return 1.0, as
3936  // is done in Pythia::TimeShower.
3937  // For ISR, return ratio
3938  return ( (FSRinRec)? min(1.,ratio) : ratio);
3939 }
3940 
3941 //--------------------------------------------------------------------------
3942 
3943 // Calculate the hard process matrix element to include in the selection
3944 // probability.
3945 
3946 double DireHistory::hardProcessME( const Event& event ) {
3947 
3948  // Calculate prob for Drell-Yan process.
3949  if (isEW2to1(event)) {
3950 
3951  // qqbar -> W.
3952  if (event[5].idAbs() == 24) {
3953  int idIn1 = event[3].id();
3954  int idIn2 = event[4].id();
3955  double mW = particleDataPtr->m0(24);
3956  double gW = particleDataPtr->mWidth(24) / mW;
3957  double sH = (event[3].p()+event[4].p()).m2Calc();
3958 
3959  double thetaWRat = 1. / (12. * coupSMPtr->sin2thetaW());
3960  double ckmW = coupSMPtr->V2CKMid(abs(idIn1), abs(idIn2));
3961 
3962  double bwW = 12. * M_PI / ( pow2(sH - pow2(mW)) + pow2(sH * gW) );
3963  double preFac = thetaWRat * sqrt(sH) * particleDataPtr->mWidth(24);
3964  return ckmW * preFac * bwW;
3965  }
3966 
3967  // qqbar -> Z. No interference with gamma included.
3968  else if (event[5].idAbs() == 23) {
3969  double mZ = particleDataPtr->m0(23);
3970  double gZ = particleDataPtr->mWidth(23) / mZ;
3971  double sH = (event[3].p()+event[4].p()).m2Calc();
3972  int flav = (mother) ? abs(clusterIn.flavRadBef) : event[3].idAbs();
3973  double thetaZRat =
3974  (pow2(coupSMPtr->rf( flav )) + pow2(coupSMPtr->lf( flav ))) /
3975  (24. * coupSMPtr->sin2thetaW() * coupSMPtr->cos2thetaW());
3976  double bwW = 12. * M_PI / ( pow2(sH - pow2(mZ)) + pow2(sH * gZ) );
3977  double preFac = thetaZRat * sqrt(sH) * particleDataPtr->mWidth(23);
3978  return preFac * bwW;
3979  }
3980 
3981  else {
3982  string message="Warning in DireHistory::hardProcessME: Only Z/W are";
3983  message+=" supported as 2->1 processes. Skipping history.";
3984  infoPtr->errorMsg(message);
3985  return 0;
3986  }
3987  }
3988  // 2 to 2 process, assume QCD.
3989  else if (isQCD2to2(event)) {
3990  int idIn1 = event[3].id();
3991  int idIn2 = event[4].id();
3992  int idOut1 = event[5].id();
3993  int idOut2 = event[6].id();
3994 
3995  double sH = (event[3].p()+event[4].p()).m2Calc();
3996  double tH = (event[3].p()-event[5].p()).m2Calc();
3997  double uH = (event[3].p()-event[6].p()).m2Calc();
3998 
3999  // Verify that it is QCD.
4000  bool isQCD = true;
4001  if (!(abs(idIn1) < 10 || abs(idIn1) == 21) ) isQCD = false;
4002  if (!(abs(idIn2) < 10 || abs(idIn2) == 21) ) isQCD = false;
4003  if (!(abs(idOut1) < 10 || abs(idOut1) == 21) ) isQCD = false;
4004  if (!(abs(idOut2) < 10 || abs(idOut2) == 21) ) isQCD = false;
4005 
4006  // Overall phase-space constant (dsigma/dcos(theta)).
4007  //double cor = M_PI / (9. * pow2(sH));
4008  double cor = 1. / (9. * pow2(sH));
4009 
4010  // Multiply with overall factor (g_s^4) / (16Pi^2) = as^2
4011  double mu2Ren = pow2(mergingHooksPtr->muR());
4012  cor *= pow2( mergingHooksPtr->AlphaS_ISR()->alphaS(mu2Ren) );
4013 
4014  // If it is QCD calculate cross section.
4015  if (isQCD) {
4016  // Find out which 2->2 process it is.
4017 
4018  // incoming gluon pair.
4019  if (abs(idIn1) == 21 && abs(idIn2) == 21) {
4020  if (abs(idOut1) == 21 && abs(idOut2) == 21)
4021  return cor * weakShowerMEs.getMEgg2gg(sH, tH, uH);
4022  else return cor * weakShowerMEs.getMEgg2qqbar(sH, tH, uH);
4023 
4024  // Incoming single gluon
4025  } else if (abs(idIn1) == 21 || abs(idIn2) == 21) {
4026  if (idIn1 != idOut1) swap(uH, tH);
4027  return cor * weakShowerMEs.getMEqg2qg(sH, tH, uH);
4028  }
4029 
4030  // Incoming quarks
4031  else {
4032  if (abs(idOut1) == 21 && abs(idOut2) == 21) {
4033  return cor * weakShowerMEs.getMEqqbar2gg(sH, tH, uH);
4034  }
4035 
4036  if (idIn1 == -idIn2) {
4037  if (abs(idIn1) == abs(idOut1)) {
4038  if (idIn1 != idOut1) swap(uH, tH);
4039  return cor * weakShowerMEs.getMEqqbar2qqbar(sH, tH, uH, true);
4040  }
4041  else {
4042  return cor * weakShowerMEs.getMEqqbar2qqbar(sH, tH, uH, false);
4043  }
4044  }
4045  else if (idIn1 == idIn2)
4046  return cor * weakShowerMEs.getMEqq2qq(sH, tH, uH, true);
4047  else {
4048  if (idIn1 == idOut1) swap(uH,tH);
4049  return cor * weakShowerMEs.getMEqq2qq(sH, tH, uH, false);
4050  }
4051  }
4052  }
4053  }
4054 
4055  // Hard process MEs for DIS.
4056  if ( isDIS2to2(event) ) {
4057 
4058  //int iIncEl(0), iOutEl(0), iIncP(0), iOutP(0);
4059  int iIncEl(0), iOutEl(0), iIncP(0);
4060  for ( int i=0; i < event.size(); ++i ) {
4061  if ( event[i].idAbs() == 11 ) {
4062  if ( event[i].status() == -21 ) iIncEl = i;
4063  if ( event[i].isFinal() ) iOutEl = i;
4064  }
4065  if ( event[i].colType() != 0 ) {
4066  if ( event[i].status() == -21 ) iIncP = i;
4067  //if ( event[i].isFinal() ) iOutP = i;
4068  }
4069  }
4070  Vec4 pgam( event[iIncEl].p() - event[iOutEl].p() );
4071  Vec4 pprot( (event[iIncP].mother1() == 1) ? event[1].p() : event[2].p() );
4072  double s = pow2(event[0].m());
4073  double Q2 = -pgam.m2Calc();
4074  double y = (pprot*pgam) / (pprot*event[iIncEl].p());
4075  double x = Q2 / (2.*pprot*pgam);
4076  double res = 4.*M_PI / (s*pow2(x)*pow2(y))*(1. - y + 0.5*pow2(y));
4077  return res;
4078 
4079  // 2 to 2 process, assume QCD.
4080  } else if (isMassless2to2(event)) {
4081  int idIn1 = event[3].id();
4082  int idIn2 = event[4].id();
4083  int idOut1 = event[5].id();
4084  int idOut2 = event[6].id();
4085 
4086  double sH = (event[3].p()+event[4].p()).m2Calc();
4087  double tH = (event[3].p()-event[5].p()).m2Calc();
4088  double uH = (event[3].p()-event[6].p()).m2Calc();
4089 
4090  // Verify that it is QCD.
4091  int inc1Type = particleDataPtr->colType(idIn1);
4092  int inc2Type = particleDataPtr->colType(idIn2);
4093  int out1Type = particleDataPtr->colType(idOut1);
4094  int out2Type = particleDataPtr->colType(idOut2);
4095  bool isQCD = (inc1Type*inc2Type*out1Type*out2Type != 0);
4096 
4097  // Overall phase-space constant (dsigma/dcos(theta)).
4098  double cor = M_PI / (9. * pow2(sH));
4099 
4100  // If it is QCD calculate cross section.
4101  if (isQCD) {
4102  // Find out which 2->2 process it is.
4103 
4104  // incoming gluon pair.
4105  if (abs(idIn1) == 21 && abs(idIn2) == 21) {
4106  if (abs(idOut1) == 21 && abs(idOut2) == 21)
4107  return cor * weakShowerMEs.getMEgg2gg(sH, tH, uH);
4108  else return cor * weakShowerMEs.getMEgg2qqbar(sH, tH, uH);
4109 
4110  // Incoming single gluon
4111  } else if (abs(idIn1) == 21 || abs(idIn2) == 21) {
4112  if (idIn1 != idOut1) swap(uH, tH);
4113  return cor * weakShowerMEs.getMEqg2qg(sH, tH, uH);
4114  }
4115 
4116  // Incoming quarks
4117  else {
4118  if (abs(idOut1) == 21 && abs(idOut2) == 21)
4119  return cor * weakShowerMEs.getMEqqbar2gg(sH, tH, uH);
4120  if (idIn1 == -idIn2) {
4121  if (abs(idIn1) == abs(idOut1)) {
4122  if (idIn1 != idOut1) swap(uH, tH);
4123  return cor * weakShowerMEs.getMEqqbar2qqbar(sH, tH, uH, true);
4124  }
4125  else {
4126  return cor * weakShowerMEs.getMEqqbar2qqbar(sH, tH, uH, false);
4127  }
4128  }
4129  else if (idIn1 == idIn2)
4130  return cor * weakShowerMEs.getMEqq2qq(sH, tH, uH, true);
4131  else {
4132  if (idIn1 == idOut1) swap(uH,tH);
4133  return cor * weakShowerMEs.getMEqq2qq(sH, tH, uH, false);
4134  }
4135  }
4136  }
4137 
4138  // Photon-gluon scattering, use gg->qq~ as proxy.
4139  if ( (idIn1 == 21 && idIn2 == 22) || (idIn1 == 22 && idIn2 == 21) )
4140  return cor * weakShowerMEs.getMEgg2qqbar(sH, tH, uH);
4141 
4142  // Photon-quark scattering, use gq->gq as proxy.
4143  if ( (abs(idIn1) < 10 && idIn2 == 22) || (idIn1 == 22 && abs(idIn2) < 10)){
4144  if (idIn1 != idOut1) swap(uH, tH);
4145  return cor * weakShowerMEs.getMEqg2qg(sH, tH, uH);
4146  }
4147 
4148  }
4149 
4150  // Get hard process.
4151  string process = mergingHooksPtr->getProcessString();
4152  double result = 1.;
4153 
4154  if ( process.compare("pp>e+ve") == 0
4155  || process.compare("pp>e-ve~") == 0
4156  || process.compare("pp>LEPTONS,NEUTRINOS") == 0 ) {
4157  // Do nothing for incomplete process.
4158  int nFinal = 0;
4159  for ( int i=0; i < int(event.size()); ++i )
4160  if ( event[i].isFinal() ) nFinal++;
4161  if ( nFinal != 2 ) return 1.;
4162  // Get W-boson mass and width.
4163  double mW = particleDataPtr->m0(24);
4164  double gW = particleDataPtr->mWidth(24) / mW;
4165  // Get incoming particles.
4166  int inP = (event[3].pz() > 0) ? 3 : 4;
4167  int inM = (event[3].pz() > 0) ? 4 : 3;
4168  // Get outgoing particles.
4169  int outP = 0;
4170  for ( int i=0; i < int(event.size()); ++i ) {
4171  if ( event[i].isFinal() && event[i].px() > 0 ) outP = i;
4172  }
4173  // Get Mandelstam variables.
4174  double sH = (event[inP].p() + event[inM].p()).m2Calc();
4175  double tH = (event[inP].p() - event[outP].p()).m2Calc();
4176  double uH = - sH - tH;
4177 
4178  // Return kinematic part of matrix element.
4179  result = ( 1. + (tH - uH)/sH ) / ( pow2(sH - mW*mW) + pow2(sH*gW) );
4180  } else
4181  result = mergingHooksPtr->hardProcessME(event);
4182 
4183  return result;
4184 
4185 }
4186 
4187 //--------------------------------------------------------------------------
4188 
4189 // Function to return the couplings present in the hard process ME (for correct
4190 // relative normalization of histories with different hard process, coupling
4191 // should be stripped off).
4192 
4193 double DireHistory::hardProcessCouplings( const Event& event, int order,
4194  double scale2, AlphaStrong* alphaS, AlphaEM* alphaEM,
4195  bool fillCouplCounters, bool with2Pi) {
4196 
4197  vector<int> nwp, nwm, nz, nh, na, nl, nlq, ng, nq, nqb;
4198  int in1(0), in2(0);
4199  for (int i=0; i < event.size(); ++i) {
4200  if (event[i].mother1() == 1 && event[i].mother2() == 0) in1 = i;
4201  if (event[i].mother1() == 2 && event[i].mother2() == 0) in2 = i;
4202  if (event[i].isFinal()) {
4203  if (event[i].id() == 21) ng.push_back(i);
4204  if (event[i].id() == 22) na.push_back(i);
4205  if (event[i].id() == 23) nz.push_back(i);
4206  if (event[i].id() == 24) nwp.push_back(i);
4207  if (event[i].id() ==-24) nwm.push_back(i);
4208  if (event[i].id() == 25) nh.push_back(i);
4209  if (event[i].isLepton()) nl.push_back(i);
4210  if (event[i].colType() == 1) nq.push_back(i);
4211  if (event[i].colType() ==-1) nqb.push_back(i);
4212  }
4213  }
4214 
4215  double twopi = (with2Pi) ? 2.*M_PI : 1.;
4216  double as2pi = (order == 0)
4217  ? infoPtr->settingsPtr->parm("SigmaProcess:alphaSvalue")/twopi
4218  : alphaS->alphaS(scale2)/twopi;
4219  double aem2pi = (order == 0)
4220  ? infoPtr->settingsPtr->parm("StandardModel:alphaEM0")/twopi
4221  : alphaEM->alphaEM(scale2)/twopi;
4222 
4223  double result = 1.;
4224  // One power of aEM for each outgoing photon.
4225  result *= pow(aem2pi,na.size());
4226  if (fillCouplCounters) couplingPowCount["qed"]+=na.size();
4227  // One power of aEM for each outgoing W- and Z-boson.
4228  result *= pow(aem2pi,nwp.size()+nwm.size()+nz.size());
4229  if (fillCouplCounters) couplingPowCount["qed"]+=nwp.size()+nwm.size()+
4230  nz.size();
4231  // One power of aS for each outgoing gluon.
4232  result *= pow(as2pi,ng.size());
4233  if (fillCouplCounters) couplingPowCount["qcd"]+=ng.size();
4234 
4235  // Couplings for outgoing quarks.
4236  if (
4237  (event[in1].colType() == 0 && event[in2].colType() == 0)
4238  && (nq.size() == 1 && nqb.size() == 1)
4239  && (event[nq[0]].id() == -event[nqb[0]].id()) ) {
4240  // Two powers of aEM for single quark pair coupling to incoming
4241  // lepton pair.
4242  result *= pow(aem2pi,2.0);
4243  if (fillCouplCounters) couplingPowCount["qed"]+=2;
4244  } else if (
4245  (event[in1].colType() == 0 && event[in2].colType() == 1)
4246  && (nq.size() == 1 && event[in2].id() == event[nq[0]].id()) ) {
4247  // Two powers of aEM for eq->eq scattering.
4248  result *= pow(aem2pi,2.0);
4249  if (fillCouplCounters) couplingPowCount["qed"]+=2;
4250  } else if (
4251  (event[in2].colType() == 0 && event[in1].colType() == 1)
4252  && (nq.size() == 1 && event[in1].id() == event[nq[0]].id()) ) {
4253  // Two powers of aEM for eq->eq scattering.
4254  result *= pow(aem2pi,2.0);
4255  if (fillCouplCounters) couplingPowCount["qed"]+=2;
4256  } else if (
4257  (event[in1].colType() == 0 && event[in2].colType() ==-1)
4258  && (nqb.size() == 1 && event[in2].id() == event[nqb[0]].id()) ) {
4259  // Two powers of aEM for eqbar->eqbar scattering.
4260  result *= pow(aem2pi,2.0);
4261  if (fillCouplCounters) couplingPowCount["qed"]+=2;
4262  } else if (
4263  (event[in2].colType() == 0 && event[in1].colType() ==-1)
4264  && (nqb.size() == 1 && event[in1].id() == event[nqb[0]].id()) ) {
4265  // Two powers of aEM for eq->eq scattering.
4266  result *= pow(aem2pi,2.0);
4267  if (fillCouplCounters) couplingPowCount["qed"]+=2;
4268  } else {
4269  // One power of aS for each outgoing quark/antiquark.
4270  result *= pow(as2pi,nq.size()+nqb.size());
4271  if (fillCouplCounters) couplingPowCount["qcd"]+=nq.size()+nqb.size();
4272  }
4273 
4274  // Coupling for outgoing Higgs to initial state.
4275  if ( nh.size() > 0 ) {
4276 
4277  double sH = event[nh.front()].m2Calc();
4278  double mH = sqrt(sH);
4279 
4280  double width = 0.;
4281  if (event[in1].id() == event[in2].id() && event[in1].id() == 21)
4282  width = particleDataPtr->particleDataEntryPtr(25)->resWidthChan(
4283  mH,21,21)/64;
4284  else if (event[in1].id() == -event[in2].id() && event[in1].idAbs() < 9)
4285  width = particleDataPtr->particleDataEntryPtr(25)->resWidthChan(
4286  mH, event[in1].id(), -event[in1].id()) / 9.;
4287  else if (event[in1].id() == 21 && event[in2].idAbs() < 9)
4288  width = max(particleDataPtr->particleDataEntryPtr(25)->resWidthChan(
4289  mH, 21, 21) / 64,
4290  particleDataPtr->particleDataEntryPtr(25)->resWidthChan(
4291  mH, event[in1].id(), -event[in1].id()) / 9.);
4292  else if (event[in2].id() == 21 && event[in1].idAbs() < 9)
4293  width = max(particleDataPtr->particleDataEntryPtr(25)->resWidthChan(
4294  mH, 21, 21) / 64,
4295  particleDataPtr->particleDataEntryPtr(25)->resWidthChan(
4296  mH, event[in2].id(), -event[in2].id()) / 9.);
4297 
4298  double m2Res = pow2(particleDataPtr->m0(25));
4299  double widthTot = particleDataPtr->particleDataEntryPtr(25)->
4300  resWidth(25,mH);
4301 
4302  // Check if Higgs can couple to final state
4303  if (width/widthTot < 1e-4) {
4304 
4305  for (int i=0; i < event.size(); ++i) {
4306  if (i != nh.front() && event[i].isFinal()) {
4307  int sign = particleDataPtr->hasAnti(event[i].id()) ? -1 : 1;
4308  double widthNew = particleDataPtr->particleDataEntryPtr(25)->
4309  resWidthChan( mH, event[i].id(), sign*event[i].id());
4310  if (event[i].id() == 21) widthNew /= 64.;
4311  if (event[i].idAbs() < 9) widthNew /= 9.;
4312  if (widthNew/widthTot > 1e-4 && widthNew/widthTot > width/widthTot){
4313  width = widthNew; break;
4314  }
4315  }
4316  }
4317 
4318  }
4319 
4320  // Also remove Breit-Wigner (since contained in clustering probability)
4321  double sigBW = 8. * M_PI/ ( pow2(sH - m2Res) + pow2(mH * widthTot) );
4322 
4323  // Discard things with extremely small branching fraction.
4324  if (width/widthTot < 1e-4) width = 0.;
4325 
4326  double asRatio = (order==0) ? 1.
4327  : pow2(alphaS->alphaS(scale2)/alphaS->alphaS(125.*125.));
4328  double res = pow(width*sigBW*asRatio,nh.size());
4329 
4330  result *= res;
4331  if (fillCouplCounters) {
4332  couplingPowCount["qcd"]+=2;
4333  couplingPowCount["heft"]++;
4334  }
4335  }
4336 
4337  return result;
4338 
4339 }
4340 
4341 //--------------------------------------------------------------------------
4342 
4343 double DireHistory::hardProcessScale( const Event& event) {
4344 
4345  // Find the mT in the hard sub-process.
4346  double nFinal(0.), mTprod(1.);
4347  for ( int i=0; i < event.size(); ++i)
4348  if ( event[i].isFinal() ) {
4349  nFinal += 1.;
4350  mTprod *= abs(event[i].mT());
4351  }
4352  double hardScale = (mTprod!=1.) ? pow(mTprod, 1./nFinal) : infoPtr->QRen();
4353 
4354  // Done.
4355  return hardScale;
4356 
4357 }
4358 
4359 //--------------------------------------------------------------------------
4360 
4361 // Perform the clustering of the current state and return the
4362 // clustered state.
4363 // IN Clustering : rad,rec,emt triple to be clustered to two partons
4364 // OUT clustered state
4365 
4366 Event DireHistory::cluster( DireClustering & inSystem ) {
4367 
4368  // Initialise tags of particles to be changed
4369  int rad = inSystem.radPos();
4370  int rec = inSystem.recPos();
4371  int emt = inSystem.emtPos();
4372  string name = inSystem.name();
4373 
4374  // Construct the clustered event
4375  Event newEvent = Event();
4376  newEvent.init("(hard process-modified)", particleDataPtr);
4377  newEvent.clear();
4378 
4379  bool isFSR(false), hasShowers(fsr && isr),
4380  hasPartonLevel(showers && showers->timesPtr && showers->spacePtr);
4381  if (hasPartonLevel) {
4382  isFSR = showers->timesPtr->isTimelike(state, rad, emt, rec, "");
4383  } else if (hasShowers) {
4384  isFSR = fsr->isTimelike(state, rad, emt, rec, "");
4385  }
4386 
4387  if (isFSR) {
4388  newEvent = (hasPartonLevel
4389  ? showers->timesPtr->clustered( state, rad, emt, rec, name)
4390  : hasShowers ? fsr->clustered( state, rad, emt, rec, name)
4391  : newEvent);
4392  } else {
4393  newEvent = (hasPartonLevel
4394  ? showers->spacePtr->clustered( state, rad, emt, rec, name)
4395  : hasShowers ? isr->clustered( state, rad, emt, rec, name)
4396  : newEvent);
4397  }
4398 
4399  // Store radiator and recoiler positions.
4400  if (newEvent.size() > 0) {
4401  inSystem.recBef = newEvent[0].mother2();
4402  inSystem.radBef = newEvent[0].mother1();
4403  newEvent[0].mothers(0,0);
4404  }
4405 
4406  // Done
4407  return newEvent;
4408 }
4409 
4410 //--------------------------------------------------------------------------
4411 
4412 // Function to get the flavour of the radiator before the splitting
4413 // for clustering
4414 // IN int : Flavour of the radiator after the splitting
4415 // int : Flavour of the emitted after the splitting
4416 // OUT int : Flavour of the radiator before the splitting
4417 
4418 int DireHistory::getRadBeforeFlav(const int RadAfter, const int EmtAfter,
4419  const Event& event) {
4420 
4421  int type = event[RadAfter].isFinal() ? 1 :-1;
4422  int emtID = event[EmtAfter].id();
4423  int radID = event[RadAfter].id();
4424  int emtCOL = event[EmtAfter].col();
4425  int radCOL = event[RadAfter].col();
4426  int emtACL = event[EmtAfter].acol();
4427  int radACL = event[RadAfter].acol();
4428 
4429  bool colConnected = ((type == 1) && ( (emtCOL !=0 && (emtCOL ==radACL))
4430  || (emtACL !=0 && (emtACL ==radCOL)) ))
4431  ||((type ==-1) && ( (emtCOL !=0 && (emtCOL ==radCOL))
4432  || (emtACL !=0 && (emtACL ==radACL)) ));
4433  // QCD splittings
4434  // Gluon radiation
4435  if ( emtID == 21 )
4436  return radID;
4437  // Final state gluon splitting
4438  if ( type == 1 && emtID == -radID && !colConnected )
4439  return 21;
4440  // Initial state s-channel gluon splitting
4441  if ( type ==-1 && radID == 21 )
4442  return -emtID;
4443  // Initial state t-channel gluon splitting
4444  if ( type ==-1 && !colConnected && radID != 21 && abs(emtID) < 10
4445  && abs(radID) < 10)
4446  return 21;
4447 
4448  // SQCD splittings
4449  int radSign = (radID < 0) ? -1 : 1;
4450  int offsetL = 1000000;
4451  int offsetR = 2000000;
4452  // Gluino radiation
4453  if ( emtID == 1000021 ) {
4454  // Gluino radiation combined with quark yields squark.
4455  if (abs(radID) < 10 ) {
4456  int offset = offsetL;
4457  // Check if righthanded squark present. If so, make the reclustered
4458  // squark match. Works for squark pair production + gluino emission.
4459  for (int i=0; i < int(event.size()); ++i)
4460  if ( event[i].isFinal()
4461  && event[i].idAbs() < offsetR+10 && event[i].idAbs() > offsetR)
4462  offset = offsetR;
4463  return radSign*(abs(radID)+offset);
4464  }
4465  // Gluino radiation combined with squark yields quark.
4466  if (abs(radID) > offsetL && abs(radID) < offsetL+10 )
4467  return radSign*(abs(radID)-offsetL);
4468  if (abs(radID) > offsetR && abs(radID) < offsetR+10 )
4469  return radSign*(abs(radID)-offsetR);
4470  // Gluino radiation off gluon yields gluino.
4471  if (radID == 21 ) return emtID;
4472  }
4473 
4474  int emtSign = (emtID < 0) ? -1 : 1;
4475  // Get PDG numbering offsets.
4476  int emtOffset = 0;
4477  if ( abs(emtID) > offsetL && abs(emtID) < offsetL+10 )
4478  emtOffset = offsetL;
4479  if ( abs(emtID) > offsetR && abs(emtID) < offsetR+10 )
4480  emtOffset = offsetR;
4481  int radOffset = 0;
4482  if ( abs(radID) > offsetL && abs(radID) < offsetL+10 )
4483  radOffset = offsetL;
4484  if ( abs(radID) > offsetR && abs(radID) < offsetR+10 )
4485  radOffset = offsetR;
4486 
4487  // Final state gluino splitting
4488  if ( type == 1 && !colConnected ) {
4489  // Emitted squark, radiating quark.
4490  if ( emtOffset > 0 && radOffset == 0
4491  && emtSign*(abs(emtID) - emtOffset) == -radID )
4492  return 1000021;
4493  // Emitted quark, radiating squark.
4494  if ( emtOffset == 0 && radOffset > 0
4495  && emtID == -radSign*(abs(radID) - radOffset) )
4496  return 1000021;
4497  }
4498 
4499  // Initial state s-channel gluino splitting
4500  if ( type ==-1 && radID == 1000021 ) {
4501  // Quark entering underlying hard process.
4502  if ( emtOffset > 0 ) return -emtSign*(abs(emtID) - emtOffset);
4503  // Squark entering underlying hard process.
4504  else return -emtSign*(abs(emtID) + emtOffset);
4505  }
4506 
4507  // Initial state t-channel gluino splitting.
4508  if ( type ==-1
4509  && ( (abs(emtID) > offsetL && abs(emtID) < offsetL+10)
4510  || (abs(emtID) > offsetR && abs(emtID) < offsetR+10))
4511  && ( (abs(radID) > offsetL && abs(radID) < offsetL+10)
4512  || (abs(radID) > offsetR && abs(radID) < offsetR+10))
4513  && emtSign*(abs(emtID)+emtOffset) == radSign*(abs(radID) - radOffset)
4514  && !colConnected ) {
4515  return 1000021;
4516  }
4517 
4518  // Electroweak splittings splittings
4519  // Photon / Z radiation: Calculate invariant mass of system
4520  double m2final = (event[RadAfter].p()+ event[EmtAfter].p()).m2Calc();
4521 
4522  if ( emtID == 22 || emtID == 23 ) return radID;
4523  // Final state Photon splitting
4524  if ( type == 1 && emtID == -radID && colConnected && sqrt(m2final) <= 10. )
4525  return 22;
4526  // Final state Photon splitting
4527  if ( type == 1 && emtID == -radID && colConnected && sqrt(m2final) > 10. )
4528  return 23;
4529  // Initial state s-channel photon/ Z splitting
4530  if ( type ==-1 && (radID == 22 || radID == 23) )
4531  return -emtID;
4532  // Initial state t-channel photon / Z splitting: Always bookkeep as photon
4533  if ( type ==-1 && abs(emtID) < 10 && abs(radID) < 10 && colConnected )
4534  return 22;
4535 
4536  // W+ radiation
4537  // Final state W+ splitting
4538  if ( emtID == 24 && radID < 0 ) return radID + 1;
4539  if ( emtID == 24 && radID > 0 ) return radID + 1;
4540 
4541  // W- radiation
4542  // Final state W- splitting
4543  if ( emtID ==-24 && radID < 0 ) return radID - 1;
4544  if ( emtID ==-24 && radID > 0 ) return radID - 1;
4545 
4546  // Done.
4547  return 0;
4548 
4549 }
4550 
4551 //--------------------------------------------------------------------------
4552 
4553 // Function to get the spin of the radiator before the splitting
4554 // IN int : Spin of the radiator after the splitting
4555 // int : Spin of the emitted after the splitting
4556 // OUT int : Spin of the radiator before the splitting
4557 
4558 int DireHistory::getRadBeforeSpin(const int radAfter, const int emtAfter,
4559  const int spinRadAfter, const int spinEmtAfter,
4560  const Event& event) {
4561 
4562  // Get flavour before the splitting.
4563  int radBeforeFlav = getRadBeforeFlav(radAfter, emtAfter, event);
4564 
4565  // Gluon in final state g-> q qbar
4566  if ( event[radAfter].isFinal()
4567  && event[radAfter].id() == -event[emtAfter].id())
4568  return (spinRadAfter == 9) ? spinEmtAfter : spinRadAfter;
4569 
4570  // Quark in final state q -> q g
4571  if ( event[radAfter].isFinal() && abs(radBeforeFlav) < 10
4572  && event[radAfter].idAbs() < 10)
4573  // Special oddity: Gluon does not change spin.
4574  return spinRadAfter;
4575 
4576  // Quark in final state q -> g q
4577  if ( event[radAfter].isFinal() && abs(radBeforeFlav) < 10
4578  && event[emtAfter].idAbs() < 10)
4579  // Special oddity: Gluon does not change spin.
4580  return spinEmtAfter;
4581 
4582  // Gluon in final state g -> g g
4583  if ( event[radAfter].isFinal() && radBeforeFlav == 21
4584  && event[radAfter].id() == 21)
4585  // Special oddity: Gluon does not change spin.
4586  return (spinRadAfter == 9) ? spinEmtAfter : spinRadAfter;
4587 
4588  // Gluon in initial state g-> q qbar
4589  if ( !event[radAfter].isFinal()
4590  && radBeforeFlav == -event[emtAfter].id())
4591  return (spinRadAfter == 9) ? spinEmtAfter : spinRadAfter;
4592 
4593  // Quark in initial state q -> q g
4594  if ( !event[radAfter].isFinal() && abs(radBeforeFlav) < 10
4595  && event[radAfter].idAbs() < 10)
4596  // Special oddity: Gluon does not change spin.
4597  return spinRadAfter;
4598 
4599  // Gluon in initial state q -> g q
4600  if ( !event[radAfter].isFinal() && radBeforeFlav == 21
4601  && event[emtAfter].idAbs() < 10)
4602  // Special oddity: Gluon does not change spin.
4603  return spinEmtAfter;
4604 
4605  // Done. Return default value.
4606  return 9;
4607 
4608 }
4609 
4610 //--------------------------------------------------------------------------
4611 
4612 // Function to properly colour-connect the radiator to the rest of
4613 // the event, as needed during clustering
4614 // IN Particle& : Particle to be connected
4615 // Particle : Recoiler forming a dipole with Radiator
4616 // Event : event to which Radiator shall be appended
4617 // OUT true : Radiator could be connected to the event
4618 // false : Radiator could not be connected to the
4619 // event or the resulting event was
4620 // non-valid
4621 
4622 bool DireHistory::connectRadiator( Particle& Radiator, const int RadType,
4623  const Particle& Recoiler, const int RecType,
4624  const Event& event ) {
4625 
4626  // Start filling radiator colour indices with dummy values
4627  Radiator.cols( -1, -1 );
4628 
4629  // Radiator should always be colour-connected to recoiler.
4630  // Three cases (rad = Anti-Quark, Quark, Gluon) to be considered
4631  if ( Radiator.colType() == -1 ) {
4632  // For final state antiquark radiator, the anticolour is fixed
4633  // by the final / initial state recoiler colour / anticolour
4634  if ( RadType + RecType == 2 )
4635  Radiator.cols( 0, Recoiler.col());
4636  else if ( RadType + RecType == 0 )
4637  Radiator.cols( 0, Recoiler.acol());
4638  // For initial state antiquark radiator, the anticolour is fixed
4639  // by the colour of the emitted gluon (which will be the
4640  // leftover anticolour of a final state particle or the leftover
4641  // colour of an initial state particle ( = the recoiler))
4642  else {
4643  // Set colour of antiquark radiator to zero
4644  Radiator.col( 0 );
4645  for (int i = 0; i < event.size(); ++i) {
4646  int col = event[i].col();
4647  int acl = event[i].acol();
4648 
4649  if ( event[i].isFinal()) {
4650  // Search for leftover anticolour in final / initial state
4651  if ( acl > 0 && FindCol(acl,i,0,event,1,true) == 0
4652  && FindCol(acl,i,0,event,2,true) == 0 )
4653  Radiator.acol(event[i].acol());
4654  } else {
4655  // Search for leftover colour in initial / final state
4656  if ( col > 0 && FindCol(col,i,0,event,1,true) == 0
4657  && FindCol(col,i,0,event,2,true) == 0 )
4658  Radiator.acol(event[i].col());
4659  }
4660  } // end loop over particles in event record
4661  }
4662 
4663  } else if ( Radiator.colType() == 1 ) {
4664  // For final state quark radiator, the colour is fixed
4665  // by the final / initial state recoiler anticolour / colour
4666  if ( RadType + RecType == 2 )
4667  Radiator.cols( Recoiler.acol(), 0);
4668 
4669  else if ( RadType + RecType == 0 )
4670  Radiator.cols( Recoiler.col(), 0);
4671  // For initial state quark radiator, the colour is fixed
4672  // by the anticolour of the emitted gluon (which will be the
4673  // leftover colour of a final state particle or the leftover
4674  // anticolour of an initial state particle ( = the recoiler))
4675 
4676  else {
4677  // Set anticolour of quark radiator to zero
4678  Radiator.acol( 0 );
4679  for (int i = 0; i < event.size(); ++i) {
4680  int col = event[i].col();
4681  int acl = event[i].acol();
4682 
4683  if ( event[i].isFinal()) {
4684  // Search for leftover colour in final / initial state
4685  if ( col > 0 && FindCol(col,i,0,event,1,true) == 0
4686  && FindCol(col,i,0,event,2,true) == 0)
4687  Radiator.col(event[i].col());
4688  } else {
4689  // Search for leftover anticolour in initial / final state
4690  if ( acl > 0 && FindCol(acl,i,0,event,1,true) == 0
4691  && FindCol(acl,i,0,event,2,true) == 0)
4692  Radiator.col(event[i].acol());
4693  }
4694  } // end loop over particles in event record
4695 
4696  } // end distinction between fsr / fsr+initial recoiler / isr
4697 
4698  } else if ( Radiator.colType() == 2 ) {
4699  // For a gluon radiator, one (anticolour) colour index is defined
4700  // by the recoiler colour (anticolour).
4701  // The remaining index is chosen to match the free index in the
4702  // event
4703  // Search for leftover colour (anticolour) in the final state
4704  for (int i = 0; i < event.size(); ++i) {
4705  int col = event[i].col();
4706  int acl = event[i].acol();
4707  int iEx = i;
4708 
4709  if ( event[i].isFinal()) {
4710  if ( col > 0 && FindCol(col,iEx,0,event,1,true) == 0
4711  && FindCol(col,iEx,0,event,2,true) == 0) {
4712  if (Radiator.status() < 0 ) Radiator.col(event[i].col());
4713  else Radiator.acol(event[i].col());
4714  }
4715  if ( acl > 0 && FindCol(acl,iEx,0,event,2,true) == 0
4716  && FindCol(acl,iEx,0,event,1,true) == 0 ) {
4717  if (Radiator.status() < 0 ) Radiator.acol(event[i].acol());
4718  else Radiator.col(event[i].acol());
4719  }
4720  } else {
4721  if ( col > 0 && FindCol(col,iEx,0,event,1,true) == 0
4722  && FindCol(col,iEx,0,event,2,true) == 0) {
4723  if (Radiator.status() < 0 ) Radiator.acol(event[i].col());
4724  else Radiator.col(event[i].col());
4725  }
4726  if ( acl > 0 && (FindCol(acl,iEx,0,event,2,true) == 0
4727  && FindCol(acl,iEx,0,event,1,true) == 0)) {
4728  if (Radiator.status() < 0 ) Radiator.col(event[i].acol());
4729  else Radiator.acol(event[i].acol());
4730  }
4731  }
4732  } // end loop over particles in event record
4733  } // end cases of different radiator colour type
4734 
4735  // If either colour or anticolour has not been set, return false
4736  if (Radiator.col() < 0 || Radiator.acol() < 0) return false;
4737  // Done
4738  return true;
4739 }
4740 
4741 //--------------------------------------------------------------------------
4742 
4743 // Function to find a colour (anticolour) index in the input event
4744 // IN int col : Colour tag to be investigated
4745 // int iExclude1 : Identifier of first particle to be excluded
4746 // from search
4747 // int iExclude2 : Identifier of second particle to be excluded
4748 // from search
4749 // Event event : event to be searched for colour tag
4750 // int type : Tag to define if col should be counted as
4751 // colour (type = 1) [->find anti-colour index
4752 // contracted with col]
4753 // anticolour (type = 2) [->find colour index
4754 // contracted with col]
4755 // OUT int : Position of particle in event record
4756 // contraced with col [0 if col is free tag]
4757 
4758 int DireHistory::FindCol(int col, int iExclude1, int iExclude2,
4759  const Event& event, int type, bool isHardIn) {
4760 
4761  bool isHard = isHardIn;
4762  int index = 0;
4763 
4764  if (isHard) {
4765  // Search event record for matching colour & anticolour
4766  for(int n = 0; n < event.size(); ++n) {
4767  if ( n != iExclude1 && n != iExclude2
4768  && event[n].colType() != 0
4769  &&( event[n].status() > 0 // Check outgoing
4770  || event[n].status() == -21) ) { // Check incoming
4771  if ( event[n].acol() == col ) {
4772  index = -n;
4773  break;
4774  }
4775  if ( event[n].col() == col ) {
4776  index = n;
4777  break;
4778  }
4779  }
4780  }
4781  } else {
4782 
4783  // Search event record for matching colour & anticolour
4784  for(int n = 0; n < event.size(); ++n) {
4785  if ( n != iExclude1 && n != iExclude2
4786  && event[n].colType() != 0
4787  &&( event[n].status() == 43 // Check outgoing from ISR
4788  || event[n].status() == 51 // Check outgoing from FSR
4789  || event[n].status() == -41 // first initial
4790  || event[n].status() == -42) ) { // second initial
4791  if ( event[n].acol() == col ) {
4792  index = -n;
4793  break;
4794  }
4795  if ( event[n].col() == col ) {
4796  index = n;
4797  break;
4798  }
4799  }
4800  }
4801  }
4802  // if no matching colour / anticolour has been found, return false
4803  if ( type == 1 && index < 0) return abs(index);
4804  if ( type == 2 && index > 0) return abs(index);
4805 
4806  return 0;
4807 }
4808 
4809 //--------------------------------------------------------------------------
4810 
4811 // Function to in the input event find a particle with quantum
4812 // numbers matching those of the input particle
4813 // IN Particle : Particle to be searched for
4814 // Event : Event to be searched in
4815 // OUT int : > 0 : Position of matching particle in event
4816 // < 0 : No match in event
4817 
4818 int DireHistory::FindParticle( const Particle& particle, const Event& event,
4819  bool checkStatus ) {
4820 
4821  int index = -1;
4822 
4823  for ( int i = int(event.size()) - 1; i > 0; --i )
4824  if ( event[i].id() == particle.id()
4825  && event[i].colType() == particle.colType()
4826  && event[i].chargeType() == particle.chargeType()
4827  && event[i].col() == particle.col()
4828  && event[i].acol() == particle.acol()
4829  && event[i].charge() == particle.charge() ) {
4830  index = i;
4831  break;
4832  }
4833 
4834  if ( checkStatus && event[index].status() != particle.status() )
4835  index = -1;
4836 
4837  return index;
4838 }
4839 
4840 //--------------------------------------------------------------------------
4841 
4842 // Function to get the colour of the radiator before the splitting
4843 // for clustering
4844 // IN int : Position of the radiator after the splitting, in the event
4845 // int : Position of the emitted after the splitting, in the event
4846 // Event : Reference event
4847 // OUT int : Colour of the radiator before the splitting
4848 
4849 int DireHistory::getRadBeforeCol(const int rad, const int emt,
4850  const Event& event) {
4851 
4852  // Save type of splitting
4853  int type = (event[rad].isFinal()) ? 1 :-1;
4854  // Get flavour of radiator after potential clustering
4855  int radBeforeFlav = getRadBeforeFlav(rad,emt,event);
4856  // Get colours of the radiator before the potential clustering
4857  int radBeforeCol = -1;
4858  // Get reconstructed gluon colours
4859  if (radBeforeFlav == 21) {
4860 
4861  // Start with quark emissions in FSR
4862  if (type == 1 && event[emt].id() != 21) {
4863  radBeforeCol = (event[rad].col() > 0)
4864  ? event[rad].col() : event[emt].col();
4865  // Quark emissions in ISR
4866  } else if (type == -1 && event[emt].id() != 21) {
4867  radBeforeCol = (event[rad].col() > 0)
4868  ? event[rad].col() : event[emt].acol();
4869  //Gluon emissions in FSR
4870  } else if (type == 1 && event[emt].id() == 21) {
4871  // If emitted is a gluon, remove the repeated index, and take
4872  // the remaining indices as colour and anticolour
4873  int colRemove = (event[rad].col() == event[emt].acol())
4874  ? event[rad].col() : event[rad].acol();
4875  radBeforeCol = (event[rad].col() == colRemove)
4876  ? event[emt].col() : event[rad].col();
4877  //Gluon emissions in ISR
4878  } else if (type == -1 && event[emt].id() == 21) {
4879  // If emitted is a gluon, remove the repeated index, and take
4880  // the remaining indices as colour and anticolour
4881  int colRemove = (event[rad].col() == event[emt].col())
4882  ? event[rad].col() : event[rad].acol();
4883  radBeforeCol = (event[rad].col() == colRemove)
4884  ? event[emt].acol() : event[rad].col();
4885  }
4886 
4887  // Get reconstructed quark colours
4888  } else if ( radBeforeFlav > 0) {
4889 
4890  // Quark emission in FSR
4891  if (type == 1 && event[emt].id() != 21) {
4892  // If radiating is a quark, remove the repeated index, and take
4893  // the remaining indices as colour and anticolour
4894  int colRemove = (event[rad].col() == event[emt].acol())
4895  ? event[rad].acol() : 0;
4896  radBeforeCol = (event[rad].col() == colRemove)
4897  ? event[emt].col() : event[rad].col();
4898  //Gluon emissions in FSR
4899  } else if (type == 1 && event[emt].id() == 21) {
4900  // If emitted is a gluon, remove the repeated index, and take
4901  // the remaining indices as colour and anticolour
4902  int colRemove = (event[rad].col() == event[emt].acol())
4903  ? event[rad].col() : 0;
4904  radBeforeCol = (event[rad].col() == colRemove)
4905  ? event[emt].col() : event[rad].col();
4906  //Quark emissions in ISR
4907  } else if (type == -1 && event[emt].id() != 21) {
4908  // If emitted is a quark, remove the repeated index, and take
4909  // the remaining indices as colour and anticolour
4910  int colRemove = (event[rad].col() == event[emt].col())
4911  ? event[rad].col() : 0;
4912  radBeforeCol = (event[rad].col() == colRemove)
4913  ? event[emt].acol() : event[rad].col();
4914  //Gluon emissions in ISR
4915  } else if (type == -1 && event[emt].id() == 21) {
4916  // If emitted is a gluon, remove the repeated index, and take
4917  // the remaining indices as colour and anticolour
4918  int colRemove = (event[rad].col() == event[emt].col())
4919  ? event[rad].col() : 0;
4920  radBeforeCol = (event[rad].col() == colRemove)
4921  ? event[emt].acol() : event[rad].col();
4922  }
4923  // Other particles are assumed uncoloured
4924  } else {
4925  radBeforeCol = 0;
4926  }
4927 
4928  return radBeforeCol;
4929 
4930 }
4931 
4932 //--------------------------------------------------------------------------
4933 
4934 // Function to get the anticolour of the radiator before the splitting
4935 // for clustering
4936 // IN int : Position of the radiator after the splitting, in the event
4937 // int : Position of the emitted after the splitting, in the event
4938 // Event : Reference event
4939 // OUT int : Anticolour of the radiator before the splitting
4940 
4941 int DireHistory::getRadBeforeAcol(const int rad, const int emt,
4942  const Event& event) {
4943 
4944  // Save type of splitting
4945  int type = (event[rad].isFinal()) ? 1 :-1;
4946  // Get flavour of radiator after potential clustering
4947 
4948  int radBeforeFlav = getRadBeforeFlav(rad,emt,event);
4949  // Get colours of the radiator before the potential clustering
4950  int radBeforeAcl = -1;
4951  // Get reconstructed gluon colours
4952  if (radBeforeFlav == 21) {
4953 
4954  // Start with quark emissions in FSR
4955  if (type == 1 && event[emt].id() != 21) {
4956  radBeforeAcl = (event[rad].acol() > 0)
4957  ? event[rad].acol() : event[emt].acol();
4958  // Quark emissions in ISR
4959  } else if (type == -1 && event[emt].id() != 21) {
4960  radBeforeAcl = (event[rad].acol() > 0)
4961  ? event[rad].acol() : event[emt].col();
4962  //Gluon emissions in FSR
4963  } else if (type == 1 && event[emt].id() == 21) {
4964  // If emitted is a gluon, remove the repeated index, and take
4965  // the remaining indices as colour and anticolour
4966  int colRemove = (event[rad].col() == event[emt].acol())
4967  ? event[rad].col() : event[rad].acol();
4968  radBeforeAcl = (event[rad].acol() == colRemove)
4969  ? event[emt].acol() : event[rad].acol();
4970  //Gluon emissions in ISR
4971  } else if (type == -1 && event[emt].id() == 21) {
4972  // If emitted is a gluon, remove the repeated index, and take
4973  // the remaining indices as colour and anticolour
4974  int colRemove = (event[rad].col() == event[emt].col())
4975  ? event[rad].col() : event[rad].acol();
4976  radBeforeAcl = (event[rad].acol() == colRemove)
4977  ? event[emt].col() : event[rad].acol();
4978  }
4979 
4980  // Get reconstructed anti-quark colours
4981  } else if ( radBeforeFlav < 0) {
4982 
4983  // Antiquark emission in FSR
4984  if (type == 1 && event[emt].id() != 21) {
4985  // If radiating is a antiquark, remove the repeated index, and take
4986  // the remaining indices as colour and anticolour
4987  int colRemove = (event[rad].col() == event[emt].acol())
4988  ? event[rad].acol() : 0;
4989  radBeforeAcl = (event[rad].acol() == colRemove)
4990  ? event[emt].acol() : event[rad].acol();
4991  //Gluon emissions in FSR
4992  } else if (type == 1 && event[emt].id() == 21) {
4993  // If emitted is a gluon, remove the repeated index, and take
4994  // the remaining indices as colour and anticolour
4995  int colRemove = (event[rad].acol() == event[emt].col())
4996  ? event[rad].acol() : 0;
4997  radBeforeAcl = (event[rad].acol() == colRemove)
4998  ? event[emt].acol() : event[rad].acol();
4999  //Antiquark emissions in ISR
5000  } else if (type == -1 && event[emt].id() != 21) {
5001  // If emitted is an antiquark, remove the repeated index, and take
5002  // the remaining indices as colour and anticolour
5003  int colRemove = (event[rad].acol() == event[emt].acol())
5004  ? event[rad].acol() : 0;
5005  radBeforeAcl = (event[rad].acol() == colRemove)
5006  ? event[emt].col() : event[rad].acol();
5007  //Gluon emissions in ISR
5008  } else if (type == -1 && event[emt].id() == 21) {
5009  // If emitted is a gluon, remove the repeated index, and take
5010  // the remaining indices as colour and anticolour
5011  int colRemove = (event[rad].acol() == event[emt].acol())
5012  ? event[rad].acol() : 0;
5013  radBeforeAcl = (event[rad].acol() == colRemove)
5014  ? event[emt].col() : event[rad].acol();
5015  }
5016  // Other particles are considered uncoloured
5017  } else {
5018  radBeforeAcl = 0;
5019  }
5020 
5021  return radBeforeAcl;
5022 
5023 }
5024 
5025 //--------------------------------------------------------------------------
5026 
5027  // Function to get the parton connected to in by a colour line
5028  // IN int : Position of parton for which partner should be found
5029  // Event : Reference event
5030  // OUT int : If a colour line connects the "in" parton with another
5031  // parton, return the Position of the partner, else return 0
5032 
5033 int DireHistory::getColPartner(const int in, const Event& event) {
5034 
5035  if (event[in].col() == 0) return 0;
5036 
5037  int partner = 0;
5038  // Try to find anticolour index first
5039  partner = FindCol(event[in].col(),in,0,event,1,true);
5040  // If no anticolour index has been found, try colour
5041  if (partner == 0)
5042  partner = FindCol(event[in].col(),in,0,event,2,true);
5043 
5044  return partner;
5045 
5046 }
5047 
5048 //--------------------------------------------------------------------------
5049 
5050 
5051  // Function to get the parton connected to in by an anticolour line
5052  // IN int : Position of parton for which partner should be found
5053  // Event : Reference event
5054  // OUT int : If an anticolour line connects the "in" parton with another
5055  // parton, return the Position of the partner, else return 0
5056 
5057 int DireHistory::getAcolPartner(const int in, const Event& event) {
5058 
5059  if (event[in].acol() == 0) return 0;
5060 
5061  int partner = 0;
5062  // Try to find colour index first
5063  partner = FindCol(event[in].acol(),in,0,event,2,true);
5064  // If no colour index has been found, try anticolour
5065  if (partner == 0)
5066  partner = FindCol(event[in].acol(),in,0,event,1,true);
5067 
5068  return partner;
5069 
5070 }
5071 
5072 //--------------------------------------------------------------------------
5073 
5074 // Function to get the list of partons connected to the particle
5075 // formed by reclusterinf emt and rad by colour and anticolour lines
5076 // IN int : Position of radiator in the clustering
5077 // IN int : Position of emitted in the clustering
5078 // Event : Reference event
5079 // OUT vector<int> : List of positions of all partons that are connected
5080 // to the parton that will be formed
5081 // by clustering emt and rad.
5082 
5083 vector<int> DireHistory::getReclusteredPartners(const int rad, const int emt,
5084  const Event& event) {
5085 
5086  // Save type
5087  int type = event[rad].isFinal() ? 1 : -1;
5088  // Get reclustered colours
5089  int radBeforeCol = getRadBeforeCol(rad, emt, event);
5090  int radBeforeAcl = getRadBeforeAcol(rad, emt, event);
5091  // Declare output
5092  vector<int> partners;
5093 
5094 
5095  // Start with FSR clusterings
5096  if (type == 1) {
5097 
5098  for(int i=0; i < int(event.size()); ++i) {
5099  // Check all initial state partons
5100  if ( i != emt && i != rad
5101  && event[i].status() == -21
5102  && event[i].col() > 0
5103  && event[i].col() == radBeforeCol)
5104  partners.push_back(i);
5105  // Check all final state partons
5106  if ( i != emt && i != rad
5107  && event[i].isFinal()
5108  && event[i].acol() > 0
5109  && event[i].acol() == radBeforeCol)
5110  partners.push_back(i);
5111  // Check all initial state partons
5112  if ( i != emt && i != rad
5113  && event[i].status() == -21
5114  && event[i].acol() > 0
5115  && event[i].acol() == radBeforeAcl)
5116  partners.push_back(i);
5117  // Check all final state partons
5118  if ( i != emt && i != rad
5119  && event[i].isFinal()
5120  && event[i].col() > 0
5121  && event[i].col() == radBeforeAcl)
5122  partners.push_back(i);
5123  }
5124  // Start with ISR clusterings
5125  } else {
5126 
5127  for(int i=0; i < int(event.size()); ++i) {
5128  // Check all initial state partons
5129  if ( i != emt && i != rad
5130  && event[i].status() == -21
5131  && event[i].acol() > 0
5132  && event[i].acol() == radBeforeCol)
5133  partners.push_back(i);
5134  // Check all final state partons
5135  if ( i != emt && i != rad
5136  && event[i].isFinal()
5137  && event[i].col() > 0
5138  && event[i].col() == radBeforeCol)
5139  partners.push_back(i);
5140  // Check all initial state partons
5141  if ( i != emt && i != rad
5142  && event[i].status() == -21
5143  && event[i].col() > 0
5144  && event[i].col() == radBeforeAcl)
5145  partners.push_back(i);
5146  // Check all final state partons
5147  if ( i != emt && i != rad
5148  && event[i].isFinal()
5149  && event[i].acol() > 0
5150  && event[i].acol() == radBeforeAcl)
5151  partners.push_back(i);
5152  }
5153 
5154  }
5155  // Done
5156  return partners;
5157 }
5158 
5159 //--------------------------------------------------------------------------
5160 
5161 // Function to extract a chain of colour-connected partons in
5162 // the event
5163 // IN int : Type of parton from which to start extracting a
5164 // parton chain. If the starting point is a quark
5165 // i.e. flavType = 1, a chain of partons that are
5166 // consecutively connected by colour-lines will be
5167 // extracted. If the starting point is an antiquark
5168 // i.e. flavType =-1, a chain of partons that are
5169 // consecutively connected by anticolour-lines
5170 // will be extracted.
5171 // IN int : Position of the parton from which a
5172 // colour-connected chain should be derived
5173 // IN Event : Refernence event
5174 // IN/OUT vector<int> : Partons that should be excluded from the search.
5175 // OUT vector<int> : Positions of partons along the chain
5176 // OUT bool : Found singlet / did not find singlet
5177 
5178 bool DireHistory::getColSinglet( const int flavType, const int iParton,
5179  const Event& event, vector<int>& exclude, vector<int>& colSinglet) {
5180 
5181  // If no possible flavour to start from has been found
5182  if (iParton < 0) return false;
5183 
5184  // If no further partner has been found in a previous iteration,
5185  // and the whole final state has been excluded, we're done
5186  if (iParton == 0) {
5187 
5188  // Count number of final state partons
5189  int nFinal = 0;
5190  for(int i=0; i < int(event.size()); ++i)
5191  if ( event[i].isFinal() && event[i].colType() != 0)
5192  nFinal++;
5193 
5194  // Get number of initial state partons in the list of
5195  // excluded partons
5196  int nExclude = int(exclude.size());
5197  int nInitExclude = 0;
5198  if (!event[exclude[2]].isFinal())
5199  nInitExclude++;
5200  if (!event[exclude[3]].isFinal())
5201  nInitExclude++;
5202 
5203  // If the whole final state has been considered, return
5204  if (nFinal == nExclude - nInitExclude)
5205  return true;
5206  else
5207  return false;
5208 
5209  }
5210 
5211  // Declare colour partner
5212  int colP = 0;
5213  // Save the colour partner
5214  colSinglet.push_back(iParton);
5215  // Remove the partner from the list
5216  exclude.push_back(iParton);
5217  // When starting out from a quark line, follow the colour lines
5218  if (flavType == 1)
5219  colP = getColPartner(iParton,event);
5220  // When starting out from an antiquark line, follow the anticolour lines
5221  else
5222  colP = getAcolPartner(iParton,event);
5223 
5224  // Do not count excluded partons twice
5225  for(int i = 0; i < int(exclude.size()); ++i)
5226  if (colP == exclude[i])
5227  return true;
5228 
5229  // Recurse
5230  return getColSinglet(flavType,colP,event,exclude,colSinglet);
5231 
5232 }
5233 
5234 //--------------------------------------------------------------------------
5235 
5236 // Function to check that a set of partons forms a colour singlet
5237 // IN Event : Reference event
5238 // IN vector<int> : Positions of the partons in the set
5239 // OUT bool : Is a colour singlet / is not
5240 
5241 bool DireHistory::isColSinglet( const Event& event,
5242  vector<int> system ) {
5243 
5244  // Check if system forms a colour singlet
5245  for(int i=0; i < int(system.size()); ++i ) {
5246  // Match quark and gluon colours
5247  if ( system[i] > 0
5248  && (event[system[i]].colType() == 1
5249  || event[system[i]].colType() == 2) ) {
5250  for(int j=0; j < int(system.size()); ++j)
5251  // If flavour matches, remove both partons and continue
5252  if ( system[j] > 0
5253  && event[system[i]].col() == event[system[j]].acol()) {
5254  // Remove index and break
5255  system[i] = 0;
5256  system[j] = 0;
5257  break;
5258  }
5259  }
5260  // Match antiquark and gluon anticolours
5261  if ( system[i] > 0
5262  && (event[system[i]].colType() == -1
5263  || event[system[i]].colType() == 2) ) {
5264  for(int j=0; j < int(system.size()); ++j)
5265  // If flavour matches, remove both partons and continue
5266  if ( system[j] > 0
5267  && event[system[i]].acol() == event[system[j]].col()) {
5268  // Remove index and break
5269  system[i] = 0;
5270  system[j] = 0;
5271  break;
5272  }
5273  }
5274 
5275  }
5276 
5277  // The system is a colour singlet if for all colours,
5278  // an anticolour was found
5279  bool isColSing = true;
5280  for(int i=0; i < int(system.size()); ++i)
5281  if ( system[i] != 0 )
5282  isColSing = false;
5283 
5284  // Return
5285  return isColSing;
5286 
5287 
5288 }
5289 
5290 //--------------------------------------------------------------------------
5291 
5292 // Function to check that a set of partons forms a flavour singlet
5293 // IN Event : Reference event
5294 // IN vector<int> : Positions of the partons in the set
5295 // IN int : Flavour of all the quarks in the set, if
5296 // all quarks in a set should have a fixed flavour
5297 // OUT bool : Is a flavour singlet / is not
5298 
5299 bool DireHistory::isFlavSinglet( const Event& event,
5300  vector<int> system, int flav) {
5301 
5302  // If a decoupled colour singlet has been found, check if this is also
5303  // a flavour singlet
5304  // Check that each quark matches an antiquark
5305  for(int i=0; i < int(system.size()); ++i)
5306  if ( system[i] > 0 ) {
5307  for(int j=0; j < int(system.size()); ++j) {
5308  // If flavour of outgoing partons matches,
5309  // remove both partons and continue.
5310  // Skip all bosons
5311  if ( event[i].idAbs() != 21
5312  && event[i].idAbs() != 22
5313  && event[i].idAbs() != 23
5314  && event[i].idAbs() != 24
5315  && system[j] > 0
5316  && event[system[i]].isFinal()
5317  && event[system[j]].isFinal()
5318  && event[system[i]].id() == -1*event[system[j]].id()) {
5319  // If we want to check if only one flavour of quarks
5320  // exists
5321  if (abs(flav) > 0 && event[system[i]].idAbs() != flav)
5322  return false;
5323  // Remove index and break
5324  system[i] = 0;
5325  system[j] = 0;
5326  break;
5327  }
5328  // If flavour of outgoing and incoming partons match,
5329  // remove both partons and continue.
5330  // Skip all bosons
5331  if ( event[i].idAbs() != 21
5332  && event[i].idAbs() != 22
5333  && event[i].idAbs() != 23
5334  && event[i].idAbs() != 24
5335  && system[j] > 0
5336  && event[system[i]].isFinal() != event[system[j]].isFinal()
5337  && event[system[i]].id() == event[system[j]].id()) {
5338  // If we want to check if only one flavour of quarks
5339  // exists
5340  if (abs(flav) > 0 && event[system[i]].idAbs() != flav)
5341  return false;
5342  // Remove index and break
5343  system[i] = 0;
5344  system[j] = 0;
5345  break;
5346  }
5347 
5348  }
5349  }
5350 
5351  // The colour singlet is a flavour singlet if for all quarks,
5352  // an antiquark was found
5353  bool isFlavSing = true;
5354  for(int i=0; i < int(system.size()); ++i)
5355  if ( system[i] != 0 )
5356  isFlavSing = false;
5357 
5358  // Return
5359  return isFlavSing;
5360 
5361 }
5362 
5363 //--------------------------------------------------------------------------
5364 
5365 // Function to check if rad,emt,rec triple is allowed for clustering
5366 // IN int rad,emt,rec : Positions (in event record) of the three
5367 // particles considered for clustering
5368 // Event event : Reference event
5369 
5370 bool DireHistory::allowedClustering( int rad, int emt, int rec, int partner,
5371  string name, const Event& event ) {
5372 
5373  // Declare output
5374  bool allowed = true;
5375 
5376  // CONSTRUCT SOME PROPERTIES FOR LATER INVESTIGATION
5377 
5378  // Check if the triple forms a colour singlett
5379  bool isSing = isSinglett(rad,emt,partner,event);
5380  bool hasColour = event[rad].colType() != 0 || event[emt].colType() != 0;
5381  int type = (event[rad].isFinal()) ? 1 :-1;
5382 
5383  // Use external shower for merging.
5384  map<string,double> stateVars;
5385 
5386  if (name.compare("Dire_fsr_qcd_1->21&1") == 0) swap(rad,emt);
5387  if (name.compare("Dire_fsr_qcd_1->22&1") == 0) swap(rad,emt);
5388  if (name.compare("Dire_fsr_qcd_11->22&11") == 0) swap(rad,emt);
5389 
5390  bool hasPartonLevel(showers && showers->timesPtr && showers->spacePtr),
5391  hasShowers(fsr && isr);
5392  if (hasPartonLevel) {
5393  bool isFSR = showers->timesPtr->isTimelike(event, rad, emt, rec, "");
5394  if (isFSR) stateVars = showers->timesPtr->getStateVariables
5395  (event,rad,emt,rec,name);
5396  else stateVars = showers->spacePtr->getStateVariables
5397  (event,rad,emt,rec,name);
5398  } else if (hasShowers) {
5399  bool isFSR = fsr->isTimelike(event, rad, emt, rec, "");
5400  if (isFSR) stateVars = fsr->getStateVariables(event,rad,emt,rec,name);
5401  else stateVars = isr->getStateVariables(event,rad,emt,rec,name);
5402  }
5403 
5404  // Get flavour of radiator after potential clustering
5405  int radBeforeFlav = int(stateVars["radBefID"]);
5406  // Get colours of the radiator before the potential clustering
5407  int radBeforeCol = int(stateVars["radBefCol"]);
5408  int radBeforeAcl = int(stateVars["radBefAcol"]);
5409 
5410  // Get colour partner of reclustered parton
5411  vector<int> radBeforeColP = getReclusteredPartners(rad, emt, event);
5412 
5413  // Only allow clustering if the evolution scale is well-defined.
5414  if ( stateVars["t"] < 0.0) return false;
5415 
5416  // Count coloured partons in hard process
5417  int nPartonInHard = 0;
5418  for(int i=0; i < int(event.size()); ++i)
5419  // Check all final state partons
5420  if ( event[i].isFinal()
5421  && event[i].colType() != 0
5422  && mergingHooksPtr->hardProcess->matchesAnyOutgoing(i, event) )
5423  nPartonInHard++;
5424 
5425  // Count coloured final state partons in event, excluding
5426  // rad, rec, emt and hard process
5427  int nPartons = 0;
5428  for(int i=0; i < int(event.size()); ++i)
5429  // Check all final state partons
5430  if ( i!=emt && i!=rad && i!=rec
5431  && event[i].isFinal()
5432  && event[i].colType() != 0
5433  && !mergingHooksPtr->hardProcess->matchesAnyOutgoing(i, event) )
5434  nPartons++;
5435 
5436  // Count number of initial state partons
5437  int nInitialPartons = 0;
5438  for(int i=0; i < int(event.size()); ++i)
5439  if ( event[i].status() == -21
5440  && event[i].colType() != 0 )
5441  nInitialPartons++;
5442 
5443  // Get number of non-charged final state particles
5444  int nFinalEW = 0;
5445  for(int i=0; i < int(event.size()); ++i)
5446  if ( event[i].isFinal()
5447  &&( event[i].id() == 22
5448  || event[i].id() == 23
5449  || event[i].idAbs() == 24
5450  ||(event[i].idAbs() > 10 && event[i].idAbs() < 20)
5451  ||(event[i].idAbs() > 1000010 && event[i].idAbs() < 1000020)
5452  ||(event[i].idAbs() > 2000010 && event[i].idAbs() < 2000020) ))
5453  nFinalEW++;
5454 
5455  int nFinalH = 0;
5456  for(int i=0; i < int(event.size()); ++i)
5457  if ( event[i].isFinal() && event[i].id() == 25)
5458  nFinalH++;
5459 
5460  // Check if event after potential clustering contains an even
5461  // number of quarks and/or antiquarks
5462  // (otherwise no electroweak vertex could be formed!)
5463  // Get number of final quarks
5464  int nFinalQuark = 0;
5465  // Get number of excluded final state quarks as well
5466  int nFinalQuarkExc = 0;
5467  for(int i=0; i < int(event.size()); ++i) {
5468  if (i !=rad && i != emt && i != rec) {
5469  if (event[i].isFinal() && abs(event[i].colType()) == 1 ) {
5470  if ( !mergingHooksPtr->hardProcess->matchesAnyOutgoing(i,event) )
5471  nFinalQuark++;
5472  else
5473  nFinalQuarkExc++;
5474  }
5475  }
5476  }
5477 
5478  // Add recoiler to number of final quarks
5479  if (event[rec].isFinal() && event[rec].isQuark()) nFinalQuark++;
5480  // Add radiator after clustering to number of final quarks
5481  if (event[rad].isFinal() && abs(radBeforeFlav) < 10) nFinalQuark++;
5482 
5483  // Get number of initial quarks
5484  int nInitialQuark = 0;
5485  if (type == 1) {
5486  if (event[rec].isFinal()) {
5487  if (event[3].isQuark()) nInitialQuark++;
5488  if (event[4].isQuark()) nInitialQuark++;
5489  } else {
5490  int iOtherIn = (rec == 3) ? 4 : 3;
5491  if (event[rec].isQuark()) nInitialQuark++;
5492  if (event[iOtherIn].isQuark()) nInitialQuark++;
5493  }
5494  } else {
5495  if (event[rec].isFinal()) {
5496  int iOtherIn = (rad == 3) ? 4 : 3;
5497  if (abs(radBeforeFlav) < 10) nInitialQuark++;
5498  if (event[iOtherIn].isQuark()) nInitialQuark++;
5499  } else {
5500  if (abs(radBeforeFlav) < 10) nInitialQuark++;
5501  if (event[rec].isQuark()) nInitialQuark++;
5502  }
5503  }
5504 
5505  // Get number of initial leptons.
5506  int nInitialLepton = 0;
5507  if (type == 1) {
5508  if (event[rec].isFinal()) {
5509  if (event[3].isLepton()) nInitialLepton++;
5510  if (event[4].isLepton()) nInitialLepton++;
5511  } else {
5512  int iOtherIn = (rec == 3) ? 4 : 3;
5513  if (event[rec].isLepton()) nInitialLepton++;
5514  if (event[iOtherIn].isLepton()) nInitialLepton++;
5515  }
5516  } else {
5517  // Add recoiler to number of initial quarks
5518  if (event[rec].isLepton()) nInitialLepton++;
5519  // Add radiator after clustering to number of initial quarks
5520  if (abs(radBeforeFlav) > 10 && abs(radBeforeFlav) < 20 ) nInitialLepton++;
5521  }
5522 
5523  // Store incoming and outgoing flavours after clustering.
5524  vector<int> in;
5525  for(int i=0; i < int(event.size()); ++i)
5526  if ( i!=emt && i!=rad && i!=rec
5527  && (event[i].mother1() == 1 || event[i].mother1() == 2))
5528  in.push_back(event[i].id());
5529  if (!event[rad].isFinal()) in.push_back(radBeforeFlav);
5530  if (!event[rec].isFinal()) in.push_back(event[rec].id());
5531  vector<int> out;
5532  for(int i=0; i < int(event.size()); ++i)
5533  if ( i!=emt && i!=rad && i!=rec && event[i].isFinal())
5534  out.push_back(event[i].id());
5535  if (event[rad].isFinal()) out.push_back(radBeforeFlav);
5536  if (event[rec].isFinal()) out.push_back(event[rec].id());
5537 
5538  // BEGIN CHECKING THE CLUSTERING
5539 
5540  // Do not allow clusterings that lead to a disallowed proton content.
5541  int proton[] = {1,2,3,4,5,21,22,23,24};
5542  bool isInProton = false;
5543  for(int i=0; i < 9; ++i)
5544  if (abs(radBeforeFlav) == proton[i]) isInProton = true;
5545  if ( type == -1 && particleDataPtr->colType(radBeforeFlav) != 0
5546  && !isInProton) return false;
5547 
5548  // Check if colour is conserved
5549  vector<int> unmatchedCol;
5550  vector<int> unmatchedAcl;
5551  // Check all unmatched colours
5552  for ( int i = 0; i < event.size(); ++i)
5553  if ( i != emt && i != rad
5554  && (event[i].isFinal() || event[i].status() == -21)
5555  && event[i].colType() != 0 ) {
5556 
5557  int colP = getColPartner(i,event);
5558  int aclP = getAcolPartner(i,event);
5559 
5560  if (event[i].col() > 0
5561  && (colP == emt || colP == rad || colP == 0) )
5562  unmatchedCol.push_back(i);
5563  if (event[i].acol() > 0
5564  && (aclP == emt || aclP == rad || aclP == 0) )
5565  unmatchedAcl.push_back(i);
5566 
5567  }
5568 
5569  // If more than one colour or more than one anticolour are unmatched,
5570  // there is no way to make this clustering work
5571  if (int(unmatchedCol.size()) + int(unmatchedAcl.size()) > 2)
5572  return false;
5573 
5574  // If triple forms colour singlett, check that resulting state
5575  // matches hard core process
5576  if (hasColour && isSing)
5577  allowed = false;
5578  if (hasColour && isSing && (abs(radBeforeFlav)<10 && event[rec].isQuark()) )
5579  allowed = true;
5580 
5581  // Colour singlet in DIS hard process
5582  if (hasColour && isSing && abs(radBeforeFlav)<10 && nPartons == 0
5583  && nInitialPartons == 1)
5584  allowed = true;
5585 
5586  // Never recluster any outgoing partons of the core V -> qqbar' splitting!
5587  if ( mergingHooksPtr->hardProcess->matchesAnyOutgoing(emt,event) ) {
5588  // Check if any other particle could replace "emt" as part of the candidate
5589  // core process. If so, replace emt with the new candidate and allow the
5590  // clustering.
5591  bool canReplace = mergingHooksPtr->hardProcess->findOtherCandidates(emt,
5592  event, true);
5593 
5594  if (canReplace) allowed = true;
5595  else allowed = false;
5596  }
5597 
5598  // Never remove so many particles that the hard process cannot
5599  // be set up afterwards.
5600  //int nIncPartHardProc = mergingHooksPtr->hardProcess->nQuarksIn();
5601  int nOutPartHardProc = mergingHooksPtr->hardProcess->nQuarksOut();
5602  // Add recoiler to number of final quarks
5603  int nOutPartNow(nPartons);
5604  // Add non-participating hard process partons.
5605  for(int i=0; i < int(event.size()); ++i)
5606  // Check all final state partons
5607  if ( i!=emt && i!=rad && i!=rec
5608  && event[i].isFinal()
5609  && event[i].colType() != 0
5610  && mergingHooksPtr->hardProcess->matchesAnyOutgoing(i, event) )
5611  nOutPartNow++;
5612  if (event[rec].isFinal() && event[rec].colType() != 0) nOutPartNow++;
5613  // Add radiator after clustering to number of final quarks
5614  if (event[rad].isFinal() && particleDataPtr->colType(radBeforeFlav) != 0)
5615  nOutPartNow++;
5616  if (nOutPartNow < nOutPartHardProc) allowed = false;
5617 
5618  // Never allow clustering of any outgoing partons of the hard process
5619  // which would change the flavour of one of the hard process partons!
5620  if ( mergingHooksPtr->hardProcess->matchesAnyOutgoing(rad,event)
5621  && event[rad].id() != radBeforeFlav )
5622  allowed = false;
5623 
5624  // If only gluons in initial state and no quarks in final state,
5625  // reject (no electroweak vertex can be formed)
5626  if ( nFinalEW != 0 && nInitialQuark == 0 && nFinalQuark == 0
5627  && nFinalQuarkExc == 0 && nInitialLepton == 0
5628  && !mayHaveEffectiveVertex( mergingHooksPtr->getProcessString(), in, out))
5629  allowed = false;
5630 
5631  if ( (nInitialQuark + nFinalQuark + nFinalQuarkExc)%2 != 0 )
5632  allowed = false;
5633 
5634  map<int,int> nIncIDs, nOutIDs;
5635  for ( int i = 0; i < event.size(); ++i) {
5636  if ( i != emt && i != rad && event[i].isFinal() ) {
5637  if (nOutIDs.find(event[i].id()) != nOutIDs.end() )
5638  nOutIDs[event[i].id()]++;
5639  else
5640  nOutIDs.insert(make_pair(event[i].id(),1));
5641  }
5642  if ( i != emt && i != rad && event[i].status() == -21 ){
5643  if (nIncIDs.find(event[i].id()) != nIncIDs.end() )
5644  nIncIDs[event[i].id()]++;
5645  else
5646  nIncIDs.insert(make_pair(event[i].id(),1));
5647  }
5648  }
5649  if (type > 0 ) {
5650  if (nOutIDs.find(radBeforeFlav) != nOutIDs.end()) nOutIDs[radBeforeFlav]++;
5651  else nOutIDs.insert(make_pair(radBeforeFlav,1));
5652  }
5653  if (type < 0 ) {
5654  if (nIncIDs.find(radBeforeFlav) != nIncIDs.end()) nIncIDs[radBeforeFlav]++;
5655  else nIncIDs.insert(make_pair(radBeforeFlav,1));
5656  }
5657 
5658  if (!canConnectFlavs(nIncIDs,nOutIDs) ) allowed = false;
5659 
5660  // Disallow clusterings that lead to a 2->1 massless state.
5661  // To check, only look at final state flavours.
5662  int nMassless(0), nOther(0);
5663  for ( map<int, int>::iterator it = nOutIDs.begin();
5664  it != nOutIDs.end(); ++it )
5665  if ( abs(it->first) < 20 || abs(it->first) == 21
5666  || abs(it->first) == 22) nMassless += it->second;
5667  else nOther++;
5668  if (nMassless == 1 && nOther == 0) allowed = false;
5669 
5670  // Disallow final state splittings that lead to a purely gluonic final
5671  // state, while having a completely colour-connected initial state.
5672  // This means that the clustering is discarded if it does not lead to the
5673  // t-channel gluon needed to connect the final state to a qq~ initial state.
5674  // Here, partons excluded from clustering are not counted as possible
5675  // partners to form a t-channel gluon
5676  if (event[3].col() == event[4].acol()
5677  && event[3].acol() == event[4].col()
5678  && !mayHaveEffectiveVertex( mergingHooksPtr->getProcessString(), in, out)
5679  && nFinalQuark == 0){
5680  // Careful if rad and rec are the only quarks in the final state, but
5681  // were both excluded from the list of final state quarks.
5682  int nTripletts = abs(event[rec].colType())
5683  + abs(particleDataPtr->colType(radBeforeFlav));
5684  if (event[3].isGluon()) allowed = false;
5685  else if (nTripletts != 2 && nFinalQuarkExc%2 == 0) allowed = false;
5686  }
5687 
5688  // Minimal phase space checks.
5689  if ( event[rad].isFinal() && event[rec].isFinal()
5690  && abs( ( event[rad].p() + event[emt].p() + event[rec].p()).pz())
5691  > ( event[rad].p() + event[emt].p() + event[rec].p()).e() )
5692  return false;
5693 
5694  if ( !event[rad].isFinal() && !event[rec].isFinal()
5695  && abs( ( event[rad].p() - event[emt].p() + event[rec].p()).pz())
5696  > ( event[rad].p() - event[emt].p() + event[rec].p()).e() )
5697  return false;
5698 
5699  if ( !event[rad].isFinal() && event[rec].isFinal()
5700  && -(-event[rad].p() + event[emt].p() + event[rec].p()).m2Calc() < 0.)
5701  return false;
5702 
5703  // Check that invariant mass of dipole is positive.
5704  // Initial-initial configuration.
5705  if ( !event[rad].isFinal() && !event[rec].isFinal()
5706  && (event[rad].p() - event[emt].p() + event[rec].p()).m2Calc() < 0.
5707  && abs((event[rad].p() - event[emt].p() + event[rec].p()).m2Calc()) > 1e-5)
5708  return false;
5709 
5710  // Initial-final configuration.
5711  if ( !event[rad].isFinal() && event[rec].isFinal()
5712  && -(event[rad].p() - event[emt].p() - event[rec].p()).m2Calc() < 0.
5713  && abs((event[rad].p() - event[emt].p() - event[rec].p()).m2Calc()) > 1e-5)
5714  return false;
5715 
5716  // Final-initial configuration.
5717  if ( event[rad].isFinal() && !event[rec].isFinal()
5718  && -(-event[rad].p() - event[emt].p() + event[rec].p()).m2Calc() < 0.
5719  && abs((-event[rad].p() - event[emt].p() + event[rec].p()).m2Calc())
5720  > 1e-5)
5721  return false;
5722 
5723  // Final-final configuration.
5724  if ( event[rad].isFinal() && event[rec].isFinal()
5725  && (event[rad].p() + event[emt].p() + event[rec].p()).m2Calc() < 0.)
5726  return false;
5727 
5728  // No problems with gluon radiation
5729  if (event[emt].id() == 21)
5730  return allowed;
5731 
5732  // No problems with photon / Z / Higgs radiation
5733  if (event[emt].id() == 22 || event[emt].id() == 23 || event[emt].id() == 25)
5734  return allowed;
5735 
5736  // No problems with gluino radiation
5737  if (event[emt].id() == 1000021)
5738  return allowed;
5739 
5740  // No problems if radiator is gluon, emitted is (anti)quark.
5741 
5742  // No problems if radiator is photon/Z/Higgs, and emitted is fermion.
5743 
5744  // No problems if radiator is gluino, and emitted is (anti)quark.
5745 
5746  // Save all hard process candidates
5747  vector<int> outgoingParticles;
5748  int nOut1 = int(mergingHooksPtr->hardProcess->PosOutgoing1.size());
5749  for ( int i=0; i < nOut1; ++i ) {
5750  int iPos = mergingHooksPtr->hardProcess->PosOutgoing1[i];
5751  outgoingParticles.push_back(
5752  mergingHooksPtr->hardProcess->state[iPos].id() );
5753  }
5754  int nOut2 = int(mergingHooksPtr->hardProcess->PosOutgoing2.size());
5755  for ( int i=0; i < nOut2; ++i ) {
5756  int iPos = mergingHooksPtr->hardProcess->PosOutgoing2[i];
5757  outgoingParticles.push_back(
5758  mergingHooksPtr->hardProcess->state[iPos].id() );
5759  }
5760 
5761  // Start more involved checks. g -> q_1 qbar_1 splittings are
5762  // particularly problematic if more than one quark of the emitted
5763  // flavour is present.
5764  // Count number of initial quarks of radiator or emitted flavour
5765  vector<int> iInQuarkFlav;
5766  for(int i=0; i < int(event.size()); ++i)
5767  // Check all initial state partons
5768  if ( i != emt && i != rad
5769  && event[i].status() == -21
5770  && event[i].idAbs() == event[emt].idAbs() )
5771  iInQuarkFlav.push_back(i);
5772 
5773  // Count number of final quarks of radiator or emitted flavour
5774  vector<int> iOutQuarkFlav;
5775  for(int i=0; i < int(event.size()); ++i)
5776  // Check all final state partons
5777  if ( i != emt && i != rad
5778  && event[i].isFinal()
5779  && event[i].idAbs() == event[emt].idAbs() ) {
5780 
5781  // Loop through final state hard particles. If one matches, remove the
5782  // matching one, and do not count.
5783  bool matchOut = false;
5784  for (int j = 0; j < int(outgoingParticles.size()); ++j)
5785  if ( event[i].idAbs() == abs(outgoingParticles[j])) {
5786  matchOut = true;
5787  outgoingParticles[j] = 99;
5788  }
5789  if (!matchOut) iOutQuarkFlav.push_back(i);
5790 
5791  }
5792 
5793  // Save number of potentially dangerous quarks
5794  int nInQuarkFlav = int(iInQuarkFlav.size());
5795  int nOutQuarkFlav = int(iOutQuarkFlav.size());
5796 
5797  // Easiest problem 0:
5798  // Radiator before splitting exactly matches the partner
5799  // after the splitting
5800  if ( event[partner].isFinal()
5801  && event[partner].id() == 21
5802  && radBeforeFlav == 21
5803  && event[partner].col() == radBeforeCol
5804  && event[partner].acol() == radBeforeAcl)
5805  return false;
5806 
5807  // If there are no ambiguities in qqbar pairs, return
5808  if (nInQuarkFlav + nOutQuarkFlav == 0)
5809  return allowed;
5810 
5811  // Save all quarks and gluons that will not change colour
5812  vector<int> gluon;
5813  vector<int> quark;
5814  vector<int> antiq;
5815  vector<int> partons;
5816  for(int i=0; i < int(event.size()); ++i)
5817  // Check initial and final state partons
5818  if ( i!=emt && i!=rad
5819  && event[i].colType() != 0
5820  && (event[i].isFinal() || event[i].status() == -21) ) {
5821  // Save index
5822  partons.push_back(i);
5823  // Split into components
5824  if (event[i].colType() == 2)
5825  gluon.push_back(i);
5826  else if (event[i].colType() == 1)
5827  quark.push_back(i);
5828  else if (event[i].colType() == -1)
5829  antiq.push_back(i);
5830  }
5831 
5832  // We split up the test of the g->qq splitting into final state
5833  // and initial state problems
5834  bool isFSRg2qq = ( (type == 1) && radBeforeFlav == 21
5835  && (event[rad].id() == -1*event[emt].id()) );
5836  bool isISRg2qq = ( (type ==-1) && radBeforeFlav == 21
5837  && (event[rad].id() == event[emt].id()) );
5838 
5839  // First check general things about colour connections
5840  // Check that clustering does not produce a gluon that is exactly
5841  // matched in the final state, or does not have any colour connections
5842  if ( (isFSRg2qq || isISRg2qq)
5843  && int(quark.size()) + int(antiq.size())
5844  + int(gluon.size()) > nPartonInHard ) {
5845 
5846  vector<int> colours;
5847  vector<int> anticolours;
5848  // Add the colour and anticolour of the gluon before the emission
5849  // to the list, bookkeep initial colour as final anticolour, and
5850  // initial anticolour as final colour
5851  if (type == 1) {
5852  colours.push_back(radBeforeCol);
5853  anticolours.push_back(radBeforeAcl);
5854  } else {
5855  colours.push_back(radBeforeAcl);
5856  anticolours.push_back(radBeforeCol);
5857  }
5858  // Now store gluon colours and anticolours.
5859  for(int i=0; i < int(gluon.size()); ++i)
5860  if (event[gluon[i]].isFinal()) {
5861  colours.push_back(event[gluon[i]].col());
5862  anticolours.push_back(event[gluon[i]].acol());
5863  } else {
5864  colours.push_back(event[gluon[i]].acol());
5865  anticolours.push_back(event[gluon[i]].col());
5866  }
5867 
5868  // Loop through colours and check if any match with
5869  // anticolours. If colour matches, remove from list
5870  for(int i=0; i < int(colours.size()); ++i)
5871  for(int j=0; j < int(anticolours.size()); ++j)
5872  if (colours[i] > 0 && anticolours[j] > 0
5873  && colours[i] == anticolours[j]) {
5874  colours[i] = 0;
5875  anticolours[j] = 0;
5876  }
5877 
5878 
5879  // If all gluon anticolours and all colours matched, disallow
5880  // the clustering
5881  bool allMatched = true;
5882  for(int i=0; i < int(colours.size()); ++i)
5883  if (colours[i] != 0)
5884  allMatched = false;
5885  for(int i=0; i < int(anticolours.size()); ++i)
5886  if (anticolours[i] != 0)
5887  allMatched = false;
5888 
5889  if (allMatched)
5890  return false;
5891 
5892  // Now add the colours of the hard process, and check if all
5893  // colours match.
5894  for(int i=0; i < int(quark.size()); ++i)
5895  if ( event[quark[i]].isFinal()
5896  && mergingHooksPtr->hardProcess->matchesAnyOutgoing(quark[i], event) )
5897  colours.push_back(event[quark[i]].col());
5898 
5899  for(int i=0; i < int(antiq.size()); ++i)
5900  if ( event[antiq[i]].isFinal()
5901  && mergingHooksPtr->hardProcess->matchesAnyOutgoing(antiq[i], event) )
5902  anticolours.push_back(event[antiq[i]].acol());
5903 
5904  // Loop through colours again and check if any match with
5905  // anticolours. If colour matches, remove from list
5906  for(int i=0; i < int(colours.size()); ++i)
5907 
5908  for(int j=0; j < int(anticolours.size()); ++j)
5909  if (colours[i] > 0 && anticolours[j] > 0
5910  && colours[i] == anticolours[j]) {
5911  colours[i] = 0;
5912  anticolours[j] = 0;
5913  }
5914 
5915  // Check if clustering would produce the hard process
5916  int nNotInHard = 0;
5917  for ( int i=0; i < int(quark.size()); ++i )
5918  if ( !mergingHooksPtr->hardProcess->matchesAnyOutgoing( quark[i],
5919  event) )
5920  nNotInHard++;
5921  for ( int i=0; i < int(antiq.size()); ++i )
5922  if ( !mergingHooksPtr->hardProcess->matchesAnyOutgoing( antiq[i],
5923  event) )
5924  nNotInHard++;
5925  for(int i=0; i < int(gluon.size()); ++i)
5926  if ( event[gluon[i]].isFinal() )
5927  nNotInHard++;
5928  if ( type == 1 )
5929  nNotInHard++;
5930 
5931  // If all colours are matched now, and since we have more quarks than
5932  // present in the hard process, disallow the clustering
5933  allMatched = true;
5934  for(int i=0; i < int(colours.size()); ++i)
5935  if (colours[i] != 0)
5936  allMatched = false;
5937  for(int i=0; i < int(anticolours.size()); ++i)
5938  if (anticolours[i] != 0)
5939  allMatched = false;
5940 
5941  if (allMatched && nNotInHard > 0)
5942  return false;
5943 
5944  }
5945 
5946  // FSR PROBLEMS
5947 
5948  if (isFSRg2qq && nInQuarkFlav + nOutQuarkFlav > 0) {
5949 
5950  // Easiest problem 1:
5951  // RECLUSTERED FINAL STATE GLUON MATCHES INITIAL STATE GLUON
5952  for(int i=0; i < int(gluon.size()); ++i) {
5953  if (!event[gluon[i]].isFinal()
5954  && event[gluon[i]].col() == radBeforeCol
5955  && event[gluon[i]].acol() == radBeforeAcl)
5956  return false;
5957  }
5958 
5959  // Easiest problem 2:
5960  // RECLUSTERED FINAL STATE GLUON MATCHES FINAL STATE GLUON
5961  for(int i=0; i < int(gluon.size()); ++i) {
5962  if (event[gluon[i]].isFinal()
5963  && event[gluon[i]].col() == radBeforeAcl
5964  && event[gluon[i]].acol() == radBeforeCol)
5965  return false;
5966  }
5967 
5968  // Easiest problem 3:
5969  // RECLUSTERED FINAL STATE GLUON MATCHES FINAL STATE Q-QBAR PAIR
5970  if ( int(radBeforeColP.size()) == 2
5971  && event[radBeforeColP[0]].isFinal()
5972  && event[radBeforeColP[1]].isFinal()
5973  && event[radBeforeColP[0]].id() == -1*event[radBeforeColP[1]].id() ) {
5974 
5975  // This clustering is allowed if there is no colour in the
5976  // initial state
5977  if (nInitialPartons > 0)
5978  return false;
5979  }
5980 
5981  // Next-to-easiest problem 1:
5982  // RECLUSTERED FINAL STATE GLUON MATCHES ONE FINAL STARE Q_1
5983  // AND ONE INITIAL STATE Q_1
5984  if ( int(radBeforeColP.size()) == 2
5985  && (( event[radBeforeColP[0]].status() == -21
5986  && event[radBeforeColP[1]].isFinal())
5987  ||( event[radBeforeColP[0]].isFinal()
5988  && event[radBeforeColP[1]].status() == -21))
5989  && event[radBeforeColP[0]].id() == event[radBeforeColP[1]].id() ) {
5990 
5991  // In principle, clustering this splitting can disconnect
5992  // the colour lines of a graph. However, the colours can be connected
5993  // again if a final or initial partons of the correct flavour exists.
5994 
5995  // Check which of the partners are final / initial
5996  int incoming = (event[radBeforeColP[0]].isFinal())
5997  ? radBeforeColP[1] : radBeforeColP[0];
5998  int outgoing = (event[radBeforeColP[0]].isFinal())
5999  ? radBeforeColP[0] : radBeforeColP[1];
6000 
6001  // Loop through event to find "recovery partons"
6002  bool clusPossible = false;
6003  for(int i=0; i < int(event.size()); ++i)
6004  if ( i != emt && i != rad
6005  && i != incoming && i != outgoing
6006  && !mergingHooksPtr->hardProcess->matchesAnyOutgoing(i,event) ) {
6007  // Check if an incoming parton matches
6008  if ( event[i].status() == -21
6009  && (event[i].id() == event[outgoing].id()
6010  ||event[i].id() == -1*event[incoming].id()) )
6011  clusPossible = true;
6012  // Check if a final parton matches
6013  if ( event[i].isFinal()
6014  && (event[i].id() == -1*event[outgoing].id()
6015  ||event[i].id() == event[incoming].id()) )
6016  clusPossible = true;
6017  }
6018 
6019  // There can be a further complication: If e.g. in
6020  // t-channel photon exchange topologies, both incoming
6021  // partons are quarks, and form colour singlets with any
6022  // number of final state partons, at least try to
6023  // recluster as much as possible.
6024  // For this, check if the incoming parton
6025  // connected to the radiator is connected to a
6026  // colour and flavour singlet
6027  vector<int> excludeIn1;
6028  for(int i=0; i < 4; ++i)
6029  excludeIn1.push_back(0);
6030  vector<int> colSingletIn1;
6031  int flavIn1Type = (event[incoming].id() > 0) ? 1 : -1;
6032  // Try finding colour singlets
6033  bool isColSingIn1 = getColSinglet(flavIn1Type,incoming,event,
6034  excludeIn1,colSingletIn1);
6035  // Check if colour singlet also is a flavour singlet
6036  bool isFlavSingIn1 = isFlavSinglet(event,colSingletIn1);
6037 
6038  // If the incoming particle is a lepton, just ensure lepton number
6039  // conservation.
6040  bool foundLepton = false;
6041  for(int i=0; i < int(event.size()); ++i)
6042  if ( i != emt && i != rad && i != incoming
6043  && event[i].isLepton() ) foundLepton = true;
6044  if ( abs(radBeforeFlav)%10 == 1 ) foundLepton = true;
6045  if ( foundLepton && event[incoming].isLepton() )
6046  isColSingIn1 = isFlavSingIn1 = true;
6047 
6048  // Check if the incoming parton not
6049  // connected to the radiator is connected to a
6050  // colour and flavour singlet
6051  int incoming2 = (incoming == 3) ? 4 : 3;
6052  vector<int> excludeIn2;
6053  for(int i=0; i < 4; ++i)
6054  excludeIn2.push_back(0);
6055  vector<int> colSingletIn2;
6056  int flavIn2Type = (event[incoming2].id() > 0) ? 1 : -1;
6057  // Try finding colour singlets
6058  bool isColSingIn2 = getColSinglet(flavIn2Type,incoming2,event,
6059  excludeIn2,colSingletIn2);
6060  // Check if colour singlet also is a flavour singlet
6061  bool isFlavSingIn2 = isFlavSinglet(event,colSingletIn2);
6062 
6063  // If the incoming particle is a lepton, just ensure lepton number
6064  // conservation.
6065  foundLepton = false;
6066  for(int i=0; i < int(event.size()); ++i)
6067  if ( i != emt && i != rad && i != incoming2
6068  && event[i].isLepton() ) foundLepton = true;
6069  if ( abs(radBeforeFlav)%10 == 1 ) foundLepton = true;
6070  if ( foundLepton && event[incoming2].isLepton() )
6071  isColSingIn2 = isFlavSingIn2 = true;
6072 
6073  // If no "recovery clustering" is possible, reject clustering
6074  if (!clusPossible
6075  && (!isColSingIn1 || !isFlavSingIn1
6076  || !isColSingIn2 || !isFlavSingIn2))
6077  return false;
6078 
6079  }
6080 
6081  // Next-to-easiest problem 2:
6082  // FINAL STATE Q-QBAR CLUSTERING DISCONNECTS SINGLETT SUBSYSTEM WITH
6083  // FINAL STATE Q-QBAR PAIR FROM GRAPH
6084 
6085  if ( int(radBeforeColP.size()) == 2 ) {
6086 
6087  // Prepare to check for colour singlet combinations of final state quarks
6088  // Start by building a list of partons to exclude when checking for
6089  // colour singlet combinations
6090  int flav = event[emt].id();
6091  vector<int> exclude;
6092  exclude.push_back(emt);
6093  exclude.push_back(rad);
6094  exclude.push_back(radBeforeColP[0]);
6095  exclude.push_back(radBeforeColP[1]);
6096  vector<int> colSinglet;
6097 
6098  // Now find parton from which to start checking colour singlets
6099  int iOther = -1;
6100  // Loop through event to find a parton of correct flavour
6101  for(int i=0; i < int(event.size()); ++i)
6102  // Check final state for parton equalling emitted flavour.
6103  // Exclude the colour system coupled to the clustering
6104  if ( i != emt
6105  && i != rad
6106  && i != radBeforeColP[0]
6107  && i != radBeforeColP[1]
6108  && event[i].isFinal() ) {
6109  // Stop if one parton of the correct flavour is found
6110  if (event[i].id() == flav) {
6111  iOther = i;
6112  break;
6113  }
6114  }
6115  // Save the type of flavour
6116  int flavType = (iOther > 0 && event[iOther].id() > 0) ? 1
6117  : (iOther > 0) ? -1 : 0;
6118  // Try finding colour singlets
6119  bool isColSing = getColSinglet(flavType,iOther,event,exclude,colSinglet);
6120  // Check if colour singlet also is a flavour singlet
6121  bool isFlavSing = isFlavSinglet(event,colSinglet);
6122 
6123  // Check if colour singlet is precisely contained in the hard process.
6124  // If so, then we're safe to recluster.
6125  bool isHardSys = true;
6126  for(int i=0; i < int(colSinglet.size()); ++i)
6127  isHardSys =
6128  mergingHooksPtr->hardProcess->matchesAnyOutgoing(colSinglet[i], event);
6129 
6130  // Nearly there...
6131  // If the decoupled colour singlet system is NOT contained in the hard
6132  // process, we need to check the whole final state.
6133  if (isColSing && isFlavSing && !isHardSys) {
6134 
6135  // In a final check, ensure that the final state does not only
6136  // consist of colour singlets that are also flavour singlets
6137  // of the identical (!) flavours
6138  // Loop through event and save all final state partons
6139  vector<int> allFinal;
6140  for(int i=0; i < int(event.size()); ++i)
6141  if ( event[i].isFinal() )
6142  allFinal.push_back(i);
6143 
6144  // Check if all final partons form a colour singlet
6145  bool isFullColSing = isColSinglet(event,allFinal);
6146  // Check if all final partons form a flavour singlet
6147  bool isFullFlavSing = isFlavSinglet(event,allFinal,flav);
6148 
6149  // If all final quarks are of identical flavour,
6150  // no possible clustering should be discriminated.
6151  // Otherwise, disallow
6152  if (!isFullColSing || !isFullFlavSing)
6153  return false;
6154  }
6155 
6156  }
6157 
6158  }
6159 
6160  // ISR PROBLEMS
6161 
6162  if (isISRg2qq && nInQuarkFlav + nOutQuarkFlav > 0) {
6163 
6164  // Easiest problem 1:
6165  // RECLUSTERED INITIAL STATE GLUON MATCHES FINAL STATE GLUON
6166  for(int i=0; i < int(gluon.size()); ++i) {
6167  if (event[gluon[i]].isFinal()
6168  && event[gluon[i]].col() == radBeforeCol
6169  && event[gluon[i]].acol() == radBeforeAcl)
6170  return false;
6171  }
6172 
6173  // Easiest problem 2:
6174  // RECLUSTERED INITIAL STATE GLUON MATCHES INITIAL STATE GLUON
6175  for(int i=0; i < int(gluon.size()); ++i) {
6176  if (event[gluon[i]].status() == -21
6177  && event[gluon[i]].acol() == radBeforeCol
6178  && event[gluon[i]].col() == radBeforeAcl)
6179  return false;
6180  }
6181 
6182  // Next-to-easiest problem 1:
6183  // RECLUSTERED INITIAL STATE GLUON MATCHES FINAL STATE Q-QBAR PAIR
6184  if ( int(radBeforeColP.size()) == 2
6185  && event[radBeforeColP[0]].isFinal()
6186  && event[radBeforeColP[1]].isFinal()
6187  && event[radBeforeColP[0]].id() == -1*event[radBeforeColP[1]].id() ) {
6188 
6189  // In principle, clustering this splitting can disconnect
6190  // the colour lines of a graph. However, the colours can be connected
6191  // again if final state partons of the correct (anti)flavour, or
6192  // initial state partons of the correct flavour exist
6193  // Loop through event to check
6194  bool clusPossible = false;
6195  for(int i=0; i < int(event.size()); ++i)
6196  if ( i != emt && i != rad
6197  && i != radBeforeColP[0]
6198  && i != radBeforeColP[1]
6199  && !mergingHooksPtr->hardProcess->matchesAnyOutgoing(i,event) ) {
6200  if (event[i].status() == -21
6201  && ( event[radBeforeColP[0]].id() == event[i].id()
6202  || event[radBeforeColP[1]].id() == event[i].id() ))
6203 
6204  clusPossible = true;
6205  if (event[i].isFinal()
6206  && ( event[radBeforeColP[0]].id() == -1*event[i].id()
6207  || event[radBeforeColP[1]].id() == -1*event[i].id() ))
6208  clusPossible = true;
6209  }
6210 
6211  // There can be a further complication: If e.g. in
6212  // t-channel photon exchange topologies, both incoming
6213  // partons are quarks, and form colour singlets with any
6214  // number of final state partons, at least try to
6215  // recluster as much as possible.
6216  // For this, check if the incoming parton
6217  // connected to the radiator is connected to a
6218  // colour and flavour singlet
6219  int incoming1 = 3;
6220  vector<int> excludeIn1;
6221  for(int i=0; i < 4; ++i)
6222  excludeIn1.push_back(0);
6223  vector<int> colSingletIn1;
6224  int flavIn1Type = (event[incoming1].id() > 0) ? 1 : -1;
6225  // Try finding colour singlets
6226  bool isColSingIn1 = getColSinglet(flavIn1Type,incoming1,event,
6227  excludeIn1,colSingletIn1);
6228  // Check if colour singlet also is a flavour singlet
6229  bool isFlavSingIn1 = isFlavSinglet(event,colSingletIn1);
6230 
6231  // If the incoming particle is a lepton, just ensure lepton number
6232  // conservation.
6233  bool foundLepton = false;
6234  for(int i=0; i < int(event.size()); ++i)
6235  if ( i != emt && i != rad && i != incoming1
6236  && event[i].isLepton() ) foundLepton = true;
6237  if ( abs(radBeforeFlav)%10 == 1 ) foundLepton = true;
6238  if ( foundLepton && event[incoming1].isLepton() )
6239  isColSingIn1 = isFlavSingIn1 = true;
6240 
6241  // Check if the incoming parton not
6242  // connected to the radiator is connected to a
6243  // colour and flavour singlet
6244  int incoming2 = 4;
6245  vector<int> excludeIn2;
6246  for(int i=0; i < 4; ++i)
6247  excludeIn2.push_back(0);
6248  vector<int> colSingletIn2;
6249  int flavIn2Type = (event[incoming2].id() > 0) ? 1 : -1;
6250  // Try finding colour singlets
6251  bool isColSingIn2 = getColSinglet(flavIn2Type,incoming2,event,
6252  excludeIn2,colSingletIn2);
6253  // Check if colour singlet also is a flavour singlet
6254  bool isFlavSingIn2 = isFlavSinglet(event,colSingletIn2);
6255 
6256  // If the incoming particle is a lepton, just ensure lepton number
6257  // conservation.
6258  foundLepton = false;
6259  for(int i=0; i < int(event.size()); ++i)
6260  if ( i != emt && i != rad && i != incoming2
6261  && event[i].isLepton() ) foundLepton = true;
6262  if ( abs(radBeforeFlav)%10 == 1 ) foundLepton = true;
6263  if ( foundLepton && event[incoming2].isLepton() )
6264  isColSingIn2 = isFlavSingIn2 = true;
6265 
6266  // If no "recovery clustering" is possible, reject clustering
6267  if (!clusPossible
6268  && (!isColSingIn1 || !isFlavSingIn1
6269  || !isColSingIn2 || !isFlavSingIn2))
6270  return false;
6271 
6272  }
6273 
6274  }
6275 
6276  // Done
6277  return allowed;
6278 }
6279 
6280 //--------------------------------------------------------------------------
6281 
6282 bool DireHistory::hasConnections( int, int nIncIDs[], int nOutIDs[]) {
6283 
6284  bool foundQuarks = false;
6285  for (int i=-6; i < 6; i++)
6286  if (nIncIDs[i] > 0 || nOutIDs[i] > 0) foundQuarks = true;
6287 
6288  if ( nIncIDs[-11] == 1 && nOutIDs[-11] == 1 && !foundQuarks) return false;
6289 
6290  return true;
6291 }
6292 
6293 
6294 bool DireHistory::canConnectFlavs(map<int,int> nIncIDs, map<int,int> nOutIDs) {
6295 
6296  bool foundIncQuarks(false), foundOutQuarks(false);
6297  for (int i=-6; i < 6; i++) {
6298  if (nIncIDs[i] > 0) foundIncQuarks = true;
6299  if (nOutIDs[i] > 0) foundOutQuarks = true;
6300  }
6301 
6302  int nIncEle = (nIncIDs.find(11) != nIncIDs.end()) ? nIncIDs[11] : 0;
6303  int nIncPos = (nIncIDs.find(-11) != nIncIDs.end()) ? nIncIDs[-11] : 0;
6304  int nOutEle = (nOutIDs.find(11) != nOutIDs.end()) ? nOutIDs[11] : 0;
6305  int nOutPos = (nOutIDs.find(-11) != nOutIDs.end()) ? nOutIDs[-11] : 0;
6306 
6307  // Cannot couple positron to other electric charge.
6308  if ( nIncPos == 1 && nOutPos == 1 && !foundOutQuarks && !foundIncQuarks)
6309  return false;
6310 
6311  // Cannot couple electron to other electric charge.
6312  if ( nIncEle == 1 && nOutEle == 1 && !foundOutQuarks && !foundIncQuarks)
6313  return false;
6314 
6315  return true;
6316 }
6317 
6318 //--------------------------------------------------------------------------
6319 
6320 // Function to check if rad,emt,rec triple is results in
6321 // colour singlet radBefore+recBefore
6322 // IN int rad,emt,rec : Positions (in event record) of the three
6323 // particles considered for clustering
6324 // Event event : Reference event
6325 
6326 bool DireHistory::isSinglett( int rad, int emt, int rec, const Event& event ) {
6327 
6328  int radCol = event[rad].col();
6329  int emtCol = event[emt].col();
6330  int recCol = event[rec].col();
6331  int radAcl = event[rad].acol();
6332  int emtAcl = event[emt].acol();
6333  int recAcl = event[rec].acol();
6334  int recType = event[rec].isFinal() ? 1 : -1;
6335 
6336  bool isSing = false;
6337 
6338  if ( ( recType == -1
6339  && radCol + emtCol == recCol && radAcl + emtAcl == recAcl)
6340  ||( recType == 1
6341  && radCol + emtCol == recAcl && radAcl + emtAcl == recCol) )
6342  isSing = true;
6343 
6344  return isSing;
6345 
6346 }
6347 
6348 //--------------------------------------------------------------------------
6349 
6350 // Function to check if event is sensibly constructed: Meaning
6351 // that all colour indices are contracted and that the charge in
6352 // initial and final states matches
6353 // IN event : event to be checked
6354 // OUT TRUE : event is properly construced
6355 // FALSE : event not valid
6356 
6357 bool DireHistory::validEvent( const Event& event ) {
6358 
6359  // Check if event is coloured
6360  bool validColour = true;
6361  for ( int i = 0; i < event.size(); ++i)
6362  // Check colour of quarks
6363  if ( event[i].isFinal() && event[i].colType() == 1
6364  // No corresponding anticolour in final state
6365  && ( FindCol(event[i].col(),i,0,event,1,true) == 0
6366  // No corresponding colour in initial state
6367  && FindCol(event[i].col(),i,0,event,2,true) == 0 )) {
6368  validColour = false;
6369  break;
6370  // Check anticolour of antiquarks
6371  } else if ( event[i].isFinal() && event[i].colType() == -1
6372  // No corresponding colour in final state
6373  && ( FindCol(event[i].acol(),i,0,event,2,true) == 0
6374  // No corresponding anticolour in initial state
6375  && FindCol(event[i].acol(),i,0,event,1,true) == 0 )) {
6376  validColour = false;
6377  break;
6378  // No uncontracted colour (anticolour) charge of gluons
6379  } else if ( event[i].isFinal() && event[i].colType() == 2
6380  // No corresponding anticolour in final state
6381  && ( FindCol(event[i].col(),i,0,event,1,true) == 0
6382  // No corresponding colour in initial state
6383  && FindCol(event[i].col(),i,0,event,2,true) == 0 )
6384  // No corresponding colour in final state
6385  && ( FindCol(event[i].acol(),i,0,event,2,true) == 0
6386  // No corresponding anticolour in initial state
6387  && FindCol(event[i].acol(),i,0,event,1,true) == 0 )) {
6388  validColour = false;
6389  break;
6390  }
6391 
6392  // Check charge sum in initial and final state
6393  bool validCharge = true;
6394  double initCharge = event[3].charge() + event[4].charge();
6395  double finalCharge = 0.0;
6396  for(int i = 0; i < event.size(); ++i)
6397  if (event[i].isFinal()) finalCharge += event[i].charge();
6398  if (abs(initCharge-finalCharge) > 1e-12) validCharge = false;
6399 
6400  return (validColour && validCharge);
6401 
6402 }
6403 
6404 //--------------------------------------------------------------------------
6405 
6406 // Function to check whether two clusterings are identical, used
6407 // for finding the history path in the mother -> children direction
6408 
6409 bool DireHistory::equalClustering( DireClustering c1 , DireClustering c2 ) {
6410 
6411  // Check if clustering members are equal.
6412  bool isIdenticalClustering
6413  = (c1.emittor == c2.emittor)
6414  && (c1.emitted == c2.emitted)
6415  && (c1.recoiler == c2.recoiler)
6416  && (c1.partner == c2.partner)
6417  && (c1.pT() == c2.pT())
6418  && (c1.spinRadBef == c2.spinRadBef)
6419  && (c1.flavRadBef == c2.flavRadBef)
6420  && (c1.splitName == c2.splitName);
6421  if (isIdenticalClustering) return true;
6422 
6423  // Require identical recoiler.
6424  if (c1.recoiler != c2.recoiler) return false;
6425  // Require same names.
6426  if (c1.name() != c2.name()) return false;
6427 
6428  // For unequal clusterings, splitting can still be identical, if symmetric
6429  // in radiator and emission.
6430  if (c1.emittor != c2.emitted || c1.emitted != c2.emittor) return false;
6431 
6432  bool isIdenticalSplitting = false;
6433  if (fsr && c1.rad()->isFinal() && c2.rad()->isFinal())
6434  isIdenticalSplitting = fsr->isSymmetric(c1.name(),c1.rad(),c1.emt());
6435  else if (isr && !c1.rad()->isFinal() && !c2.rad()->isFinal())
6436  isIdenticalSplitting = isr->isSymmetric(c1.name(),c1.rad(),c1.emt());
6437 
6438  return isIdenticalSplitting;
6439 
6440 }
6441 
6442 //--------------------------------------------------------------------------
6443 
6444 // Chose dummy scale for event construction. By default, choose
6445 // sHat for 2->Boson(->2)+ n partons processes and
6446 // M_Boson for 2->Boson(->) processes
6447 
6448 double DireHistory::choseHardScale( const Event& event ) const {
6449 
6450  // Get sHat
6451  double mHat = (event[3].p() + event[4].p()).mCalc();
6452 
6453  // Find number of final state particles and bosons
6454  int nFinal = 0;
6455  int nFinBos= 0;
6456  int nBosons= 0;
6457  double mBos = 0.0;
6458  for(int i = 0; i < event.size(); ++i)
6459  if ( event[i].isFinal() ) {
6460  nFinal++;
6461  // Remember final state unstable bosons
6462  if ( event[i].idAbs() == 23
6463  || event[i].idAbs() == 24 ) {
6464  nFinBos++;
6465  nBosons++;
6466  mBos += event[i].m();
6467  }
6468  } else if ( abs(event[i].status()) == 22
6469  && ( event[i].idAbs() == 23
6470  || event[i].idAbs() == 24 )) {
6471  nBosons++;
6472  mBos += event[i].m(); // Real mass
6473  }
6474 
6475  // Return averaged boson masses
6476  if ( nBosons > 0 && (nFinal + nFinBos*2) <= 3)
6477  return (mBos / double(nBosons));
6478  else return
6479  mHat;
6480 }
6481 
6482 
6483 //--------------------------------------------------------------------------
6484 
6485 // If the state has an incoming hadron return the flavour of the
6486 // parton entering the hard interaction. Otherwise return 0
6487 
6488 int DireHistory::getCurrentFlav(const int side) const {
6489  int in = (side == 1) ? 3 : 4;
6490  return state[in].id();
6491 }
6492 
6493 //--------------------------------------------------------------------------
6494 
6495 double DireHistory::getCurrentX(const int side) const {
6496  int in = (side == 1) ? 3 : 4;
6497  return ( 2.*state[in].e()/state[0].e() );
6498 }
6499 
6500 //--------------------------------------------------------------------------
6501 
6502 double DireHistory::getCurrentZ(const int rad,
6503  const int rec, const int emt, int idRadBef) const {
6504 
6505  int type = state[rad].isFinal() ? 1 : -1;
6506  double z = 0.;
6507 
6508  if (type == 1) {
6509 
6510  Vec4 radAfterBranch(state[rad].p());
6511  Vec4 recAfterBranch(state[rec].p());
6512  Vec4 emtAfterBranch(state[emt].p());
6513 
6514  // Store masses both after and prior to emission.
6515  double m2RadAft = radAfterBranch.m2Calc();
6516  double m2EmtAft = emtAfterBranch.m2Calc();
6517  double m2RadBef = 0.;
6518  if ( state[rad].idAbs() != 21 && state[rad].idAbs() != 22
6519  && state[emt].idAbs() != 24 && state[rad].idAbs() != state[emt].idAbs())
6520  m2RadBef = m2RadAft;
6521  else if ( state[emt].idAbs() == 24) {
6522  if (idRadBef != 0)
6523  m2RadBef = pow2(particleDataPtr->m0(abs(idRadBef)));
6524  }
6525 
6526  double Qsq = (radAfterBranch + emtAfterBranch).m2Calc();
6527 
6528  // Calculate dipole invariant mass.
6529  double m2final
6530  = (radAfterBranch + recAfterBranch + emtAfterBranch).m2Calc();
6531  // More complicated for initial state recoiler.
6532  if ( !state[rec].isFinal() ){
6533  double mar2 = m2final - 2. * Qsq + 2. * m2RadBef;
6534  recAfterBranch *= (1. - (Qsq - m2RadBef)/(mar2 - m2RadBef))
6535  /(1. + (Qsq - m2RadBef)/(mar2 - m2RadBef));
6536  // If Qsq is larger than mar2 the event is not kinematically possible.
6537  // Just return random z, since clustering will be discarded.
6538  if (Qsq > mar2) return 0.5;
6539  }
6540 
6541  Vec4 sum = radAfterBranch + recAfterBranch + emtAfterBranch;
6542  double m2Dip = sum.m2Calc();
6543  // Construct 2->3 variables for FSR
6544  double x1 = 2. * (sum * radAfterBranch) / m2Dip;
6545  double x2 = 2. * (sum * recAfterBranch) / m2Dip;
6546 
6547  // Prepare for more complicated z definition for massive splittings.
6548  double lambda13 = sqrt( pow2(Qsq - m2RadAft - m2EmtAft )
6549  - 4.*m2RadAft*m2EmtAft);
6550  double k1 = ( Qsq - lambda13 + (m2EmtAft - m2RadAft ) ) / ( 2. * Qsq );
6551  double k3 = ( Qsq - lambda13 - (m2EmtAft - m2RadAft ) ) / ( 2. * Qsq );
6552  // Calculate z of splitting, different for FSR
6553  z = 1./ ( 1- k1 -k3) * ( x1 / (2.-x2) - k3);
6554 
6555  } else {
6556  // Construct momenta of dipole before/after splitting for ISR
6557  Vec4 qBR(state[rad].p() - state[emt].p() + state[rec].p());
6558  Vec4 qAR(state[rad].p() + state[rec].p());
6559  // Calculate z of splitting, different for ISR
6560  z = (qBR.m2Calc())/( qAR.m2Calc());
6561  }
6562 
6563  return z;
6564 
6565 }
6566 
6567 //--------------------------------------------------------------------------
6568 
6569 // Function to compute "pythia pT separation" from Particle input
6570 
6571 double DireHistory::pTLund(const Event& event, int rad, int emt, int rec,
6572  string name) {
6573 
6574  // Use external shower for merging.
6575  map<string,double> stateVars;
6576 
6577  bool hasPartonLevel(showers && showers->timesPtr && showers->spacePtr),
6578  hasShowers(fsr && isr);
6579  if (hasPartonLevel) {
6580  bool isFSR = showers->timesPtr->isTimelike(event, rad, emt, rec, "");
6581  if (isFSR) stateVars = showers->timesPtr->getStateVariables
6582  (event, rad,emt,rec, name);
6583  else stateVars = showers->spacePtr->getStateVariables
6584  (event, rad,emt,rec, name);
6585  } else if (hasShowers) {
6586  bool isFSR = fsr->isTimelike(event, rad, emt, rec, "");
6587  if (isFSR) stateVars = fsr->getStateVariables(event, rad,emt,rec, name);
6588  else stateVars = isr->getStateVariables(event, rad,emt,rec, name);
6589  }
6590 
6591  return ( (stateVars.size() > 0 && stateVars.find("t") != stateVars.end())
6592  ? sqrt(stateVars["t"]) : -1.0 );
6593 }
6594 
6595 //--------------------------------------------------------------------------
6596 
6597 // Function to return the position of the initial line before (or after)
6598 // a single (!) splitting.
6599 
6600 int DireHistory::posChangedIncoming(const Event& event, bool before) {
6601 
6602  // Check for initial state splittings.
6603  // Consider a splitting to exist if both mother and sister were found.
6604  // Find sister
6605  int iSister = 0;
6606  for (int i =0; i < event.size(); ++i)
6607  if (event[i].status() == 43) {
6608  iSister = i;
6609  break;
6610  }
6611  // Find mother
6612  int iMother = 0;
6613  if (iSister > 0) iMother = event[iSister].mother1();
6614 
6615  // Initial state splitting has been found.
6616  if (iSister > 0 && iMother > 0) {
6617 
6618  // Find flavour, mother flavour
6619  int flavSister = event[iSister].id();
6620  int flavMother = event[iMother].id();
6621 
6622  // Find splitting flavour
6623  int flavDaughter = 0;
6624  if ( abs(flavMother) < 21 && flavSister == 21)
6625  flavDaughter = flavMother;
6626  else if ( flavMother == 21 && flavSister == 21)
6627  flavDaughter = flavMother;
6628  else if ( flavMother == 21 && abs(flavSister) < 21)
6629  flavDaughter = -1*flavSister;
6630  else if ( abs(flavMother) < 21 && abs(flavSister) < 21)
6631  flavDaughter = 21;
6632 
6633  // Find initial state (!) daughter
6634  int iDaughter = 0;
6635  for (int i =0; i < event.size(); ++i)
6636  if ( !event[i].isFinal()
6637  && event[i].mother1() == iMother
6638  && event[i].id() == flavDaughter )
6639  iDaughter = i;
6640 
6641  // Done for initial state splitting.
6642  if ( !before ) return iMother;
6643  else return iDaughter;
6644 
6645  }
6646 
6647  // Check for final state splittings with initial state recoiler.
6648  // Consider a splitting to exist if both mother and daughter were found.
6649  // Find new mother
6650  iMother = 0;
6651  for (int i =0; i < event.size(); ++i)
6652  if ( abs(event[i].status()) == 53 || abs(event[i].status()) == 54) {
6653  iMother = i;
6654  break;
6655  }
6656  // Find daughter
6657  int iDaughter = 0;
6658  if (iMother > 0) iDaughter = event[iMother].daughter1();
6659 
6660  // Done if final state splitting has been found.
6661  if (iDaughter > 0 && iMother > 0) {
6662 
6663  // Done for final state splitting.
6664  if ( !before ) return iMother;
6665  else return iDaughter;
6666 
6667  }
6668 
6669  // If no splitting has been found, return zero.
6670  return 0;
6671 
6672 }
6673 
6674 //--------------------------------------------------------------------------
6675 
6676 vector<int> DireHistory::getSplittingPos(const Event& e, int type) {
6677 
6678  // Get radiators and recoilers before and after splitting.
6679  int iRadBef(-1), iRecBef(-1), iRadAft(-1), iEmt(-1), iRecAft(-1);
6680  // ISR
6681  if (type == 2) {
6682  // Loop through event to find new particles.
6683  for (int i = e.size() - 1; i > 0; i--) {
6684  if ( iRadAft == -1 && e[i].status() == -41) iRadAft = i;
6685  else if ( iEmt == -1 && e[i].status() == 43) iEmt = i;
6686  else if ( iRecAft == -1
6687  && (e[i].status() == -42 || e[i].status() == 48) ) iRecAft = i;
6688  if (iRadAft != -1 && iEmt != -1 && iRecAft != -1) break;
6689  }
6690  // Radiator before emission.
6691  iRadBef = (iRadAft > 0) ? e[iRadAft].daughter2() : -1;
6692  // Recoiler before emission.
6693  iRecBef = (iRecAft > 0) ? (e[iRecAft].isFinal()
6694  ? e[iRecAft].mother1() : e[iRecAft].daughter1()) : -1;
6695 
6696  // FSR
6697  } else if (type >= 3) {
6698 
6699  // Recoiler after branching.
6700  if ( e[e.size() - 1].status() == 52
6701  || e[e.size() - 1].status() == -53
6702  || e[e.size() - 1].status() == -54) iRecAft = (e.size() - 1);
6703  // Emission after branching.
6704  if ( e[e.size() - 2].status() == 51) iEmt = (e.size() - 2);
6705  // Radiator after branching.
6706  if ( e[e.size() - 3].status() == 51) iRadAft = (e.size() - 3);
6707  // Radiator before emission.
6708  iRadBef = (iRadAft > 0) ? e[iRadAft].mother1() : -1;
6709  // Recoiler before emission.
6710  iRecBef = (iRecAft > 0) ? (e[iRecAft].isFinal()
6711  ? e[iRecAft].mother1() : e[iRecAft].daughter1()) : -1;
6712  }
6713 
6714  vector<int> ret;
6715  if ( iRadBef != -1
6716  && iRecBef != -1
6717  && iRadAft != -1
6718  && iEmt != -1
6719  && iRecAft != -1)
6720  ret = createvector<int>(iRadBef)(iRecBef)(iRadAft)(iRecAft)(iEmt);
6721 
6722  return ret;
6723 
6724 }
6725 
6726 double DireHistory::pdfFactor( const Event&, const Event& e, const int type,
6727  double pdfScale, double mu ) {
6728 
6729  double wt = 1.;
6730 
6731  // Do nothing for MPI
6732  if (type < 2) return 1.0;
6733 
6734  // Get radiators and recoilers before and after splitting.
6735  vector<int> splitPos = getSplittingPos(e, type);
6736  if (splitPos.size() < 5) return 1.0;
6737  int iRadBef = splitPos[0];
6738  int iRecBef = splitPos[1];
6739  int iRadAft = splitPos[2];
6740  int iRecAft = splitPos[3];
6741 
6742  bool useSummedPDF
6743  = infoPtr->settingsPtr->flag("ShowerPDF:useSummedPDF");
6744 
6745  // Final-final splittings
6746  if ( e[iRadAft].isFinal() && e[iRecAft].isFinal() ) {
6747  return 1.0;
6748 
6749  // Final-initial splittings
6750  } else if ( e[iRadAft].isFinal() && !e[iRecAft].isFinal() ) {
6751 
6752  // Find flavour and x values.
6753  int flavAft = e[iRecAft].id();
6754  int flavBef = e[iRecBef].id();
6755  double xAft = 2.*e[iRecAft].e() / e[0].e();
6756  double xBef = 2.*e[iRecBef].e() / e[0].e();
6757  bool hasPDFAft = (particleDataPtr->colType(flavAft) != 0);
6758  bool hasPDFBef = (particleDataPtr->colType(flavBef) != 0);
6759 
6760  // Calculate PDF weight to reweight emission to emission evaluated at
6761  // constant factorisation scale. No need to include the splitting kernel in
6762  // the weight, since it will drop out anyway.
6763  int sideSplit = ( e[iRecAft].pz() > 0.) ? 1 : -1;
6764  double pdfDen1, pdfDen2, pdfNum1, pdfNum2;
6765  pdfDen1 = pdfDen2 = pdfNum1 = pdfNum2 = 1.;
6766  if ( sideSplit == 1 ) {
6767  pdfDen1 = (!hasPDFBef) ? 1.0 : (useSummedPDF)
6768  ? beamA.xf(flavBef, xBef, pow2(mu))
6769  : beamA.xfISR(0, flavBef, xBef, pow2(mu));
6770  pdfNum1 = (!hasPDFBef) ? 1.0 : (useSummedPDF)
6771  ? beamA.xf(flavBef, xBef, pow2(pdfScale))
6772  : beamA.xfISR(0, flavBef, xBef, pow2(pdfScale));
6773  pdfNum2 = (!hasPDFAft) ? 1.0 : (useSummedPDF)
6774  ? beamA.xf(flavAft, xAft, pow2(mu))
6775  : beamA.xfISR(0, flavAft, xAft, pow2(mu));
6776  pdfDen2 = (!hasPDFAft) ? 1.0 : (useSummedPDF)
6777  ? beamA.xf(flavAft, xAft, pow2(pdfScale))
6778  : beamA.xfISR(0, flavAft, xAft, pow2(pdfScale));
6779  } else {
6780  pdfDen1 = (!hasPDFBef) ? 1.0 : (useSummedPDF)
6781  ? beamB.xf(flavBef, xBef, pow2(mu))
6782  : beamB.xfISR(0, flavBef, xBef, pow2(mu));
6783  pdfNum1 = (!hasPDFBef) ? 1.0 : (useSummedPDF)
6784  ? beamB.xf(flavBef, xBef, pow2(pdfScale))
6785  : beamB.xfISR(0, flavBef, xBef, pow2(pdfScale));
6786  pdfNum2 = (!hasPDFAft) ? 1.0 : (useSummedPDF)
6787  ? beamB.xf(flavAft, xAft, pow2(mu))
6788  : beamB.xfISR(0, flavAft, xAft, pow2(mu));
6789  pdfDen2 = (!hasPDFAft) ? 1.0 : (useSummedPDF)
6790  ? beamB.xf(flavAft, xAft, pow2(pdfScale))
6791  : beamB.xfISR(0, flavAft, xAft, pow2(pdfScale));
6792  }
6793  wt = (pdfNum1/pdfDen1) * (pdfNum2)/(pdfDen2);
6794 
6795  // Initial-final splittings
6796  } else if ( !e[iRadAft].isFinal() && e[iRecAft].isFinal() ) {
6797 
6798  // Find flavour and x values.
6799  int flavAft = e[iRadAft].id();
6800  int flavBef = e[iRadBef].id();
6801  double xAft = 2.*e[iRadAft].e() / e[0].e();
6802  double xBef = 2.*e[iRadBef].e() / e[0].e();
6803  bool hasPDFAft = (particleDataPtr->colType(flavAft) != 0);
6804  bool hasPDFBef = (particleDataPtr->colType(flavBef) != 0);
6805 
6806  // Calculate PDF weight to reweight emission to emission evaluated at
6807  // constant factorisation scale. No need to include the splitting kernel in
6808  // the weight, since it will drop out anyway.
6809  int sideSplit = ( e[iRadAft].pz() > 0.) ? 1 : -1;
6810  double pdfDen1, pdfDen2, pdfNum1, pdfNum2;
6811  pdfDen1 = pdfDen2 = pdfNum1 = pdfNum2 = 1.;
6812  if ( sideSplit == 1 ) {
6813  pdfDen1 = (!hasPDFBef) ? 1.0 : (useSummedPDF)
6814  ? beamA.xf(flavBef, xBef, pow2(mu))
6815  : beamA.xfISR(0, flavBef, xBef, pow2(mu));
6816  pdfNum1 = (!hasPDFBef) ? 1.0 : (useSummedPDF)
6817  ? beamA.xf(flavBef, xBef, pow2(pdfScale))
6818  : beamA.xfISR(0, flavBef, xBef, pow2(pdfScale));
6819  pdfNum2 = (!hasPDFAft) ? 1.0 : (useSummedPDF)
6820  ? beamA.xf(flavAft, xAft, pow2(mu))
6821  : beamA.xfISR(0, flavAft, xAft, pow2(mu));
6822  pdfDen2 = (!hasPDFAft) ? 1.0 : (useSummedPDF)
6823  ? beamA.xf(flavAft, xAft, pow2(pdfScale))
6824  : beamA.xfISR(0, flavAft, xAft, pow2(pdfScale));
6825  } else {
6826  pdfDen1 = (!hasPDFBef) ? 1.0 : (useSummedPDF)
6827  ? beamB.xf(flavBef, xBef, pow2(mu))
6828  : beamB.xfISR(0, flavBef, xBef, pow2(mu));
6829  pdfNum1 = (!hasPDFBef) ? 1.0 : (useSummedPDF)
6830  ? beamB.xf(flavBef, xBef, pow2(pdfScale))
6831  : beamB.xfISR(0, flavBef, xBef, pow2(pdfScale));
6832  pdfNum2 = (!hasPDFAft) ? 1.0 : (useSummedPDF)
6833  ? beamB.xf(flavAft, xAft, pow2(mu))
6834  : beamB.xfISR(0, flavAft, xAft, pow2(mu));
6835  pdfDen2 = (!hasPDFAft) ? 1.0 : (useSummedPDF)
6836  ? beamB.xf(flavAft, xAft, pow2(pdfScale))
6837  : beamB.xfISR(0, flavAft, xAft, pow2(pdfScale));
6838  }
6839  wt = (pdfNum1/pdfDen1) * (pdfNum2)/(pdfDen2);
6840 
6841 
6842  // Initial-initial splittings
6843  } else if ( !e[iRadAft].isFinal() && !e[iRecAft].isFinal() ) {
6844 
6845  // Find flavour and x values.
6846  int flavAft = e[iRadAft].id();
6847  int flavBef = e[iRadBef].id();
6848  double xAft = 2.*e[iRadAft].e() / e[0].e();
6849  double xBef = 2.*e[iRadBef].e() / e[0].e();
6850 
6851  // Calculate PDF weight to reweight emission to emission evaluated at
6852  // constant factorisation scale. No need to include the splitting kernel
6853  // in the weight, since it will drop out anyway.
6854  int sideSplit = ( e[iRadAft].pz() > 0.) ? 1 : -1;
6855  double ratio1 = getPDFratio( sideSplit, false, false, flavBef,
6856  xBef, pdfScale, flavBef, xBef, mu );
6857  double ratio2 = getPDFratio( sideSplit, false, false, flavAft,
6858  xAft, mu, flavAft, xAft, pdfScale );
6859 
6860  wt = ratio1*ratio2;
6861 
6862  }
6863 
6864  // Done
6865  return wt;
6866 }
6867 
6868 //--------------------------------------------------------------------------
6869 
6870 // Function giving the product of splitting kernels and PDFs so that the
6871 // resulting flavour is given by flav. This is used as a helper routine
6872 // to dgauss
6873 
6874 double DireHistory::integrand(int flav, double x, double scaleInt, double z) {
6875 
6876  // Colour factors.
6877  double CA = infoPtr->settingsPtr->parm("DireColorQCD:CA") > 0.0
6878  ? infoPtr->settingsPtr->parm("DireColorQCD:CA") : 3.0;
6879  double CF = infoPtr->settingsPtr->parm("DireColorQCD:CF") > 0.0
6880  ? infoPtr->settingsPtr->parm("DireColorQCD:CF") : 4./3.;
6881  double TR = infoPtr->settingsPtr->parm("DireColorQCD:TR") > 0.
6882  ? infoPtr->settingsPtr->parm("DireColorQCD:TR") : 0.5;
6883 
6884  double result = 0.;
6885 
6886  // Integrate NLL sudakov remainder
6887  if (flav==0) {
6888 
6889  AlphaStrong* as = mergingHooksPtr->AlphaS_ISR();
6890  double asNow = (*as).alphaS(z);
6891  result = 1./z *asNow*asNow* ( log(scaleInt/z) -3./2. );
6892 
6893  // Integrand for PDF ratios. Careful about factors if 1/z, since formulae
6894  // are expressed in terms if f(x,mu), while Pythia uses x*f(x,mu)!
6895  } else if (flav==21) {
6896 
6897  double measure1 = 1./(1. - z);
6898  double measure2 = 1.;
6899 
6900  double integrand1 =
6901  2.*CA
6902  * z * beamB.xf( 21,x/z,pow(scaleInt,2))
6903  / beamB.xf( 21,x, pow(scaleInt,2))
6904  - 2.*CA;
6905 
6906  double integrand2 =
6907  // G -> G terms
6908  2.*CA *((1. -z)/z + z*(1.-z))
6909  * beamB.xf( 21,x/z,pow(scaleInt,2))
6910  / beamB.xf( 21,x, pow(scaleInt,2))
6911  // G -> Q terms
6912  + CF * ((1+pow(1-z,2))/z)
6913  *( beamB.xf( 1, x/z,pow(scaleInt,2))
6914  / beamB.xf( 21, x, pow(scaleInt,2))
6915  + beamB.xf( -1, x/z,pow(scaleInt,2))
6916  / beamB.xf( 21, x, pow(scaleInt,2))
6917  + beamB.xf( 2, x/z,pow(scaleInt,2))
6918  / beamB.xf( 21, x, pow(scaleInt,2))
6919  + beamB.xf( -2, x/z,pow(scaleInt,2))
6920  / beamB.xf( 21, x, pow(scaleInt,2))
6921  + beamB.xf( 3, x/z,pow(scaleInt,2))
6922  / beamB.xf( 21, x, pow(scaleInt,2))
6923  + beamB.xf( -3, x/z,pow(scaleInt,2))
6924  / beamB.xf( 21, x, pow(scaleInt,2))
6925  + beamB.xf( 4, x/z,pow(scaleInt,2))
6926  / beamB.xf( 21, x, pow(scaleInt,2))
6927  + beamB.xf( -4, x/z,pow(scaleInt,2))
6928  / beamB.xf( 21, x, pow(scaleInt,2)) );
6929 
6930  // Done
6931  result = integrand1*measure1 + integrand2*measure2;
6932 
6933  } else {
6934 
6935  double measure1 = 1./(1. -z);
6936  double measure2 = 1.;
6937 
6938  // Q -> Q terms
6939  double integrand1 =
6940  CF * (1+pow(z,2))
6941  * beamB.xf( flav, x/z, pow(scaleInt,2))
6942  / beamB.xf( flav, x, pow(scaleInt,2))
6943  - 2.*CF;
6944 
6945  // Q -> G terms
6946  double integrand2 =
6947  + TR * (pow(z,2) + pow(1-z,2))
6948  * beamB.xf( 21, x/z, pow(scaleInt,2))
6949  / beamB.xf( flav, x, pow(scaleInt,2));
6950 
6951  // Done
6952  result = measure1*integrand1 + measure2*integrand2;
6953  }
6954 
6955  return result;
6956 
6957 }
6958 
6959 //--------------------------------------------------------------------------
6960 
6961 // Function providing a list of possible new flavours after a w emssion
6962 // from the input flavour.
6963 
6964 vector<int> DireHistory::posFlavCKM(int flav) {
6965 
6966  // absolute values!
6967  int flavAbs = abs(flav);
6968 
6969  vector<int> flavRadBefs;
6970  // (e,mu,tau)
6971  if (flavAbs > 10 && flavAbs % 2 == 1)
6972  flavRadBefs.push_back(flavAbs + 1);
6973  // (neutrinoes)
6974  else if (flavAbs > 10 && flavAbs % 2 == 0)
6975  flavRadBefs.push_back(flavAbs - 1);
6976  // Full CKM for quarks.
6977  else if (flavAbs < 10 && flavAbs % 2 == 1) {
6978  flavRadBefs.push_back(2);
6979  flavRadBefs.push_back(4);
6980  flavRadBefs.push_back(6);
6981  }
6982  else if (flavAbs < 10 && flavAbs % 2 == 0) {
6983  flavRadBefs.push_back(1);
6984  flavRadBefs.push_back(3);
6985  flavRadBefs.push_back(5);
6986  }
6987 
6988  // Return the possible flavours.
6989  return flavRadBefs;
6990 }
6991 
6992 //--------------------------------------------------------------------------
6993 
6994 // Check if the new flavour structure is possible.
6995 // If clusType is 1 final clustering is assumed, otherwise initial clustering
6996 // is assumed.
6997 
6998 bool DireHistory::checkFlavour(vector<int>& flavCounts, int flavRad,
6999  int flavRadBef, int clusType) {
7000 
7001  // Loop over event.
7002  for(int k = 0; k < 20; ++k) {
7003  // Find changes from this W emission.
7004  int cor = 0;
7005  if (abs(flavRad) == k) {
7006  cor = -1;
7007  if (flavRad < 0) cor = 1;
7008  }
7009 
7010  if (abs(flavRadBef) == k) {
7011  cor = 1;
7012  if (flavRadBef < 0) cor = -1;
7013  }
7014 
7015  // if flavour and flavRadBef is the same, no correction.
7016  if (flavRadBef == flavRad) cor = 0;
7017 
7018  // Check if flavour is consistent.
7019  if (clusType == 1) {
7020  if (flavCounts[k] + cor != 0) return false;
7021  }
7022  else
7023  if (flavCounts[k] - cor != 0) return false;
7024  }
7025 
7026  // No more checks.
7027  return true;
7028 
7029 }
7030 
7031 //--------------------------------------------------------------------------
7032 
7033 // Check if an event reclustered into a 2 -> 2 dijet.
7034 // (Only enabled if W reclustering is used).
7035 bool DireHistory::isQCD2to2(const Event& event) {
7036 
7037  if (!mergingHooksPtr->doWeakClustering()) return false;
7038  int nFinalPartons = 0, nFinal = 0;
7039  for (int i = 0;i < event.size();++i)
7040  if (event[i].isFinal()) {
7041  nFinal++;
7042  if ( event[i].idAbs() < 10 || event[i].idAbs() == 21)
7043  nFinalPartons++;
7044  }
7045  if (nFinalPartons == 2 && nFinal == 2) return true;
7046  else return false;
7047 
7048 }
7049 
7050 //--------------------------------------------------------------------------
7051 
7052 // Check if an event reclustered into a 2 -> 1 Drell-Yan.
7053 // (Only enabled if W reclustering is used).
7054 bool DireHistory::isEW2to1(const Event& event) {
7055 
7056  if (!mergingHooksPtr->doWeakClustering()) return false;
7057  int nVector = 0;
7058  for (int i = 0;i < event.size();++i) {
7059  if (event[i].isFinal()) {
7060  if (event[i].idAbs() == 23 ||
7061  event[i].idAbs() == 24 ||
7062  event[i].idAbs() == 22) nVector++;
7063  else return false;
7064  }
7065  }
7066 
7067  // Only true if a single vector boson as outgoing process.
7068  if (nVector == 1) return true;
7069 
7070  // Done
7071  return false;
7072 
7073 }
7074 
7075 //--------------------------------------------------------------------------
7076 
7077 // Check if an event reclustered into massless 2 -> 2.
7078 
7079 bool DireHistory::isMassless2to2(const Event& event) {
7080 
7081  int nFmassless(0), nFinal(0), nImassless(0);
7082  for (int i = 0;i < event.size();++i)
7083  if (event[i].isFinal()) {
7084  nFinal++;
7085  if ( event[i].idAbs() < 10
7086  || event[i].idAbs() == 21
7087  || event[i].idAbs() == 22) nFmassless++;
7088  } else if ( event[i].status() == -21 ) {
7089  if ( event[i].idAbs() < 10
7090  || event[i].idAbs() == 21
7091  || event[i].idAbs() == 22) nImassless++;
7092  }
7093  if (nFmassless == 2 && nFinal == 2 && nImassless == 2) return true;
7094 
7095  // Done
7096  return false;
7097 
7098 }
7099 
7100 //--------------------------------------------------------------------------
7101 
7102 // Check if an event reclustered into DIS 2 -> 2.
7103 bool DireHistory::isDIS2to2(const Event& event) {
7104 
7105  int nFpartons(0), nFleptons(0), nIpartons(0), nIleptons(0), nFinal(0);
7106  for (int i = 0;i < event.size();++i)
7107  if (event[i].isFinal()) {
7108  if ( event[i].isLepton() ) nFleptons++;
7109  if ( event[i].colType() != 0 ) nFpartons++;
7110  nFinal++;
7111  } else if ( event[i].status() == -21 ) {
7112  if ( event[i].isLepton() ) nIleptons++;
7113  if ( event[i].colType() != 0 ) nIpartons++;
7114  }
7115  bool isDIS = nFinal == 2 && nFpartons == 1 && nFleptons == 1
7116  && nIpartons == 1 && nIleptons == 1;
7117  if (isDIS) return true;
7118 
7119  // Done.
7120  return false;
7121 }
7122 
7123 // Function to allow effective gg -> EW boson couplings.
7124 bool DireHistory::mayHaveEffectiveVertex( string process, vector<int> in,
7125  vector<int> out) {
7126 
7127  if ( process.compare("ta+ta->jj") == 0
7128  || process.compare("ta-ta+>jj") == 0 ) {
7129  int nInFermions(0), nOutFermions(0), nOutBosons(0);
7130  for (int i=0; i < int(in.size()); ++i)
7131  if (abs(in[i])<20) nInFermions++;
7132  for (int i=0; i < int(out.size()); ++i) {
7133  if (abs(out[i])<20) nOutFermions++;
7134  if (abs(out[i])>20) nOutBosons++;
7135  }
7136  return (nInFermions%2==0 && nOutFermions%2==0);
7137  }
7138 
7139  int nInG(0), nOutZ(0), nOutWp(0), nOutWm(0), nOutH(0), nOutA(0), nOutG(0);
7140  for (int i=0; i < int(in.size()); ++i)
7141  if (in[i]==21) nInG++;
7142  for (int i=0; i < int(out.size()); ++i) {
7143  if (out[i] == 21) nOutG++;
7144  if (out[i] == 22) nOutA++;
7145  if (out[i] == 23) nOutZ++;
7146  if (out[i] == 24) nOutWp++;
7147  if (out[i] ==-24) nOutWm++;
7148  if (out[i] == 25) nOutH++;
7149  }
7150 
7151  if ( nInG==2 && nOutWp+nOutWm > 0 && nOutWp+nOutWm == int(out.size())
7152  && nOutWp-nOutWm == 0)
7153  return true;
7154  if (nInG+nOutG>0 && nOutH > 0)
7155  return true;
7156 
7157  if ( process.find("Hinc") != string::npos
7158  && process.find("Ainc") != string::npos
7159  && (nOutH > 0 || nOutA%2==0) )
7160  return true;
7161 
7162  return false;
7163 }
7164 
7165 //--------------------------------------------------------------------------
7166 
7167 // Set selected child indices.
7168 
7169 void DireHistory::setSelectedChild() {
7170 
7171  if (mother == nullptr) return;
7172  for (int i = 0;i < int(mother->children.size());++i)
7173  if (mother->children[i] == this) mother->selectedChild = i;
7174  mother->setSelectedChild();
7175 }
7176 
7177 //--------------------------------------------------------------------------
7178 
7179 // Store index of children that pass "trimHistories".
7180 
7181 void DireHistory::setGoodChildren() {
7182  if (mother == nullptr) return;
7183  for (int i = 0;i < int(mother->children.size());++i)
7184  if (mother->children[i] == this) {
7185  // Nothing to be done if good child is already tagged.
7186  if ( find(mother->goodChildren.begin(), mother->goodChildren.end(), i)
7187  != mother->goodChildren.end() ) continue;
7188  mother->goodChildren.push_back(i);
7189  }
7190  mother->setGoodChildren();
7191 }
7192 
7193 //--------------------------------------------------------------------------
7194 
7195 // Store index of children that pass "trimHistories".
7196 
7197 void DireHistory::setGoodSisters() {
7198 
7199  for (int i = 0;i < int(goodChildren.size());++i) {
7200  for (int j = 0;j < int(goodChildren.size());++j) {
7201  children[i]->goodSisters.push_back(children[j]);
7202  }
7203  children[i]->setGoodSisters();
7204  }
7205  if (!mother) goodSisters.push_back(this);
7206 
7207 }
7208 
7209 //--------------------------------------------------------------------------
7210 
7211 // Store index of children that pass "trimHistories".
7212 
7213 void DireHistory::printMECS() {
7214 
7215  if ( !mother && children.size() > 0 && (MECnum/MECden > 1e2 )) {
7216  cout << scientific << setprecision(6);
7217  listFlavs(state);
7218  cout << " " << goodChildren.size() << " num " << MECnum
7219  << " den " << MECden << endl;
7220  }
7221  if (mother ) mother->printMECS();
7222  return;
7223 
7224 }
7225 
7226 //--------------------------------------------------------------------------
7227 
7228 void DireHistory::setProbabilities() {
7229 
7230  for (int i = 0;i < int(goodSisters.size());++i) {
7231 
7232  DireHistory* sisterNow = goodSisters[i];
7233  bool foundOrdered=false;
7234  double denominator=0.;
7235  double contrib=0.;
7236  double denominator_unconstrained=0.;
7237  double contrib_unconstrained=0.;
7238 
7239  for (int j = 0;j < int(sisterNow->goodChildren.size());++j) {
7240 
7241  DireHistory* childNow = sisterNow->children[j];
7242 
7243  double virtuality = 2.*(childNow->clusterIn.rad()->p()*
7244  childNow->clusterIn.emt()->p());
7245 
7246  // Get clustering variables.
7247  map<string,double> stateVars;
7248  int rad = childNow->clusterIn.radPos();
7249  int emt = childNow->clusterIn.emtPos();
7250  int rec = childNow->clusterIn.recPos();
7251 
7252  bool hasPartonLevel(showers && showers->timesPtr && showers->spacePtr),
7253  hasShowers(fsr && isr), isFSR(false);
7254  if (hasPartonLevel) {
7255  isFSR = showers->timesPtr->isTimelike
7256  (sisterNow->state, rad, emt, rec, "");
7257  if (isFSR) stateVars = showers->timesPtr->getStateVariables
7258  (sisterNow->state,rad,emt,rec,"");
7259  else stateVars = showers->spacePtr->getStateVariables
7260  (sisterNow->state,rad,emt,rec,"");
7261  } else if (hasShowers) {
7262  isFSR = fsr->isTimelike(sisterNow->state, rad, emt, rec, "");
7263  if (isFSR) stateVars = fsr->getStateVariables
7264  (sisterNow->state,rad,emt,rec,"");
7265  else stateVars = isr->getStateVariables
7266  (sisterNow->state,rad,emt,rec,"");
7267  }
7268 
7269  double z = stateVars["z"];
7270  double t = stateVars["t"];
7271  double Q2 = stateVars["m2dip"];
7272  double xCS = 1.;
7273  // For splittings with initial-state particles, remember initial
7274  // momentum rescaling.
7275  if ( !isFSR && !sisterNow->state[rec].isFinal() ) {
7276  double kappa2 = t/Q2;
7277  xCS = (z*(1-z) - kappa2) / (1 -z);
7278  } else if ( !isFSR && sisterNow->state[rec].isFinal() ) {
7279  xCS = z;
7280  } else if ( isFSR && !sisterNow->state[rec].isFinal() ) {
7281  double kappa2 = t/Q2;
7282  xCS = 1 - kappa2/(1.-z);
7283  if (abs(Q2) < 1e-5) xCS = 1.;
7284  }
7285 
7286  double dd = childNow->MECnum
7287  * childNow->clusterProb
7288  // clusterProb includes 1/pT2, but here, we only want
7289  // the propagator factor 1/(2.*pipj)
7290  * pow2(childNow->clusterIn.pT()) / virtuality
7291  // extra factor left-over from 8*Pi*alphaS of dipole ME
7292  // factorization:
7293  // |Mn+1|^2 ~ 8*Pi*alphaS*1/(2.pipj)*1/x*dipole*|Mn|^2
7294  // = 2g^2 *1/(2.pipj)*1/x*dipole*|Mn|^2
7295  // compared with using g^2=1 in MG5 MEs.
7296  // * 2.
7297  // Part of the definition of dipole factorization.
7298  * 1 / xCS
7299  / childNow->MECden * childNow->MECcontrib;
7300 
7301  // Multiply coupling.
7302  double coupl = 1.;
7303  string name = childNow->clusterIn.name();
7304  if (hasPartonLevel) {
7305  if ( name.find("qcd") != string::npos
7306  || name.find("qed") != string::npos)
7307  coupl = childNow->clusterCoupl * 2. * M_PI * 8. * M_PI;
7308  else
7309  coupl = childNow->clusterCoupl;
7310  } else if (hasShowers) {
7311  if ( isFSR && ( fsr->splits[name]->is_qcd
7312  || fsr->splits[name]->is_qed))
7313  coupl = childNow->clusterCoupl * 2. * M_PI * 8. * M_PI;
7314  else if ( isr->splits[name]->is_qcd
7315  || isr->splits[name]->is_qed)
7316  coupl = childNow->clusterCoupl * 2. * M_PI * 8. * M_PI;
7317  else
7318  coupl = childNow->clusterCoupl;
7319  }
7320 
7321  dd *= coupl;
7322 
7323  denominator_unconstrained += dd;
7324 
7325  // Remember if this child contributes to the next-higher denominator.
7326  if (childNow->clusterIn.pT() > sisterNow->clusterIn.pT()) {
7327  contrib_unconstrained += dd;
7328  foundOrdered=true;
7329  }
7330 
7331  // Careful about first emissions above the factorization scale.
7332  if ( int(childNow->goodChildren.size()) == 0
7333  && hardStartScale(childNow->state) > childNow->clusterIn.pT()) {
7334  denominator += dd;
7335  if (childNow->clusterIn.pT() > sisterNow->clusterIn.pT())
7336  contrib += dd;
7337  } else if (int(childNow->goodChildren.size()) > 0) {
7338  denominator += dd;
7339  if (childNow->clusterIn.pT() > sisterNow->clusterIn.pT())
7340  contrib += dd;
7341  }
7342 
7343  }
7344 
7345  // Update ME correction pieces in sister node.
7346  if (sisterNow->children.size() > 0) {
7347  if (denominator != 0.0) goodSisters[i]->MECden = denominator;
7348  goodSisters[i]->MECcontrib = contrib;
7349  if (denominator == 0. && contrib == 0.) {
7350  if (denominator_unconstrained != 0.0)
7351  goodSisters[i]->MECden = denominator_unconstrained;
7352  goodSisters[i]->MECcontrib = contrib_unconstrained;
7353  }
7354 
7355  if (!foundOrdered) goodSisters[i]->foundOrderedChildren = false;
7356 
7357  }
7358 
7359  }
7360 
7361  if (mother) mother->setProbabilities();
7362 
7363  return;
7364 
7365 }
7366 
7367 //--------------------------------------------------------------------------
7368 
7369 void DireHistory::setEffectiveScales() {
7370 
7371  for (int i = 0;i < int(goodSisters.size());++i) {
7372 
7373  DireHistory* sisterNow = goodSisters[i];
7374 
7375  // Nothing to do if there are no children.
7376  if (sisterNow->goodChildren.size()==0) continue;
7377 
7378  double alphasOftEff_num(0.), alphasOftEff_den(0.), tmin(1e15), tmax(-1.0);
7379 
7380  for (int j = 0;j < int(sisterNow->goodChildren.size());++j) {
7381 
7382  DireHistory* childNow = sisterNow->children[j];
7383 
7384  // Scale with correct coupling factor.
7385  double t(pow2(childNow->clusterIn.pT()));
7386  tmax = max(tmax,t);
7387  tmin = min(tmin,t);
7388 
7389  // We will want to choose an effective scale by solving
7390  // as(teff) = (sum of kernel*propagator*MEC) . Note that we DO NOT
7391  // include the Jacobian here, and consequently have to remove its
7392  // contribution from clusterProb. Also, an extra 1/x-factor has
7393  // to be included for inital-state splittings.
7394  double massSign = childNow->clusterIn.rad()->isFinal() ? 1. : -1.;
7395  double virtuality = massSign*(childNow->clusterIn.rad()->p()
7396  + massSign*childNow->clusterIn.emt()->p()).m2Calc();
7397  // Get clustering variables.
7398  map<string,double> stateVars;
7399  int rad = childNow->clusterIn.radPos();
7400  int emt = childNow->clusterIn.emtPos();
7401  int rec = childNow->clusterIn.recPos();
7402  bool hasPartonLevel(showers && showers->timesPtr && showers->spacePtr),
7403  hasShowers(fsr && isr), isFSR(false);
7404  if (hasPartonLevel) {
7405  isFSR = showers->timesPtr->isTimelike
7406  (sisterNow->state, rad, emt, rec, "");
7407  if (isFSR) stateVars = showers->timesPtr->getStateVariables
7408  (sisterNow->state,rad,emt,rec,"");
7409  else stateVars = showers->spacePtr->getStateVariables
7410  (sisterNow->state,rad,emt,rec,"");
7411  } else if (hasShowers) {
7412  isFSR = fsr->isTimelike(sisterNow->state, rad, emt, rec, "");
7413  if (isFSR) stateVars = fsr->getStateVariables
7414  (sisterNow->state,rad,emt,rec,"");
7415  else stateVars = isr->getStateVariables
7416  (sisterNow->state,rad,emt,rec,"");
7417  }
7418 
7419  double z = stateVars["z"];
7420  double Q2 = stateVars["m2dip"];
7421  double xCS = 1.;
7422  // For splittings with initial-state particles, remember initial
7423  // momentum rescaling.
7424  if ( !isFSR && !sisterNow->state[rec].isFinal() ) {
7425  double kappa2 = t/Q2;
7426  xCS = (z*(1-z) - kappa2) / (1 -z);
7427  } else if ( !isFSR && sisterNow->state[rec].isFinal() ) {
7428  xCS = z;
7429  } else if ( isFSR && !sisterNow->state[rec].isFinal() ) {
7430  double kappa2 = t/Q2;
7431  xCS = 1 - kappa2/(1.-z);
7432  }
7433 
7434  // Construct coupling.
7435  double coupling(1.);
7436  string name = childNow->clusterIn.name();
7437  int idRadBef = int(stateVars["radBefID"]);
7438  int idRec = sisterNow->state[rec].id();
7439  if (hasPartonLevel) {
7440  if ( name.find("qcd") != string::npos)
7441  coupling = mergingHooksPtr->AlphaS_FSR()->alphaS(t);
7442  else if ( name.find("qed") != string::npos)
7443  coupling = pow2(childNow->clusterIn.rad()->charge())
7444  * mergingHooksPtr->AlphaEM_FSR()->alphaEM(t);
7445  else if ( name.find("ew") != string::npos) {
7446  int flav = abs(childNow->clusterIn.flavRadBef);
7447  coupling = 4.*M_PI
7448  * (pow2(coupSMPtr->rf( flav )) + pow2(coupSMPtr->lf( flav )))
7449  / (coupSMPtr->sin2thetaW() * coupSMPtr->cos2thetaW());
7450  }
7451  } else if (hasShowers) {
7452  if (isFSR) coupling = 2.*M_PI*fsr->splits[name]->coupling(z,t,Q2,-1.,
7453  make_pair(idRadBef, sisterNow->state[rad].isFinal()),
7454  make_pair(idRec, sisterNow->state[rec].isFinal()) );
7455  else coupling = 2.*M_PI*isr->splits[name]->coupling(z,t,Q2,-1.,
7456  make_pair(idRadBef, sisterNow->state[rad].isFinal()),
7457  make_pair(idRec, sisterNow->state[rec].isFinal()) );
7458  }
7459 
7460  //double prob = childNow->clusterProb
7461  double prob = abs(childNow->clusterProb)
7462  // clusterProb includes 1/pT2, but here, we only want
7463  // the propagator factor 1/(2.*pipj)
7464  * pow2(childNow->clusterIn.pT()) / virtuality
7465  // extra factor left-over from 8*Pi*alphaS of dipole ME
7466  // factorization:
7467  // |Mn+1|^2 ~ 8*Pi*alphaS*1/(2.pipj)*1/x*dipole*|Mn|^2
7468  // = 2g^2 *1/(2.pipj)*1/x*dipole*|Mn|^2
7469  // compared with using g^2=1 in MG5 MEs.
7470  * 2.
7471  // Part of the definition of dipole factorization.
7472  * 1 / xCS;
7473 
7474  // Include alphaS at effective scale of previous order.
7475  double alphasOftEffPrev(childNow->couplEffective);
7476  alphasOftEff_num += prob * childNow->MECnum * alphasOftEffPrev
7477  * coupling;
7478  alphasOftEff_den += prob * childNow->MECnum;
7479 
7480  }
7481 
7482  // Calculate the effective scale.
7483  // Note: For negative probabilities, it might be necessary to increase the
7484  // scale range for root finding.
7485  DireCouplFunction couplFunc( mergingHooksPtr->AlphaS_FSR(),
7486  couplingPowCount["qcd"], mergingHooksPtr->AlphaEM_FSR(),
7487  couplingPowCount["qed"]);
7488  double as_tmin = couplFunc.f(tmin,vector<double>());
7489  double as_tmax = couplFunc.f(tmax,vector<double>());
7490  double headroom = 1.;
7491  bool failed = false;
7492  double alphasOftEffRatio = pow(alphasOftEff_num/alphasOftEff_den,1.);
7493  while ( tmin/headroom < tmax*headroom
7494  && ( ( as_tmin-alphasOftEffRatio > 0
7495  && as_tmax-alphasOftEffRatio > 0)
7496  || ( as_tmin-alphasOftEffRatio < 0
7497  && as_tmax-alphasOftEffRatio < 0))) {
7498  if (tmin/headroom < mergingHooksPtr->pTcut()) { failed = true; break;}
7499  headroom *= 1.01;
7500  as_tmin = couplFunc.f(tmin/headroom,vector<double>());
7501  as_tmax = couplFunc.f(tmax*headroom,vector<double>());
7502  }
7503 
7504  // Include correct power for effective alphaS.
7505  DireRootFinder direRootFinder;
7506  double teff = mergingHooksPtr->pTcut();
7507  double tminNow(tmin/headroom), tmaxNow(tmax*headroom);
7508  if (!failed) {
7509  if (abs(tmaxNow-tminNow)/tmaxNow < 1e-4) teff = tmaxNow;
7510  else teff = direRootFinder.findRoot1D( &couplFunc, tminNow, tmaxNow,
7511  alphasOftEffRatio, vector<double>(), 100);
7512  }
7513 
7514  // Set the effective scale for currect sister.
7515  sisterNow->scaleEffective = sqrt(teff);
7516  sisterNow->couplEffective = alphasOftEffRatio;
7517 
7518  }
7519 
7520  if (mother) mother->setEffectiveScales();
7521 
7522  return;
7523 
7524 }
7525 
7526 //--------------------------------------------------------------------------
7527 
7528 // Function to retrieve scale information from external showers.
7529 
7530 double DireHistory::getShowerPluginScale(const Event& event, int rad, int emt,
7531  int rec, string name, string key, double) {
7532 
7533  map<string,double> stateVars;
7534  bool hasPartonLevel(showers && showers->timesPtr && showers->spacePtr),
7535  hasShowers(fsr && isr);
7536  if (hasPartonLevel) {
7537  bool isFSR = showers->timesPtr->isTimelike(event, rad, emt, rec, "");
7538  if (isFSR) stateVars = showers->timesPtr->getStateVariables
7539  (event, rad, emt, rec, name);
7540  else stateVars = showers->spacePtr->getStateVariables
7541  (event, rad, emt, rec, name);
7542  } else if (hasShowers) {
7543  bool isFSR = fsr->isTimelike(event, rad, emt, rec, "");
7544  if (isFSR) stateVars = fsr->getStateVariables(event, rad, emt, rec, name);
7545  else stateVars = isr->getStateVariables(event, rad, emt, rec, name);
7546  }
7547 
7548  return ( (stateVars.size() > 0 && stateVars.find(key) != stateVars.end())
7549  ? stateVars[key] : -1.0 );
7550 
7551 }
7552 
7553 //--------------------------------------------------------------------------
7554 
7555 // Function to retrieve type of splitting from external showers.
7556 
7557 pair<int,double> DireHistory::getCoupling(const Event& event, int rad, int emt,
7558  int rec, string name) {
7559 
7560  // Retrieve state variables.
7561  map<string,double> stateVars;
7562  bool hasPartonLevel(showers && showers->timesPtr && showers->spacePtr),
7563  hasShowers(fsr && isr);
7564  if (hasPartonLevel) {
7565  bool isFSR = showers->timesPtr->isTimelike(event, rad, emt, rec, "");
7566  if (isFSR) stateVars = showers->timesPtr->getStateVariables
7567  (event, rad, emt, rec, name);
7568  else stateVars = showers->spacePtr->getStateVariables
7569  (event, rad, emt, rec, name);
7570  } else if (hasShowers) {
7571  bool isFSR = fsr->isTimelike(event, rad, emt, rec, "");
7572  if (isFSR) stateVars = fsr->getStateVariables(event, rad, emt, rec, name);
7573  else stateVars = isr->getStateVariables(event, rad, emt, rec, name);
7574  }
7575 
7576  // Get coupling type (identifier of interaction), and get coupling value for
7577  // the current splitting, i.e. 1 / [4\pi] * g^2 {splitting variables}
7578  int type = ( (stateVars.size() > 0
7579  && stateVars.find("couplingType") != stateVars.end())
7580  ? stateVars["couplingType"] : -1);
7581  double value = ( (stateVars.size() > 0
7582  && stateVars.find("couplingValue") != stateVars.end())
7583  ? stateVars["couplingValue"] : -1.0);
7584 
7585  // Done.
7586  return make_pair(type,value);
7587 
7588 }
7589 
7590 //--------------------------------------------------------------------------
7591 
7592 // Store if path is considered "signal" or "background" according to a
7593 // user-defined criterion.
7594 
7595 void DireHistory::tagPath(DireHistory* leaf) {
7596 
7597  int nHiggs = 0;
7598  for (int i=0; i < state.size(); ++i)
7599  if (state[i].isFinal() && state[i].id() == 25) nHiggs++;
7600  // Tag as Higgs signal.
7601  if (nHiggs > 0) leaf->tagSave.push_back("higgs");
7602  if (leaf == this) {
7603  int nFinal(0), nFinalPartons(0), nFinalGamma(0);
7604  for (int i = 0;i < state.size();++i) {
7605  if (state[i].isFinal()) {
7606  nFinal++;
7607  if ( state[i].idAbs() < 10
7608  || state[i].idAbs() == 21) nFinalPartons++;
7609  if ( state[i].idAbs() == 22) nFinalGamma++;
7610  }
7611  }
7612  // Tag as QCD signal.
7613  if (nFinal == 2 && nFinalPartons == 2)
7614  leaf->tagSave.push_back("qcd");
7615  // Tag as QED signal.
7616  if (nFinal == 2 && nFinalGamma == 2)
7617  leaf->tagSave.push_back("qed");
7618  // Tag as QCD and QED signal.
7619  if (nFinal == 2 && nFinalGamma == 1 && nFinalPartons == 1) {
7620  leaf->tagSave.push_back("qed");
7621  leaf->tagSave.push_back("qcd");
7622  }
7623  }
7624 
7625  if (mother) mother->tagPath(leaf);
7626  return;
7627 
7628 }
7629 
7630 //--------------------------------------------------------------------------
7631 
7632 // Multiply ME corrections to the probability of the path.
7633 
7634 void DireHistory::multiplyMEsToPath(DireHistory* leaf) {
7635 
7636  if (leaf == this) {
7637  leaf->prodOfProbsFull *= hardProcessCouplings(state)*clusterCoupl;
7638  leaf->prodOfProbs *= abs(hardProcessCouplings(state)*clusterCoupl);
7639  } else {
7640  leaf->prodOfProbsFull *= MECnum/MECden*clusterCoupl;
7641  leaf->prodOfProbs *= abs(MECnum/MECden*clusterCoupl);
7642  }
7643 
7644  if (mother) mother->multiplyMEsToPath(leaf);
7645 
7646  return;
7647 }
7648 
7649 //--------------------------------------------------------------------------
7650 
7651 // Set coupling power counters in the path.
7652 
7653 void DireHistory::setCouplingOrderCount(DireHistory* leaf,
7654  map<string,int> count) {
7655 
7656  string name = clusterIn.name();
7657  if (leaf == this) {
7658  // Count hard process couplings.
7659  hardProcessCouplings(state, 0, 1., nullptr, nullptr, true);
7660  // Update with coupling order of clustering.
7661  count = couplingPowCount;
7662 
7663  } else if (couplingPowCount.empty()) {
7664  couplingPowCount = count;
7665  }
7666 
7667  if ( name.find("qcd") != string::npos) count["qcd"]++;
7668  if ( name.find("qed") != string::npos) count["qed"]++;
7669 
7670  if (mother) mother->setCouplingOrderCount(leaf, count);
7671 
7672  return;
7673 }
7674 
7675 //==========================================================================
7676 
7677 } // end namespace Pythia8
Definition: beam.h:43
Definition: AgUStep.h:26