]> git.uio.no Git - u/mrichter/AliRoot.git/blame - PYTHIA8/pythia8170/src/History.cxx
Stupid bug fix in new superlight mode (from Zurich airport)
[u/mrichter/AliRoot.git] / PYTHIA8 / pythia8170 / src / History.cxx
CommitLineData
63ba5337 1// History.cc is a part of the PYTHIA event generator.
2// Copyright (C) 2012 Torbjorn Sjostrand.
3// PYTHIA is licenced under the GNU GPL version 2, see COPYING for details.
4// Please respect the MCnet Guidelines, see GUIDELINES for details.
5
6// This file is written by Stefan Prestel.
7// Function definitions (not found in the header) for the
8// Clustering and History classes.
9
10#include "History.h"
11
12namespace Pythia8 {
13
14//==========================================================================
15
16// The Clustering class.
17
18//--------------------------------------------------------------------------
19
20// Declaration of Clustering class
21// This class holds information about one radiator, recoiler,
22// emitted system.
23// This class is a container class for History class use.
24
25// print for debug
26void Clustering::list() const {
27 cout << " emt " << emitted
28 << " rad " << emittor
29 << " rec " << recoiler
30 << " partner " << partner
31 << " pTscale " << pTscale << endl;
32}
33
34//==========================================================================
35
36// The History class.
37
38// A History object represents an event in a given step in the CKKW-L
39// clustering procedure. It defines a tree-like recursive structure,
40// where the root node represents the state with n jets as given by
41// the matrix element generator, and is characterized by the member
42// variable mother being null. The leaves on the tree corresponds to a
43// fully clustered paths where the original n-jets has been clustered
44// down to the Born-level state. Also states which cannot be clustered
45// down to the Born-level are possible - these will be called
46// incomplete. The leaves are characterized by the vector of children
47// being empty.
48
49//--------------------------------------------------------------------------
50
51// Declaration of History class
52// The only constructor. Default arguments are used when creating
53// the initial history node. The \a depth is the maximum number of
54// clusterings requested. \a scalein is the scale at which the \a
55// statein was clustered (should be set to the merging scale for the
56// initial history node. \a beamAIn and beamBIn are needed to
57// calcutate PDF ratios, \a particleDataIn to have access to the
58// correct masses of particles. If \a isOrdered is true, the previous
59// clusterings has been ordered. \a is the PDF ratio for this
60// clustering (=1 for FSR clusterings). \a probin is the accumulated
61// probabilities for the previous clusterings, and \ mothin is the
62// previous history node (null for the initial node).
63
64History::History( int depth,
65 double scalein,
66 Event statein,
67 Clustering c,
68 MergingHooks* mergingHooksPtrIn,
69 BeamParticle beamAIn,
70 BeamParticle beamBIn,
71 ParticleData* particleDataPtrIn,
72 Info* infoPtrIn,
73 bool isOrdered = true,
74 bool isUnordered = true,
75 bool isStronglyOrdered = true,
76 bool isAllowed = true,
77 double probin = 1.0,
78 History * mothin = 0)
79 : state(statein),
80 mother(mothin),
81 sumpath(0.0),
82 sumGoodBranches(0.0),
83 sumBadBranches(0.0),
84 foundOrderedPath(false),
85 foundUnorderedPath(false),
86 foundStronglyOrderedPath(false),
87 foundAllowedPath(false),
88 foundCompletePath(false),
89 scale(scalein),
90 prob(probin),
91 clusterIn(c),
92 iReclusteredOld(0),
93 doInclude(true),
94 mergingHooksPtr(mergingHooksPtrIn),
95 beamA(beamAIn),
96 beamB(beamBIn),
97 particleDataPtr(particleDataPtrIn),
98 infoPtr(infoPtrIn)
99 {
100
101 // Initialise beam particles
102 setupBeams();
103 // Update probability with PDF ratio
104 if (mother && mergingHooksPtr->includeRedundant()) prob *= pdfForSudakov();
105
106 // Minimal scalar sum of pT used in Herwig to choose history
107 // Keep track of scalar PT
108 if (mother) {
109 double acoll = (mother->state[clusterIn.emittor].isFinal())
110 ? mergingHooksPtr->herwigAcollFSR()
111 : mergingHooksPtr->herwigAcollISR();
112 sumScalarPT = mother->sumScalarPT + acoll*scale;
113 } else
114 sumScalarPT = 0.0;
115
116 // Remember reclustered radiator in lower multiplicity state
117 if ( mother ) iReclusteredOld = mother->iReclusteredNew;
118
119 // Check if more steps should be taken.
120 int nFinalP = 0;
121 int nFinalW = 0;
122 for ( int i = 0; i < int(state.size()); ++i )
123 if ( state[i].isFinal() ) {
124 if ( state[i].colType() != 0 )
125 nFinalP++;
126 if ( state[i].idAbs() == 24 )
127 nFinalW++;
128 }
129 if ( mergingHooksPtr->doWClustering()
130 && nFinalP == 2 && nFinalW == 0 ) depth = 0;
131
132 // If this is not the fully clustered state, try to find possible
133 // QCD clusterings.
134 vector<Clustering> clusterings;
135 if ( depth > 0 ) clusterings = getAllQCDClusterings();
136
137 // If necessary, try to find possible EW clusterings.
138 vector<Clustering> clusteringsEW;
139 if ( depth > 0 && mergingHooksPtr->doWClustering() )
140 clusteringsEW = getAllEWClusterings();
141 if ( !clusteringsEW.empty() ) {
142 clusterings.resize(0);
143 clusterings.insert( clusterings.end(), clusteringsEW.begin(),
144 clusteringsEW.end() );
145 }
146 // If no clusterings were found, the recursion is done and we
147 // register this node.
148 if ( clusterings.empty() ) {
149 registerPath( *this, isOrdered, isUnordered, isStronglyOrdered,
150 isAllowed, depth == 0 );
151 return;
152 }
153
154 // Now we sort the possible clusterings so that we try the
155 // smallest scale first.
156 multimap<double, Clustering *> sorted;
157 for ( int i = 0, N = clusterings.size(); i < N; ++i ) {
158 sorted.insert(make_pair(clusterings[i].pT(), &clusterings[i]));
159 }
160
161 for ( multimap<double, Clustering *>::iterator it = sorted.begin();
162 it != sorted.end(); ++it ) {
163
164 // If this path is not strongly ordered and we already have found an
165 // ordered path, then we don't need to continue along this path.
166 bool stronglyOrdered = isStronglyOrdered;
167 if ( mergingHooksPtr->enforceStrongOrdering()
168 && ( !stronglyOrdered
169 || ( mother && ( it->first <
170 mergingHooksPtr->scaleSeparationFactor()*scale ) ))) {
171 if ( onlyStronglyOrderedPaths() ) continue;
172 stronglyOrdered = false;
173 }
174
175 bool ordered = isOrdered;
176 bool unordered = isUnordered;
177 if ( mergingHooksPtr->orderInRapidity()
178 && mergingHooksPtr->orderHistories() ) {
179 // Get new z value
180 double z = getCurrentZ((*it->second).emittor,
181 (*it->second).recoiler,(*it->second).emitted);
182 // Get z value of splitting that produced this state
183 double zOld = (!mother) ? 0. : mother->getCurrentZ(clusterIn.emittor,
184 clusterIn.recoiler,clusterIn.emitted);
185 // If this path is not ordered in pT and y, and we already have found
186 // an ordered path, then we don't need to continue along this path.
187 if ( !ordered || ( mother && (it->first < scale
188 || it->first < pow(1. - z,2) / (z * (1. - zOld ))*scale ))) {
189 if ( onlyOrderedPaths() ) continue;
190 ordered = false;
191 }
192
193 } else if ( mergingHooksPtr->orderHistories() ) {
194 // If this path is not ordered in pT and we already have found an
195 // ordered path, then we don't need to continue along this path.
196 if ( !ordered || ( mother && (it->first < scale) ) ) {
197 if ( onlyOrderedPaths() ) continue;
198 ordered = false;
199 }
200 } else if ( mergingHooksPtr->forceUnorderedHistories() ) {
201 // If this path is not unordered in pT and we already have found an
202 // unordered path, then we don't need to continue along this path.
203 if ( !unordered || ( mother && (it->first > scale) ) ) {
204 if ( onlyUnorderedPaths() ) continue;
205 unordered = false;
206 }
207 }
208
209 // Check if reclustered state should be disallowed
210 bool doCut = mergingHooksPtr->canCutOnRecState()
211 || mergingHooksPtr->allowCutOnRecState();
212 bool allowed = isAllowed;
213
214 if ( doCut
215 && mergingHooksPtr->doCutOnRecState(cluster(*it->second)) ) {
216 if ( onlyAllowedPaths() ) continue;
217 allowed = false;
218 }
219
220 // Perform the clustering and recurse and construct the next
221 // history node.
222 children.push_back(new History(depth - 1,it->first,cluster(*it->second),
223 *it->second, mergingHooksPtr, beamA, beamB, particleDataPtr,
224 infoPtr, ordered, unordered, stronglyOrdered, allowed,
225 prob*getProb(*it->second), this ));
226 }
227}
228
229//--------------------------------------------------------------------------
230
231// Function to project all possible paths onto only the desired paths.
232
233bool History::projectOntoDesiredHistories() {
234 // At the moment, only trim histories.
235 return trimHistories();
236}
237
238//--------------------------------------------------------------------------
239
240// In the initial history node, select one of the paths according to
241// the probabilities. This function should be called for the initial
242// history node.
243// IN trialShower* : Previously initialised trialShower object,
244// to perform trial showering and as
245// repository of pointers to initialise alphaS
246// PartonSystems* : PartonSystems object needed to initialise
247// shower objects
248// OUT double : (Sukadov) , (alpha_S ratios) , (PDF ratios)
249
250double History::weightTREE(PartonLevel* trial, AlphaStrong * asFSR,
251 AlphaStrong * asISR, double RN) {
252
253 // Read alpha_S in ME calculation and maximal scale (eCM)
254 double asME = infoPtr->alphaS();
255 double maxScale = (foundCompletePath) ? infoPtr->eCM() : infoPtr->QFac();
256 // Select a path of clusterings
257 History * selected = select(RN);
258 // Set scales in the states to the scales pythia would have set
259 selected->setScalesInHistory();
260 // Get weight.
261 double asWeight = 1.;
262 double pdfWeight = 1.;
263
264 // Do trial shower, calculation of alpha_S ratios, PDF ratios
265 double wt = selected->weightTree(trial, asME, maxScale,
266 selected->clusterIn.pT(), asFSR, asISR, asWeight, pdfWeight);
267
268 // Set hard process renormalisation scale to default Pythia value.
269 bool resetScales = mergingHooksPtr->resetHardQRen();
270 // For pure QCD dijet events, evaluate the coupling of the hard process at
271 // a more reasonable pT, rather than evaluation \alpha_s at a fixed
272 // arbitrary scale.
273 if ( resetScales
274 && mergingHooksPtr->getProcessString().compare("pp>jj") == 0) {
275 // Reset to a running coupling. Here we choose FSR for simplicity.
276 double newQ2Ren = pow2( selected->hardRenScale() );
277 double runningCoupling = (*asFSR).alphaS(newQ2Ren) / asME;
278 asWeight *= pow(runningCoupling,2);
279 }
280
281 // For prompt photon events, evaluate the coupling of the hard process at
282 // a more reasonable pT, rather than evaluation \alpha_s at a fixed
283 // arbitrary scale.
284 if ( resetScales
285 && mergingHooksPtr->getProcessString().compare("pp>aj") == 0) {
286 // Reset to a running coupling. In prompt photon always ISR.
287 double newQ2Ren = pow2( selected->hardRenScale() );
288 double runningCoupling =
289 (*asISR).alphaS( newQ2Ren + pow(mergingHooksPtr->pT0ISR(),2) ) / asME;
290 asWeight *= runningCoupling;
291 }
292
293 // Done
294 return (wt*asWeight*pdfWeight);
295}
296
297//--------------------------------------------------------------------------
298
299// Function to set the state with complete scales for evolution.
300
301void History::getStartingConditions( const double RN, Event& outState ) {
302
303 // Select the history
304 History * selected = select(RN);
305
306
307 // Copy the output state
308 outState = state;
309
310 // Set the scale of the lowest order process
311 if (!selected->mother) {
312 int nFinal = 0;
313 for(int i=0; i < int(outState.size()); ++i)
314 if (outState[i].isFinal()) nFinal++;
315 if (nFinal <=2)
316 outState.scale(infoPtr->QFac());
317// // If the hard process has a resonance decay which is not
318// // corrected (e.g. for pp -> (V->jj) + jets merging), set
319// // factorization scale as starting scale
320// if (mergingHooksPtr->hardProcess.hasResInProc())
321// outState.scale(infoPtr->QFac());
322// // If the hard process has a resonance decay which is
323// // corrected (e.g. for e+e- -> 2 + n jets merging), set
324// // half the intermediate mass as starting scale
325// else
326// outState.scale(0.5*outState[5].m());
327
328 // Save information on last splitting, to allow the next
329 // emission in the shower to have smaller rapidity with
330 // respect to the last ME splitting
331 // For hard process, use dummy values
332 if (mergingHooksPtr->getNumberOfClusteringSteps(state) == 0) {
333 infoPtr->zNowISR(0.5);
334 infoPtr->pT2NowISR(pow(state[0].e(),2));
335 infoPtr->hasHistory(true);
336 // For incomplete process, try to use real values
337 } else {
338 infoPtr->zNowISR(selected->zISR());
339 infoPtr->pT2NowISR(pow(selected->pTISR(),2));
340 infoPtr->hasHistory(true);
341 }
342
343 } else {
344 // Save information on last splitting, to allow the next
345 // emission in the shower to have smaller rapidity with
346 // respect to the last ME splitting
347 infoPtr->zNowISR(selected->zISR());
348 infoPtr->pT2NowISR(pow(selected->pTISR(),2));
349 infoPtr->hasHistory(true);
350 }
351
352}
353
354//--------------------------------------------------------------------------
355
356// Function to set the state with complete scales for evolution.
357
358bool History::getClusteredEvent( const double RN, Event& outState,
359 int nSteps) {
360
361 // Select history
362 History * selected = select(RN);
363 // Set scales in the states to the scales pythia would have set
364 // (Only needed if not done before in calculation of weights or
365 // setting of starting conditions)
366 selected->setScalesInHistory();
367 // If the history does not allow for nSteps clusterings (e.g. because the
368 // history is incomplete), return false
369 if (nSteps > selected->nClusterings()) return false;
370 // Return event with nSteps-1 additional partons (i.e. recluster the last
371 // splitting) and copy the output state
372 outState = selected->clusteredState(nSteps-1);
373 // Done
374 return true;
375
376}
377
378//--------------------------------------------------------------------------
379
380// Calculate and return pdf ratio.
381
382double History::getPDFratio( int side, bool forSudakov,
383 int flavNum, double xNum, double muNum,
384 int flavDen, double xDen, double muDen) {
385
386 // Do nothing for e+e- beams
387 if ( abs(flavNum) > 10 && flavNum != 21 ) return 1.0;
388 if ( abs(flavDen) > 10 && flavDen != 21 ) return 1.0;
389
390 // Now calculate PDF ratio if necessary
391 double pdfRatio = 1.0;
392
393 // Get mother and daughter pdfs
394 double pdfNum = 0.0;
395 double pdfDen = 0.0;
396
397 // Use rescaled PDFs in the presence of multiparton interactions
398 if (side == 1) {
399 if (forSudakov)
400 pdfNum = mother->beamA.xfISR(0, flavNum, xNum, muNum*muNum);
401 else
402 pdfNum = beamA.xfISR(0, flavNum, xNum, muNum*muNum);
403 if (forSudakov)
404 pdfDen = max(1e-10, beamA.xfISR(0, flavDen, xDen, muDen*muDen));
405 else
406 pdfDen = max(1e-10, beamA.xfISR(0, flavDen, xDen, muDen*muDen));
407
408 } else {
409 if (forSudakov)
410 pdfNum = mother->beamB.xfISR(0, flavNum, xNum, muNum*muNum);
411 else
412 pdfNum = beamB.xfISR(0, flavNum, xNum, muNum*muNum);
413
414 if (forSudakov)
415 pdfDen = max(1e-10,beamB.xfISR(0, flavDen, xDen, muDen*muDen));
416 else
417 pdfDen = max(1e-10,beamB.xfISR(0, flavDen, xDen, muDen*muDen));
418 }
419
420 // Return ratio of pdfs
421 if ( pdfNum > 1e-15 && pdfDen > 1e-10 ) {
422 pdfRatio *= pdfNum / pdfDen;
423
424 } else if ( pdfNum < pdfDen ) {
425 pdfRatio = 0.;
426 } else if ( pdfNum > pdfDen ) {
427 pdfRatio = 1.;
428 }
429
430 // Done
431 return pdfRatio;
432
433}
434
435//--------------------------------------------------------------------------
436
437/*--------------- METHODS USED FOR ONLY ONE PATH OF HISTORY NODES ------- */
438
439// Function to set all scales in the sequence of states. This is a
440// wrapper routine for setScales and setEventScales methods
441
442void History::setScalesInHistory() {
443 // Find correct links from n+1 to n states (mother --> child), as
444 // needed for enforcing ordered scale sequences
445 vector<int> ident;
446 findPath(ident);
447 // Set production scales in the states to the scales pythia would
448 // have set and enforce ordering
449 setScales(ident,true);
450 // Set the overall event scales to the scale of the last branching
451 setEventScales();
452}
453
454//--------------------------------------------------------------------------
455
456// Function to find the index (in the mother histories) of the
457// child history, thus providing a way access the path from both
458// initial history (mother == 0) and final history (all children == 0)
459// IN vector<int> : The index of each child in the children vector
460// of the current history node will be saved in
461// this vector
462// NO OUTPUT
463
464void History::findPath(vector<int>& out) {
465
466 // If the initial and final nodes are identical, return
467 if (!mother && int(children.size()) < 1) return;
468 // Find the child by checking the children vector for the perfomed
469 // clustering
470 int iChild=-1;
471 if ( mother ) {
472 int size = int(mother->children.size());
473 // Loop through children and identify child chosen
474 for ( int i=0; i < size; ++i) {
475 if ( mother->children[i]->scale == scale
476 && mother->children[i]->prob == prob
477 && equalClustering(mother->children[i]->clusterIn,clusterIn)) {
478 iChild = i;
479 break;
480 }
481 }
482 // Save the index of the child in the children vector and recurse
483 if (iChild >-1)
484 out.push_back(iChild);
485 mother->findPath(out);
486 }
487}
488
489//--------------------------------------------------------------------------
490
491// Functions to set the parton production scales and enforce
492// ordering on the scales of the respective clusterings stored in
493// the History node:
494// Method will start from lowest multiplicity state and move to
495// higher states, setting the production scales the shower would
496// have used.
497// When arriving at the highest multiplicity, the method will switch
498// and go back in direction of lower states to check and enforce
499// ordering for unordered histories.
500// IN vector<int> : Vector of positions of the chosen child
501// in the mother history to allow to move
502// in direction initial->final along path
503// bool : True: Move in direction low->high
504// multiplicity and set production scales
505// False: Move in direction high->low
506// multiplicity and check and enforce
507// ordering
508// NO OUTPUT
509
510void History::setScales( vector<int> index, bool forward) {
511
512 // First, set the scales of the hard process to the kinematial
513 // limit (=s)
514 if ( children.empty() && forward ) {
515 // New "incomplete" configurations showered from mu
516 if (!mother) {
517 double scaleNew = 1.;
518
519 if (mergingHooksPtr->incompleteScalePrescip()==0) {
520 scaleNew = infoPtr->QFac();
521 } else if (mergingHooksPtr->incompleteScalePrescip()==1) {
522 Vec4 pOut;
523 pOut.p(0.,0.,0.,0.);
524 for(int i=0; i<int(state.size()); ++i)
525 if (state[i].isFinal())
526 pOut += state[i].p();
527 scaleNew = pOut.mCalc();
528 } else if (mergingHooksPtr->incompleteScalePrescip()==2) {
529 scaleNew = state[0].e();
530 }
531
532 scaleNew = max( mergingHooksPtr->pTcut(), scaleNew);
533
534 state.scale(scaleNew);
535 for(int i=3; i < int(state.size());++i)
536 if (state[i].colType() != 0)
537 state[i].scale(scaleNew);
538 } else {
539 // 2->2 with non-parton particles showered from eCM
540 state.scale( state[0].e() );
541 // Count final partons
542 bool isLEP = ( state[3].isLepton() && state[4].isLepton() );
543 bool isQCD = true;
544 vector<int> finalPartons;
545 for(int i=0; i < int(state.size());++i) {
546 if (state[i].isFinal() && state[i].colType() != 0) {
547 finalPartons.push_back(i);
548 }
549 if (state[i].isFinal() && state[i].colType() == 0) {
550 isQCD = false;
551 break;
552 }
553 }
554 // If 2->2, purely partonic, set event scale to kinematic pT
555 if (!isLEP && isQCD && int(finalPartons.size()) == 2)
556 state.scale(state[finalPartons[0]].pT());
557
558 }
559 }
560 // Set all particle production scales, starting from lowest
561 // multiplicity (final) state
562 if (mother && forward) {
563 // When choosing splitting scale, beware of unordered splittings:
564 double scaleNew = 1.;
565 if (mergingHooksPtr->unorderedScalePrescip() == 0) {
566 // Use larger scale as common splitting scale for mother and child
567 scaleNew = max( mergingHooksPtr->pTcut(), max(scale,mother->scale));
568 } else if (mergingHooksPtr->unorderedScalePrescip() == 1) {
569 // Use smaller scale as common splitting scale for mother and child
570 if (scale < mother->scale)
571 scaleNew *= max( mergingHooksPtr->pTcut(), min(scale,mother->scale));
572 else
573 scaleNew *= max( mergingHooksPtr->pTcut(), max(scale,mother->scale));
574 }
575
576 // Rescale the mother state partons to the clustering scales
577 // that have been found along the path
578 mother->state[clusterIn.emitted].scale(scaleNew);
579 mother->state[clusterIn.emittor].scale(scaleNew);
580 mother->state[clusterIn.recoiler].scale(scaleNew);
581
582 // Find unchanged copies of partons in higher multiplicity states
583 // and rescale those
584 mother->scaleCopies(clusterIn.emitted, mother->state, scaleNew);
585 mother->scaleCopies(clusterIn.emittor, mother->state, scaleNew);
586 mother->scaleCopies(clusterIn.recoiler, mother->state, scaleNew);
587
588 // Recurse
589 mother->setScales(index,true);
590 }
591
592 // Now, check and correct ordering from the highest multiplicity
593 // state backwards to all the clustered states
594 if (!mother || !forward) {
595 // Get index of child along the path
596 int iChild = -1;
597 if ( int(index.size()) > 0 ) {
598 iChild = index.back();
599 index.pop_back();
600 }
601
602 // Check that the reclustered scale is above the shower cut
603 if (mother) {
604 scale = max(mergingHooksPtr->pTcut(), scale);
605 }
606 // If this is NOT the 2->2 process, check and enforce ordering
607 if (iChild != -1 && !children.empty()) {
608
609 if (scale > children[iChild]->scale ) {
610 if (mergingHooksPtr->unorderedScalePrescip() == 0) {
611 // Use larger scale as common splitting scale for mother and child
612 double scaleNew = max( mergingHooksPtr->pTcut(),
613 max(scale,children[iChild]->scale));
614 // Enforce ordering in particle production scales
615 for( int i = 0; i < int(children[iChild]->state.size()); ++i)
616 if (children[iChild]->state[i].scale() == children[iChild]->scale)
617 children[iChild]->state[i].scale(scaleNew);
618 // Enforce ordering in saved clustering scale
619 children[iChild]->scale = scaleNew;
620
621 } else if ( mergingHooksPtr->unorderedScalePrescip() == 1) {
622 // Use smaller scale as common splitting scale for mother & child
623 double scaleNew = max(mergingHooksPtr->pTcut(),
624 min(scale,children[iChild]->scale));
625 // Enforce ordering in particle production scales
626 for( int i = 0; i < int(state.size()); ++i)
627 if (state[i].scale() == scale)
628 state[i].scale(scaleNew);
629 // Enforce ordering in saved clustering scale
630 scale = scaleNew;
631 }
632 // Just set the overall event scale to the minimal scale
633 } else {
634 double scalemin = state[0].e();
635 for( int i = 0; i < int(state.size()); ++i)
636 if (state[i].colType() != 0)
637 scalemin = max(mergingHooksPtr->pTcut(),
638 min(scalemin,state[i].scale()));
639 state.scale(scalemin);
640 scale = max(mergingHooksPtr->pTcut(), scale);
641 }
642 //Recurse
643 children[iChild]->setScales(index, false);
644 }
645 }
646
647}
648
649//--------------------------------------------------------------------------
650
651// Function to find a particle in all higher multiplicity events
652// along the history path and set its production scale to the input
653// scale
654// IN int iPart : Parton in refEvent to be checked / rescaled
655// Event& refEvent : Reference event for iPart
656// double scale : Scale to be set as production scale for
657// unchanged copies of iPart in subsequent steps
658
659void History::scaleCopies(int iPart, const Event& refEvent, double rho) {
660
661 // Check if any parton recently rescaled is found unchanged:
662 // Same charge, colours in mother->state
663 if ( mother ) {
664 for( int i=0; i < mother->state.size(); ++i) {
665 if ( ( mother->state[i].id() == refEvent[iPart].id()
666 && mother->state[i].colType() == refEvent[iPart].colType()
667 && mother->state[i].chargeType() == refEvent[iPart].chargeType()
668 && mother->state[i].col() == refEvent[iPart].col()
669 && mother->state[i].acol() == refEvent[iPart].acol() )
670 ) {
671 // Rescale the unchanged parton
672 mother->state[i].scale(rho);
673 // Recurse
674 if (mother->mother)
675 mother->scaleCopies( iPart, refEvent, rho );
676 } // end if found unchanged parton case
677 } // end loop over particle entries in event
678 }
679}
680
681//--------------------------------------------------------------------------
682
683// Functions to set the OVERALL EVENT SCALES [=state.scale()] to
684// the scale of the last clustering
685// NO INPUT
686// NO OUTPUT
687
688void History::setEventScales() {
689 // Set the event scale to the scale of the last clustering,
690 // except for the very lowest multiplicity state
691 if (mother) {
692 mother->state.scale(scale);
693 // Recurse
694 mother->setEventScales();
695 }
696}
697
698//--------------------------------------------------------------------------
699
700// Functions to return the z value of the last ISR splitting
701// NO INPUT
702// OUTPUT double : z value of last ISR splitting in history
703
704double History::zISR() {
705
706 // Do nothing for ME level state
707 if (!mother) return 0.0;
708 // Skip FSR splitting
709 if (mother->state[clusterIn.emittor].isFinal()) return mother->zISR();
710 // Calculate z
711 int rad = clusterIn.emittor;
712 int rec = clusterIn.recoiler;
713 int emt = clusterIn.emitted;
714 double z = (mother->state[rad].p() + mother->state[rec].p()
715 - mother->state[emt].p()).m2Calc()
716 / (mother->state[rad].p() + mother->state[rec].p()).m2Calc();
717 // Recurse
718 double znew = mother->zISR();
719 // Update z
720 if (znew > 0.) z = znew;
721
722 return z;
723}
724
725//--------------------------------------------------------------------------
726
727// Functions to return the z value of the last FSR splitting
728// NO INPUT
729// OUTPUT double : z value of last FSR splitting in history
730
731double History::zFSR() {
732
733 // Do nothing for ME level state
734 if (!mother) return 0.0;
735 // Skip ISR splitting
736 if (!mother->state[clusterIn.emittor].isFinal()) return mother->zFSR();
737 // Calculate z
738 int rad = clusterIn.emittor;
739 int rec = clusterIn.recoiler;
740 int emt = clusterIn.emitted;
741 // Construct 2->3 variables for FSR
742 Vec4 sum = mother->state[rad].p() + mother->state[rec].p()
743 + mother->state[emt].p();
744 double m2Dip = sum.m2Calc();
745 double x1 = 2. * (sum * mother->state[rad].p()) / m2Dip;
746 double x3 = 2. * (sum * mother->state[emt].p()) / m2Dip;
747 // Calculate z of splitting for FSR
748 double z = x1/(x1+x3);
749 // Recurse
750 double znew = mother->zFSR();
751 // Update z
752 if (znew > 0.) z = znew;
753
754 return z;
755}
756
757//--------------------------------------------------------------------------
758
759// Functions to return the pT scale of the last FSR splitting
760// NO INPUT
761// OUTPUT double : pT scale of last FSR splitting in history
762
763double History::pTISR() {
764 // Do nothing for ME level state
765 if (!mother) return 0.0;
766 // Skip FSR splitting
767 if (mother->state[clusterIn.emittor].isFinal()) return mother->pTISR();
768 double pT = mother->state.scale();
769 // Recurse
770 double pTnew = mother->pTISR();
771 // Update pT
772 if (pTnew > 0.) pT = pTnew;
773
774 return pT;
775}
776
777//--------------------------------------------------------------------------
778
779// Functions to return the pT scale of the last FSR splitting
780// NO INPUT
781// OUTPUT double : pT scale of last FSR splitting in history
782
783double History::pTFSR() {
784 // Do nothing for ME level state
785 if (!mother) return 0.0;
786 // Skip ISR splitting
787 if (!mother->state[clusterIn.emittor].isFinal()) return mother->pTFSR();
788 double pT = mother->state.scale();
789 // Recurse
790 double pTnew = mother->pTFSR();
791 // Update pT
792 if (pTnew > 0.) pT = pTnew;
793 return pT;
794}
795
796//--------------------------------------------------------------------------
797
798// Functions to return the depth of the history (i.e. the number of
799// reclustered splittings)
800// NO INPUT
801// OUTPUT int : Depth of history
802
803int History::nClusterings() {
804
805 if (!mother) return 0;
806 int w = mother->nClusterings();
807 w += 1;
808 return w;
809}
810
811//--------------------------------------------------------------------------
812
813// Functions to return the event after nSteps splittings of the 2->2 process
814// Example: nSteps = 1 -> return event with one additional parton
815// INPUT int : Number of splittings in the event,
816// as counted from core 2->2 process
817// OUTPUT Event : event with nSteps additional partons
818
819Event History::clusteredState(int nSteps) {
820
821 // Save state
822 Event outState = state;
823 // As long as there are steps to do, recursively save state
824 if (mother && nSteps > 0)
825 outState = mother->clusteredState(nSteps - 1);
826 // Done
827 return outState;
828
829}
830
831//--------------------------------------------------------------------------
832
833// Function to choose a path from all paths in the tree
834// according to their splitting probabilities
835// IN double : Random number
836// OUT History* : Leaf of history path chosen
837
838History * History::select(double rnd) {
839
840 // No need to choose if no paths have been constructed.
841 if ( goodBranches.empty() && badBranches.empty() ) return this;
842
843 // Choose amongst paths allowed by projections.
844 double sum = 0.;
845 map<double, History*> selectFrom;
846 if ( !goodBranches.empty() ) {
847 selectFrom = goodBranches;
848 sum = sumGoodBranches;
849 } else {
850 selectFrom = badBranches;
851 sum = sumBadBranches;
852 }
853
854 if (mergingHooksPtr->pickBySumPT()) {
855 // Find index of history with minimal sum of scalar pT
856 int nFinal = 0;
857 for (int i=0; i < state.size(); ++i)
858 if (state[i].isFinal())
859 nFinal++;
860 double iMin = 0.;
861 double sumMin = (nFinal-2)*state[0].e();
862 for ( map<double, History*>::iterator it = selectFrom.begin();
863 it != selectFrom.end(); ++it ) {
864
865 if (it->second->sumScalarPT < sumMin) {
866 sumMin = it->second->sumScalarPT;
867 iMin = it->first;
868 }
869 }
870 // Choose history with smallest sum of scalar pT
871 return selectFrom.lower_bound(iMin)->second;
872 } else {
873 // Choose history according to probability, be careful about upper bound
874 if ( rnd != 1. ) {
875 return selectFrom.upper_bound(sum*rnd)->second;
876 } else {
877 return selectFrom.lower_bound(sum*rnd)->second;
878 }
879 }
880 // Done
881}
882
883//--------------------------------------------------------------------------
884
885// Function to project paths onto desired paths.
886
887bool History::trimHistories() {
888 // Do nothing if no paths have been constructed.
889 if ( paths.empty() ) return false;
890 // Loop through all constructed paths. Check all removal conditions.
891 for ( map<double, History*>::iterator it = paths.begin();
892 it != paths.end(); ++it ) {
893 // Check if history is allowed.
894 if ( it->second->keep() && !it->second->keepHistory() )
895 it->second->remove();
896 }
897 // Project onto desired / undesired branches.
898 double sumold, sumnew, sumprob, mismatch;
899 sumold = sumnew = sumprob = mismatch = 0.;
900 // Loop through all constructed paths and store allowed paths.
901 // Skip undesired paths.
902 for ( map<double, History*>::iterator it = paths.begin();
903 it != paths.end(); ++it ) {
904 // Update index
905 sumnew = it->first;
906 if ( it->second->keep() ) {
907 // Fill branches with allowed paths.
908 goodBranches.insert( make_pair( sumnew - mismatch, it->second) );
909 // Add probability of this path.
910 sumGoodBranches = sumnew - mismatch;
911 } else {
912 // Update mismatch in probabilities resulting from not including this
913 // path
914 double mismatchOld = mismatch;
915 mismatch += sumnew - sumold;
916 // Fill branches with allowed paths.
917 badBranches.insert( make_pair( mismatchOld + sumnew - sumold,
918 it->second ) );
919 // Add probability of this path.
920 sumBadBranches = mismatchOld + sumnew - sumold;
921 }
922 // remember index of this path in order to caclulate probability of
923 // subsequent path.
924 sumold = it->first;
925 }
926 // Done
927 return !goodBranches.empty();
928}
929
930//--------------------------------------------------------------------------
931
932// Function implementing checks on a paths, for deciding if the path should
933// be considered valid or not.
934
935bool History::keepHistory() {
936 bool keepPath = true;
937 //// Tag unordered paths for removal.
938 //double maxScale = (foundCompletePath)
939 // ? infoPtr->eCM()
940 // : infoPtr->QFac();
941 //keepPath = isOrderedPath( maxScale );
942 //Done
943 return keepPath;
944}
945
946//--------------------------------------------------------------------------
947
948// Function to check if a path is ordered in evolution pT.
949
950bool History::isOrderedPath( double maxscale ) {
951 double newscale = clusterIn.pT();
952 if ( !mother ) return true;
953 bool ordered = mother->isOrderedPath(newscale);
954 if ( !ordered || maxscale < newscale) return false;
955 return ordered;
956}
957
958//--------------------------------------------------------------------------
959
960// Function to check if all reconstucted states in a path pass the merging
961// scale cut.
962
963bool History::allIntermediateAboveRhoMS( double rhoms ) {
964
965 int nFinal = 0;
966 for ( int i = 0; i < state.size(); ++i )
967 if ( state[i].isFinal() && state[i].colType() != 0 )
968 nFinal++;
969
970 double rhoNew = mergingHooksPtr->rhoms( state, false );
971
972 if ( !mother ) return true;
973
974 bool passRHOMS = mother->allIntermediateAboveRhoMS( rhoms );
975
976 if ( !passRHOMS || ( nFinal > 0 && rhoNew < rhoms ) ) return false;
977
978 // Done
979 return passRHOMS;
980}
981
982//--------------------------------------------------------------------------
983
984// Function to check if reconstucted states in a path are ordered in the
985// merging scale variable.
986
987bool History::intermediateRhoMSOrdered( double maxscale ) {
988 // Count number of final state partons.
989 int nFinal = 0;
990 for ( int i = 0; i < state.size(); ++i )
991 if ( state[i].isFinal() && state[i].colType() != 0 )
992 nFinal++;
993 // Get new min(rho) scale.
994 double newscale = (nFinal == 0 )
995 ? maxscale
996 : mergingHooksPtr->rhoms( state, false );
997 // For no final state particles or available mother, check mother.
998 bool isOrdered = ( nFinal == 0 || mother )
999 ? mother->intermediateRhoMSOrdered( newscale )
1000 : true;
1001 // Done.
1002 return isOrdered && ( maxscale >= newscale );
1003}
1004
1005//--------------------------------------------------------------------------
1006
1007// Function to check if any ordered paths were found (and kept).
1008
1009bool History::foundAnyOrderedPaths() {
1010 //Do nothing if no paths were found
1011 if ( paths.empty() ) return false;
1012 double maxscale = infoPtr->eCM();
1013 // Loop through paths. Divide probability into ordered and unordered pieces.
1014 for ( map<double, History*>::iterator it = paths.begin();
1015 it != paths.end(); ++it )
1016 if ( it->second->isOrderedPath(maxscale) )
1017 return true;
1018 // Done
1019 return false;
1020}
1021
1022//--------------------------------------------------------------------------
1023
1024// Function to check if any unordered paths were found (and kept).
1025
1026bool History::foundAnyUnorderedPaths() {
1027 // Do nothing if no paths were found
1028 if ( paths.empty() ) return false;
1029 double maxscale = infoPtr->eCM();
1030 // Loop through paths. Return false if an ordered path was found.
1031 for ( map<double, History*>::iterator it = paths.begin();
1032 it != paths.end(); ++it )
1033 if ( !it->second->isOrderedPath(maxscale) )
1034 return true;
1035 // Done
1036 return false;
1037}
1038
1039//--------------------------------------------------------------------------
1040
1041// For a full path, find the weight calculated from the ratio of
1042// couplings, the no-emission probabilities, and possible PDF
1043// ratios. This function should only be called for the last history
1044// node of a full path.
1045// IN TimeShower : Already initialised shower object to be used as
1046// trial shower
1047// double : alpha_s value used in ME calculation
1048// double : Maximal mass scale of the problem (e.g. E_CM)
1049// AlphaStrong: Initialised shower alpha_s object for FSR
1050// alpha_s ratio calculation
1051// AlphaStrong: Initialised shower alpha_s object for ISR
1052// alpha_s ratio calculation (can be different from previous)
1053
1054double History::weightTree(PartonLevel* trial, double as0, double maxscale,
1055 double pdfScale, AlphaStrong * asFSR, AlphaStrong * asISR,
1056 double& asWeight, double& pdfWeight) {
1057
1058 // Use correct scale
1059 double newScale = scale;
1060
1061 // For ME state, just multiply by PDF ratios
1062 if ( !mother ) {
1063
1064 int sideRad = (state[3].pz() > 0) ? 1 :-1;
1065 int sideRec = (state[4].pz() > 0) ? 1 :-1;
1066 // Calculate PDF first leg
1067 if (state[3].colType() != 0) {
1068 // Find x value and flavour
1069 double x = 2.*state[3].e() / state[0].e();
1070 int flav = state[3].id();
1071
1072 // Find numerator/denominator scale
1073 double scaleNum = (children.empty()) ? hardFacScale() : maxscale;
1074 double scaleDen = infoPtr->QFac();
1075 // For initial parton, multiply by PDF ratio
1076 double ratio = getPDFratio(sideRad, false, flav, x, scaleNum,
1077 flav, x, scaleDen);
1078 pdfWeight *= ratio;
1079 }
1080
1081 // Calculate PDF ratio for second leg
1082 if (state[4].colType() != 0) {
1083 // Find x value and flavour
1084 double x = 2.*state[4].e() / state[0].e();
1085 int flav = state[4].id();
1086 // Find numerator/denominator scale
1087 double scaleNum = (children.empty()) ? hardFacScale() : maxscale;
1088 double scaleDen = infoPtr->QFac();
1089 // For initial parton, multiply with PDF ratio
1090 double ratio = getPDFratio(sideRec, false, flav, x, scaleNum,
1091 flav, x, scaleDen);
1092 pdfWeight *= ratio;
1093 }
1094
1095 return 1.0;
1096 }
1097
1098 // Remember new PDF scale n case true sclae should be used for un-ordered
1099 // splittings.
1100 double newPDFscale = newScale;
1101 if (mergingHooksPtr->unorderedPDFscalePrescip() == 1)
1102 newPDFscale = clusterIn.pT();
1103
1104 // Recurse
1105 double w = mother->weightTree(trial, as0, newScale, newPDFscale,
1106 asFSR, asISR, asWeight, pdfWeight);
1107
1108 // Do nothing for empty state
1109 if (state.size() < 3) return 1.0;
1110 // If up to now, trial shower was not successful, return zero
1111 if ( w < 1e-12 ) return 0.0;
1112 // Do trial shower on current state, return zero if not successful
1113 w *= doTrialShower(trial, maxscale);
1114 if ( w < 1e-12 ) return 0.0;
1115
1116 // Calculate alpha_s ratio for current state
1117 if ( asFSR && asISR ) {
1118 double asScale = pow2( newScale );
1119 if (mergingHooksPtr->unorderedASscalePrescip() == 1)
1120 asScale = pow2( clusterIn.pT() );
1121 bool FSR = mother->state[clusterIn.emittor].isFinal();
1122 double alphaSinPS = (FSR) ? (*asFSR).alphaS(asScale)
1123 : (*asISR).alphaS(asScale
1124 + pow2(mergingHooksPtr->pT0ISR()) );
1125 asWeight *= alphaSinPS / as0;
1126 }
1127
1128 // Calculate pdf ratios: Get both sides of event
1129 int inP = 3;
1130 int inM = 4;
1131 int sideP = (mother->state[inP].pz() > 0) ? 1 :-1;
1132 int sideM = (mother->state[inM].pz() > 0) ? 1 :-1;
1133
1134 if ( mother->state[inP].colType() != 0 ) {
1135 // Find x value and flavour
1136 double x = getCurrentX(sideP);
1137 int flav = getCurrentFlav(sideP);
1138 // Find numerator scale
1139 double scaleNum = (children.empty())
1140 ? hardFacScale()
1141 : ( (mergingHooksPtr->unorderedPDFscalePrescip() == 1)
1142 ? pdfScale : maxscale );
1143 double scaleDen = (mergingHooksPtr->unorderedPDFscalePrescip() == 1)
1144 ? clusterIn.pT() : newScale;
1145 // Multiply PDF ratio
1146 double ratio = getPDFratio(sideP, false, flav, x, scaleNum,
1147 flav, x, scaleDen);
1148 pdfWeight *= ratio;
1149 }
1150
1151 if ( mother->state[inM].colType() != 0 ) {
1152 // Find x value and flavour
1153 double x = getCurrentX(sideM);
1154 int flav = getCurrentFlav(sideM);
1155 // Find numerator scale
1156 double scaleNum = (children.empty())
1157 ? hardFacScale()
1158 : ( (mergingHooksPtr->unorderedPDFscalePrescip() == 1)
1159 ? pdfScale : maxscale );
1160 double scaleDen = (mergingHooksPtr->unorderedPDFscalePrescip() == 1)
1161 ? clusterIn.pT() : newScale;
1162 // Multiply PDF ratio
1163 double ratio = getPDFratio(sideM, false, flav, x, scaleNum,
1164 flav, x, scaleDen);
1165 pdfWeight *= ratio;
1166 }
1167
1168 // Done
1169 return w;
1170}
1171
1172//--------------------------------------------------------------------------
1173
1174// Function to return the factorisation scale of the hard process in Pythia.
1175
1176double History::hardFacScale() {
1177 // Declare output scale.
1178 double hardscale = 0.;
1179 // If scale should not be reset, done.
1180 if ( !mergingHooksPtr->resetHardQFac() ) return infoPtr->QFac();
1181 // For pure QCD dijet events, calculate the hadronic cross section
1182 // of the hard process at the pT of the dijet system, rather than at fixed
1183 // arbitrary scale.
1184 if ( mergingHooksPtr->getProcessString().compare("pp>jj") == 0
1185 || mergingHooksPtr->getProcessString().compare("pp>aj") == 0 ) {
1186 // Find the mT in the hard sub-process.
1187 vector <double> mT;
1188 for ( int i=0; i < state.size(); ++i)
1189 if ( state[i].isFinal() && state[i].colType() != 0 )
1190 mT.push_back( abs(state[i].mT2()) );
1191 if ( int(mT.size()) != 2 )
1192 hardscale = infoPtr->QFac();
1193 else
1194 hardscale = sqrt( min( mT[0], mT[1] ) );
1195 } else {
1196 hardscale = infoPtr->QFac();
1197 }
1198 // Done
1199 return hardscale;
1200}
1201
1202//--------------------------------------------------------------------------
1203
1204// Function to return the factorisation scale of the hard process in Pythia.
1205
1206double History::hardRenScale() {
1207 // Declare output scale.
1208 double hardscale = 0.;
1209 // For pure QCD dijet events, calculate the hadronic cross section
1210 // of the hard process at the pT of the dijet system, rather than at fixed
1211 // arbitrary scale.
1212 if ( mergingHooksPtr->getProcessString().compare("pp>jj") == 0
1213 || mergingHooksPtr->getProcessString().compare("pp>aj") == 0 ) {
1214 // Find the mT in the hard sub-process.
1215 vector <double> mT;
1216 for ( int i=0; i < state.size(); ++i)
1217 if ( state[i].isFinal()
1218 && ( state[i].colType() != 0 || state[i].id() == 22 ) )
1219 mT.push_back( abs(state[i].mT()) );
1220 if ( int(mT.size()) != 2 )
1221 hardscale = infoPtr->QRen();
1222 else
1223 hardscale = sqrt( mT[0]*mT[1] );
1224 } else {
1225 hardscale = infoPtr->QRen();
1226 }
1227 // Done
1228 return hardscale;
1229}
1230
1231//--------------------------------------------------------------------------
1232
1233// Perform a trial shower using the \a pythia object between
1234// maxscale down to this scale and return the corresponding Sudakov
1235// form factor.
1236// IN trialShower : Shower object used as trial shower
1237// double : Maximum scale for trial shower branching
1238// OUT 0.0 : trial shower emission outside allowed pT range
1239// 1.0 : trial shower successful (any emission was below
1240// the minimal scale )
1241
1242double History::doTrialShower( PartonLevel* trial, double maxscale,
1243 double minscale ) {
1244
1245 // Copy state to local process
1246 Event process = state;
1247 // Set starting scale.
1248 double startingScale = maxscale;
1249 // Set output.
1250 bool doVeto = false;
1251
1252 while ( true ) {
1253
1254 // Reset trialShower object
1255 trial->resetTrial();
1256 // Construct event to be showered
1257 Event event = Event();
1258 event.init("(hard process-modified)", particleDataPtr);
1259 event.clear();
1260 // Reset process scale so thatshower starting scale is correctly set.
1261 process.scale(startingScale);
1262
1263 doVeto = false;
1264
1265 // Get pT before reclustering
1266 double minScale = (minscale > 0.) ? minscale : scale;
1267 // If the maximal scale and the minimal scale coincide (as would
1268 // be the case for the corrected scales of unordered histories),
1269 // do not generate Sudakov
1270 if (minScale >= startingScale) break;
1271
1272 // Find z and pT values at which the current state was formed, to
1273 // ensure that the showers can order the next emission correctly in
1274 // rapidity, if required.
1275 // NOT CORRECTLY SET FOR HIGHEST MULTIPLICITY STATE!
1276 double z = ( mergingHooksPtr->getNumberOfClusteringSteps(state) == 0
1277 || !mother )
1278 ? 0.5
1279 : mother->getCurrentZ(clusterIn.emittor,clusterIn.recoiler,
1280 clusterIn.emitted);
1281 // Store z and pT values at which the current state was formed
1282 infoPtr->zNowISR(z);
1283 infoPtr->pT2NowISR(pow(startingScale,2));
1284 infoPtr->hasHistory(true);
1285
1286 // Perform trial shower emission
1287 trial->next(process,event);
1288 // Get trial shower pT.
1289 double pTtrial = trial->pTLastInShower();
1290 double typeTrial = trial->typeLastInShower();
1291
1292 // Get veto (merging) scale value
1293 double vetoScale = (mother) ? 0. : mergingHooksPtr->tms();
1294 // Get merging scale in current event
1295 double tnow = 0.;
1296 // Use KT/Durham merging scale definition.
1297 if (mergingHooksPtr->doKTMerging() || mergingHooksPtr->doMGMerging())
1298 tnow = mergingHooksPtr->kTms(event);
1299 // Use Lund PT merging scale definition.
1300 else if (mergingHooksPtr->doPTLundMerging())
1301 tnow = mergingHooksPtr->rhoms(event, false);
1302 // Use DeltaR_{ij}, pT_i, Q_{ij} combination merging scale definition.
1303 else if (mergingHooksPtr->doCutBasedMerging())
1304 tnow = mergingHooksPtr->cutbasedms(event);
1305 // Use user-defined merging scale.
1306 else
1307 tnow = mergingHooksPtr->tmsDefinition(event);
1308
1309 // Done if evolution scale has fallen below minimum
1310 if ( pTtrial < minScale ) break;
1311 // Reset starting scale.
1312 startingScale = pTtrial;
1313
1314 // Continue if this state is below the veto scale
1315 if ( tnow < vetoScale && vetoScale > 0. ) continue;
1316
1317 // Retry if the trial emission was not allowed.
1318 if ( mergingHooksPtr->canVetoTrialEmission()
1319 && mergingHooksPtr->doVetoTrialEmission( process, event) ) continue;
1320
1321 // Veto event if trial pT was above the next nodal scale.
1322 if ( pTtrial > minScale ) doVeto = true;
1323
1324 //// For last no-emission probability, veto event if the trial state
1325 //// is above the merging scale, i.e. in the matrix element region.
1326 //if ( !mother && tnow > vetoScale && vetoScale > 0. ) doVeto = true;
1327
1328 // For 2 -> 2 pure QCD state, do not allow multiparton interactions
1329 // above the kinematical pT of the 2 -> 2 state
1330 if (typeTrial == 1) {
1331 // Count number of final state particles and remember partons
1332 int nFinal = 0;
1333 vector<int> finalPartons;
1334 for(int i=0; i < state.size(); ++i) {
1335 if (state[i].isFinal()) {
1336 nFinal++;
1337 if ( state[i].colType() != 0)
1338 finalPartons.push_back(i);
1339 }
1340 }
1341 // Veto if MPI was above 2 -> 2 pT
1342 if ( nFinal == 2 && int(finalPartons.size()) == 2
1343 && pTtrial > event[finalPartons[0]].pT() ) {
1344 return 0.0;
1345 }
1346 }
1347
1348 // If pT of trial emission was in suitable range (trial shower
1349 // successful), return false
1350 if ( pTtrial < minScale ) doVeto = false;
1351
1352 // Done
1353 break;
1354
1355 }
1356
1357 // Done
1358 return ( (doVeto) ? 0. : 1. );
1359}
1360
1361/*--------------- METHODS USED FOR CONTRUCTION OF ALL HISTORIES --------- */
1362
1363// Check if a ordered (and complete) path has been found in the
1364// initial node, in which case we will no longer be interested in
1365// any unordered paths.
1366
1367bool History::onlyOrderedPaths() {
1368 if ( !mother || foundOrderedPath ) return foundOrderedPath;
1369 return foundOrderedPath = mother->onlyOrderedPaths();
1370}
1371
1372bool History::onlyUnorderedPaths() {
1373 if ( !mother || foundUnorderedPath ) return foundUnorderedPath;
1374 return foundUnorderedPath = mother->onlyUnorderedPaths();
1375}
1376
1377//--------------------------------------------------------------------------
1378
1379// Check if a STRONGLY ordered (and complete) path has been found in the
1380// initial node, in which case we will no longer be interested in
1381// any unordered paths.
1382
1383bool History::onlyStronglyOrderedPaths() {
1384 if ( !mother || foundStronglyOrderedPath ) return foundStronglyOrderedPath;
1385 return foundStronglyOrderedPath = mother->onlyStronglyOrderedPaths();
1386}
1387
1388//--------------------------------------------------------------------------
1389
1390// Check if an allowed (according to user-criterion) path has been found in
1391// the initial node, in which case we will no longer be interested in
1392// any forbidden paths.
1393
1394bool History::onlyAllowedPaths() {
1395 if ( !mother || foundAllowedPath ) return foundAllowedPath;
1396 return foundAllowedPath = mother->onlyAllowedPaths();
1397}
1398
1399//--------------------------------------------------------------------------
1400
1401// When a full path has been found, register it with the initial
1402// history node.
1403// IN History : History to be registered as path
1404// bool : Specifying if clusterings so far were ordered
1405// bool : Specifying if path is complete down to 2->2 process
1406// OUT true if History object forms a plausible path (eg prob>0 ...)
1407
1408bool History::registerPath(History & l, bool isOrdered, bool isUnordered,
1409 bool isStronglyOrdered, bool isAllowed, bool isComplete) {
1410
1411 // We are not interested in improbable paths.
1412 if ( l.prob <= 0.0)
1413 return false;
1414 // We only register paths in the initial node.
1415 if ( mother ) return mother->registerPath(l, isOrdered, isUnordered,
1416 isStronglyOrdered, isAllowed, isComplete);
1417 // Again, we are not interested in improbable paths.
1418 if ( sumpath == sumpath + l.prob )
1419 return false;
1420 if ( mergingHooksPtr->canCutOnRecState()
1421 && foundAllowedPath && !isAllowed )
1422 return false;
1423 if ( mergingHooksPtr->enforceStrongOrdering()
1424 && foundStronglyOrderedPath && !isStronglyOrdered )
1425 return false;
1426 if ( mergingHooksPtr->orderHistories()
1427 && foundOrderedPath && !isOrdered )
1428 return false;
1429
1430 if ( mergingHooksPtr->forceUnorderedHistories()
1431 && foundUnorderedPath && !isUnordered )
1432 return false;
1433
1434 if ( foundCompletePath && !isComplete )
1435 return false;
1436 if ( !mergingHooksPtr->canCutOnRecState()
1437 && !mergingHooksPtr->allowCutOnRecState() )
1438 foundAllowedPath = true;
1439
1440 if ( mergingHooksPtr->canCutOnRecState() && isAllowed && isComplete) {
1441 if ( !foundAllowedPath || !foundCompletePath ) {
1442 // If this is the first complete, allowed path, discard the
1443 // old, disallowed or incomplete ones.
1444 paths.clear();
1445 sumpath = 0.0;
1446 }
1447 foundAllowedPath = true;
1448
1449 }
1450
1451 if ( mergingHooksPtr->enforceStrongOrdering() && isStronglyOrdered
1452 && isComplete ) {
1453 if ( !foundStronglyOrderedPath || !foundCompletePath ) {
1454 // If this is the first complete, ordered path, discard the
1455 // old, non-ordered or incomplete ones.
1456 paths.clear();
1457 sumpath = 0.0;
1458 }
1459 foundStronglyOrderedPath = true;
1460 foundCompletePath = true;
1461
1462 }
1463
1464 if ( mergingHooksPtr->orderHistories() && isOrdered && isComplete ) {
1465 if ( !foundOrderedPath || !foundCompletePath ) {
1466 // If this is the first complete, ordered path, discard the
1467 // old, non-ordered or incomplete ones.
1468 paths.clear();
1469 sumpath = 0.0;
1470 }
1471 foundOrderedPath = true;
1472 foundCompletePath = true;
1473
1474 }
1475
1476 if ( mergingHooksPtr->forceUnorderedHistories() && isUnordered
1477 && isComplete ) {
1478 if ( !foundUnorderedPath || !foundCompletePath ) {
1479 // If this is the first complete, unordered path, discard the
1480 // old, ordered or incomplete ones.
1481 paths.clear();
1482 sumpath = 0.0;
1483 }
1484 foundUnorderedPath = true;
1485 foundCompletePath = true;
1486 }
1487
1488 if ( isComplete ) {
1489 if ( !foundCompletePath ) {
1490 // If this is the first complete path, discard the old,
1491 // incomplete ones.
1492 paths.clear();
1493 sumpath = 0.0;
1494 }
1495 foundCompletePath = true;
1496 }
1497
1498 // Remember, if this path is ordered, even if no ordering is required
1499 if ( isOrdered ) {
1500 foundOrderedPath = true;
1501 }
1502
1503 // Index path by probability
1504 sumpath += l.prob;
1505 paths[sumpath] = &l;
1506
1507 return true;
1508}
1509
1510//--------------------------------------------------------------------------
1511
1512// For the history-defining state (and if necessary interfering
1513// states), find all possible clusterings.
1514// NO INPUT
1515// OUT vector of all (rad,rec,emt) systems
1516
1517vector<Clustering> History::getAllQCDClusterings() {
1518 vector<Clustering> ret;
1519 // Initialise vectors to keep track of position of partons in the
1520 // history-defining state
1521 vector <int> PosFinalPartn;
1522 vector <int> PosInitPartn;
1523 vector <int> PosFinalGluon;
1524 vector <int> PosFinalQuark;
1525 vector <int> PosFinalAntiq;
1526 vector <int> PosInitGluon;
1527 vector <int> PosInitQuark;
1528 vector <int> PosInitAntiq;
1529
1530 // Search event record for final state particles and store these in
1531 // quark, anti-quark and gluon vectors
1532 for ( int i=0; i < state.size(); ++i )
1533 if ( state[i].isFinal() && state[i].colType() !=0 ) {
1534 // Store final partons
1535 if ( state[i].id() == 21 ) PosFinalGluon.push_back(i);
1536 else if ( state[i].idAbs() < 10 && state[i].id() > 0)
1537 PosFinalQuark.push_back(i);
1538 else if ( state[i].idAbs() < 10 && state[i].id() < 0)
1539 PosFinalAntiq.push_back(i);
1540 } else if (state[i].status() == -21 && state[i].colType() != 0 ) {
1541 // Store initial partons
1542 if ( state[i].id() == 21 ) PosInitGluon.push_back(i);
1543 else if ( state[i].idAbs() < 10 && state[i].id() > 0)
1544 PosInitQuark.push_back(i);
1545 else if ( state[i].idAbs() < 10 && state[i].id() < 0)
1546 PosInitAntiq.push_back(i);
1547 }
1548
1549 // Get all clusterings for input state
1550 vector<Clustering> systems;
1551 systems = getQCDClusterings(state);
1552 ret.insert(ret.end(), systems.begin(), systems.end());
1553 systems.resize(0);
1554
1555 // If valid clusterings were found, return
1556 if ( !ret.empty() ) return ret;
1557 // If no clusterings have been found until now, try to find
1558 // clusterings of diagrams that interfere with the current one
1559 // (i.e. change the colours of the current event slightly and run
1560 // search again)
1561 else if ( ret.empty()
1562 && mergingHooksPtr->allowColourShuffling() ) {
1563 Event NewState = Event(state);
1564 // Start with changing final state quark colour
1565 for(int i = 0; i < int(PosFinalQuark.size()); ++i) {
1566 // Never change the hard process candidates
1567 if ( mergingHooksPtr->hardProcess.matchesAnyOutgoing(PosFinalQuark[i],
1568 NewState) )
1569 continue;
1570 int col = NewState[PosFinalQuark[i]].col();
1571 for(int j = 0; j < int(PosInitAntiq.size()); ++j) {
1572 // Now swap colours
1573 int acl = NewState[PosInitAntiq[j]].acol();
1574 if ( col == acl ) continue;
1575 NewState[PosFinalQuark[i]].col(acl);
1576 NewState[PosInitAntiq[j]].acol(col);
1577 systems = getQCDClusterings(NewState);
1578 if (!systems.empty()) {
1579 state = NewState;
1580 NewState.clear();
1581 ret.insert(ret.end(), systems.begin(), systems.end());
1582 systems.resize(0);
1583 return ret;
1584 }
1585 }
1586 }
1587 // Now change final state antiquark anticolour
1588 for(int i = 0; i < int(PosFinalAntiq.size()); ++i) {
1589 // Never change the hard process candidates
1590 if ( mergingHooksPtr->hardProcess.matchesAnyOutgoing(PosFinalAntiq[i],
1591 NewState) )
1592 continue;
1593 int acl = NewState[PosFinalAntiq[i]].acol();
1594 for(int j = 0; j < int(PosInitQuark.size()); ++j) {
1595 // Now swap colours
1596 int col = NewState[PosInitQuark[j]].col();
1597 if ( col == acl ) continue;
1598 NewState[PosFinalAntiq[i]].acol(col);
1599 NewState[PosInitQuark[j]].col(acl);
1600 systems = getQCDClusterings(NewState);
1601 if (!systems.empty()) {
1602 state = NewState;
1603 NewState.clear();
1604 ret.insert(ret.end(), systems.begin(), systems.end());
1605 systems.resize(0);
1606 return ret;
1607 }
1608 }
1609 }
1610
1611 if ( !ret.empty() ) {
1612 string message="Warning in History::getAllQCDClusterings: Changed";
1613 message+=" colour structure to allow at least one clustering";
1614 infoPtr->errorMsg(message);
1615 }
1616
1617 // If no colour rearrangements should be done, print warning and return
1618 } else {
1619 string message="Warning in History::getAllQCDClusterings: No clusterings";
1620 message+=" found. History incomplete";
1621 infoPtr->errorMsg(message);
1622 }
1623 // Done
1624 return ret;
1625}
1626
1627//--------------------------------------------------------------------------
1628
1629// For one given state, find all possible clusterings.
1630// IN Event : state to be investigated
1631// OUT vector of all (rad,rec,emt) systems in the state
1632
1633vector<Clustering> History::getQCDClusterings( const Event& event) {
1634 vector<Clustering> ret;
1635
1636 // Initialise vectors to keep track of position of partons in the
1637 // input event
1638 vector <int> PosFinalPartn;
1639 vector <int> PosInitPartn;
1640
1641 vector <int> PosFinalGluon;
1642 vector <int> PosFinalQuark;
1643 vector <int> PosFinalAntiq;
1644 vector <int> PosInitGluon;
1645 vector <int> PosInitQuark;
1646 vector <int> PosInitAntiq;
1647
1648 // Search event record for final state particles and store these in
1649 // quark, anti-quark and gluon vectors
1650 for (int i=0; i < event.size(); ++i)
1651 if ( event[i].isFinal() && event[i].colType() !=0 ) {
1652 // Store final partons
1653 PosFinalPartn.push_back(i);
1654 if ( event[i].id() == 21 ) PosFinalGluon.push_back(i);
1655 else if ( event[i].idAbs() < 10 && event[i].id() > 0)
1656 PosFinalQuark.push_back(i);
1657 else if ( event[i].idAbs() < 10 && event[i].id() < 0)
1658 PosFinalAntiq.push_back(i);
1659 } else if ( event[i].status() == -21 && event[i].colType() != 0 ) {
1660 // Store initial partons
1661 PosInitPartn.push_back(i);
1662 if ( event[i].id() == 21 ) PosInitGluon.push_back(i);
1663 else if ( event[i].idAbs() < 10 && event[i].id() > 0)
1664 PosInitQuark.push_back(i);
1665 else if ( event[i].idAbs() < 10 && event[i].id() < 0)
1666 PosInitAntiq.push_back(i);
1667 }
1668
1669 int nFiGluon = int(PosFinalGluon.size());
1670 int nFiQuark = int(PosFinalQuark.size());
1671 int nFiAntiq = int(PosFinalAntiq.size());
1672 int nInGluon = int(PosInitGluon.size());
1673 int nInQuark = int(PosInitQuark.size());
1674 int nInAntiq = int(PosInitAntiq.size());
1675
1676 vector<Clustering> systems;
1677
1678 // Find rad + emt + rec systems:
1679 // (1) Start from gluon and find all (rad,rec,emt=gluon) triples
1680 for (int i = 0; i < nFiGluon; ++i) {
1681 //if ( mergingHooksPtr->nRecluster() > 0
1682 // && PosFinalGluon[i] == iReclusteredOld )
1683 // continue;
1684 int EmtGluon = PosFinalGluon[i];
1685 systems = findQCDTriple( EmtGluon, 2, event, PosFinalPartn, PosInitPartn);
1686 ret.insert(ret.end(), systems.begin(), systems.end());
1687 systems.resize(0);
1688 }
1689
1690 // For more than one quark-antiquark pair in final state, check for
1691 // g -> qqbar splittings
1692 bool check_g2qq = true;
1693 if ( ( ( nInQuark + nInAntiq == 0 )
1694 && (nInGluon == 0)
1695 && (nFiQuark == 1) && (nFiAntiq == 1) )
1696 || ( ( nFiQuark + nFiAntiq == 0)
1697 && (nInQuark == 1) && (nInAntiq == 1) ) )
1698 check_g2qq = false;
1699
1700 if ( check_g2qq ) {
1701
1702 // (2) Start from quark and find all (rad,rec,emt=quark) triples
1703 // ( when g -> q qbar occured )
1704 for( int i=0; i < nFiQuark; ++i) {
1705 //if ( mergingHooksPtr->nRecluster() > 0
1706 // && PosFinalQuark[i] == iReclusteredOld )
1707 // continue;
1708 int EmtQuark = PosFinalQuark[i];
1709 systems = findQCDTriple( EmtQuark,1,event, PosFinalPartn, PosInitPartn);
1710 ret.insert(ret.end(), systems.begin(), systems.end());
1711 systems.resize(0);
1712 }
1713
1714 // (3) Start from anti-quark and find all (rad,rec,emt=anti-quark)
1715 // triples ( when g -> q qbar occured )
1716 for( int i=0; i < nFiAntiq; ++i) {
1717 //if ( mergingHooksPtr->nRecluster() > 0
1718 // && PosFinalAntiq[i] == iReclusteredOld )
1719 // continue;
1720 int EmtAntiq = PosFinalAntiq[i];
1721 systems = findQCDTriple( EmtAntiq,1,event, PosFinalPartn, PosInitPartn);
1722 ret.insert(ret.end(), systems.begin(), systems.end());
1723 systems.resize(0);
1724 }
1725 }
1726
1727 return ret;
1728}
1729
1730//--------------------------------------------------------------------------
1731
1732// Function to construct (rad,rec,emt) triples from the event
1733// IN int : Position of Emitted in event record for which
1734// dipoles should be constructed
1735// int : Colour topogy to be tested
1736// 1= g -> qqbar, causing 2 -> 2 dipole splitting
1737// 2= q(bar) -> q(bar) g && g -> gg,
1738// causing a 2 -> 3 dipole splitting
1739// Event : event record to be checked for ptential partners
1740// OUT vector of all allowed radiator+recoiler+emitted triples
1741
1742vector<Clustering> History::findQCDTriple (int EmtTagIn, int colTopIn,
1743 const Event& event,
1744 vector<int> PosFinalPartn,
1745 vector <int> PosInitPartn ) {
1746
1747 // Copy input parton tag
1748 int EmtTag = EmtTagIn;
1749 // Copy input colour topology tag
1750 // (1: g --> qqbar splitting present, 2:rest)
1751 int colTop = colTopIn;
1752
1753 // Initialise FinalSize
1754 int FinalSize = int(PosFinalPartn.size());
1755 int InitSize = int(PosInitPartn.size());
1756 int Size = InitSize + FinalSize;
1757
1758 vector<Clustering> clus;
1759
1760 // Search final partons to find partons colour-connected to
1761 // event[EmtTag], choose radiator, then choose recoiler
1762 for ( int a = 0; a < Size; ++a ) {
1763 int i = (a < FinalSize)? a : (a - FinalSize) ;
1764 int iRad = (a < FinalSize)? PosFinalPartn[i] : PosInitPartn[i];
1765
1766 if ( event[iRad].col() == event[EmtTag].col()
1767 && event[iRad].acol() == event[EmtTag].acol() )
1768 continue;
1769
1770 //if ( mergingHooksPtr->nRecluster() > 0
1771 // && iRad == iReclusteredOld ) continue;
1772
1773 if (iRad != EmtTag ) {
1774 int pTdef = event[iRad].isFinal() ? 1 : -1;
1775 int sign = (a < FinalSize)? 1 : -1 ;
1776
1777 // First colour topology: g --> qqbar. Here, emt & rad should
1778 // have same flavour (causes problems for gamma->qqbar).
1779 if (colTop == 1) {
1780
1781 if ( event[iRad].id() == -sign*event[EmtTag].id() ) {
1782 int col = -1;
1783 int acl = -1;
1784 if (event[iRad].id() < 0) {
1785 col = event[EmtTag].acol();
1786 acl = event[iRad].acol();
1787 } else {
1788 col = event[EmtTag].col();
1789 acl = event[iRad].col();
1790 }
1791 // Recoiler
1792 int iRec = 0;
1793 // Colour partner
1794 int iPartner = 0;
1795
1796 if (col > 0) {
1797 // Find recoiler by colour
1798 iRec = FindCol(col,iRad,EmtTag,event,1,true);
1799 // In initial state splitting has final state colour partner,
1800 // Save both partner and recoiler
1801 if ( (sign < 0) && (event[iRec].isFinal()) ) {
1802 // Save colour recoiler
1803 iPartner = iRec;
1804 // Reset kinematic recoiler to initial state parton
1805 for(int l = 0; l < int(PosInitPartn.size()); ++l)
1806 if (PosInitPartn[l] != iRad) iRec = PosInitPartn[l];
1807 // For final state splittings, colour partner and recoiler are
1808 // identical
1809 } else {
1810 iPartner = iRec;
1811 }
1812 if ( iRec != 0 && iPartner != 0
1813 && allowedClustering( iRad, EmtTag, iRec, iPartner, event) ) {
1814 clus.push_back( Clustering(EmtTag, iRad, iRec, iPartner,
1815 pTLund(event[iRad], event[EmtTag], event[iRec], pTdef) ));
1816 continue;
1817 }
1818
1819 // Reset partner
1820 iPartner = 0;
1821 // Find recoiler by colour
1822 iRec = FindCol(col,iRad,EmtTag,event,2,true);
1823 // In initial state splitting has final state colour partner,
1824 // Save both partner and recoiler
1825 if ( (sign < 0) && (event[iRec].isFinal()) ) {
1826 // Save colour recoiler
1827 iPartner = iRec;
1828 // Reset kinematic recoiler to initial state parton
1829 for(int l = 0; l < int(PosInitPartn.size()); ++l)
1830 if (PosInitPartn[l] != iRad) iRec = PosInitPartn[l];
1831 // For final state splittings, colour partner and recoiler are
1832 // identical
1833 } else {
1834 iPartner = iRec;
1835 }
1836 if ( iRec != 0 && iPartner != 0
1837 && allowedClustering( iRad, EmtTag, iRec, iPartner, event) ) {
1838 clus.push_back( Clustering(EmtTag, iRad, iRec, iPartner,
1839 pTLund(event[iRad], event[EmtTag], event[iRec], pTdef) ));
1840 continue;
1841 }
1842 }
1843
1844 if (acl > 0) {
1845
1846 // Reset partner
1847 iPartner = 0;
1848 // Find recoiler by colour
1849 iRec = FindCol(acl,iRad,EmtTag,event,1,true);
1850 // In initial state splitting has final state colour partner,
1851 // Save both partner and recoiler
1852 if ( (sign < 0) && (event[iRec].isFinal()) ) {
1853 // Save colour recoiler
1854 iPartner = iRec;
1855 // Reset kinematic recoiler to initial state parton
1856 for(int l = 0; l < int(PosInitPartn.size()); ++l)
1857 if (PosInitPartn[l] != iRad) iRec = PosInitPartn[l];
1858 // For final state splittings, colour partner and recoiler are
1859 // identical
1860 } else {
1861 iPartner = iRec;
1862 }
1863 if ( iRec != 0 && iPartner != 0
1864 && allowedClustering( iRad, EmtTag, iRec, iPartner, event) ) {
1865 clus.push_back( Clustering(EmtTag, iRad, iRec, iPartner,
1866 pTLund(event[iRad], event[EmtTag], event[iRec], pTdef) ));
1867 continue;
1868 }
1869
1870 // Reset partner
1871 iPartner = 0;
1872 // Find recoiler by colour
1873 iRec = FindCol(acl,iRad,EmtTag,event,2,true);
1874 // In initial state splitting has final state colour partner,
1875 // Save both partner and recoiler
1876 if ( (sign < 0) && (event[iRec].isFinal()) ) {
1877 // Save colour recoiler
1878 iPartner = iRec;
1879 // Reset kinematic recoiler to initial state parton
1880 for(int l = 0; l < int(PosInitPartn.size()); ++l)
1881 if (PosInitPartn[l] != iRad) iRec = PosInitPartn[l];
1882 // For final state splittings, colour partner and recoiler are
1883 // identical
1884 } else {
1885 iPartner = iRec;
1886 }
1887 if ( iRec != 0 && iPartner != 0
1888 && allowedClustering( iRad, EmtTag, iRec, iPartner, event) ) {
1889 clus.push_back( Clustering(EmtTag, iRad, iRec, iPartner,
1890 pTLund(event[iRad], event[EmtTag], event[iRec], pTdef) ));
1891 continue;
1892 }
1893 }
1894 // Initial gluon splitting
1895 } else if ( event[iRad].id() == 21
1896 &&( event[iRad].col() == event[EmtTag].col()
1897 || event[iRad].acol() == event[EmtTag].acol() )) {
1898 // For an initial state radiator, always set recoiler
1899 // to the other initial state parton (recoil is taken
1900 // by full remaining system, so this is just a
1901 // labelling for such a process)
1902 int RecInit = 0;
1903 for(int l = 0; l < int(PosInitPartn.size()); ++l)
1904 if (PosInitPartn[l] != iRad) RecInit = PosInitPartn[l];
1905
1906 // Find the colour connected partner
1907 // Find colour index of radiator before splitting
1908 int col = getRadBeforeCol(iRad, EmtTag, event);
1909 int acl = getRadBeforeAcol(iRad, EmtTag, event);
1910
1911 // Find the correct partner: If a colour line has split,
1912 // the partner is connected to the radiator before the splitting
1913 // by a colour line (same reasoning for anticolour). The colour
1914 // that split is the colour appearing twice in the
1915 // radiator + emitted pair.
1916 // Thus, if we remove a colour index with the clustering,
1917 // we should look for a colour partner, else look for
1918 // an anticolour partner
1919 int colRemove = (event[iRad].col() == event[EmtTag].col())
1920 ? event[iRad].col() : 0;
1921
1922 int iPartner = 0;
1923 if (colRemove > 0 && col > 0)
1924 iPartner = FindCol(col,iRad,EmtTag,event,1,true)
1925 + FindCol(col,iRad,EmtTag,event,2,true);
1926 else if (colRemove > 0 && acl > 0)
1927 iPartner = FindCol(acl,iRad,EmtTag,event,1,true)
1928 + FindCol(acl,iRad,EmtTag,event,2,true);
1929
1930 if ( allowedClustering( iRad, EmtTag, RecInit, iPartner, event ) ) {
1931 clus.push_back( Clustering(EmtTag, iRad, RecInit, iPartner,
1932 pTLund(event[iRad],event[EmtTag],event[RecInit], pTdef) ));
1933 continue;
1934 }
1935 }
1936
1937 // Second colour topology: Gluon emission
1938
1939 } else {
1940 if ( (event[iRad].col() == event[EmtTag].acol())
1941 || (event[iRad].acol() == event[EmtTag].col())
1942 || (event[iRad].col() == event[EmtTag].col())
1943 || (event[iRad].acol() == event[EmtTag].acol()) ) {
1944 // For the rest, choose recoiler to have a common colour
1945 // tag with radiator, while not being the "Emitted"
1946
1947 int col = -1;
1948 int acl = -1;
1949
1950 if (event[iRad].isFinal() ) {
1951
1952 if ( event[iRad].id() < 0) {
1953 acl = event[EmtTag].acol();
1954 col = event[iRad].col();
1955 } else if ( event[iRad].id() > 0 && event[iRad].id() < 10) {
1956 col = event[EmtTag].col();
1957 acl = event[iRad].acol();
1958 } else {
1959 col = event[iRad].col();
1960 acl = event[iRad].acol();
1961 }
1962
1963 int iRec = 0;
1964 if (col > 0) {
1965 iRec = FindCol(col,iRad,EmtTag,event,1,true);
1966 if ( (sign < 0) && (event[iRec].isFinal()) ) iRec = 0;
1967 if (iRec != 0
1968 && allowedClustering( iRad, EmtTag, iRec, iRec, event) ) {
1969 clus.push_back( Clustering(EmtTag, iRad, iRec, iRec,
1970 pTLund(event[iRad],event[EmtTag],event[iRec], pTdef) ));
1971 continue;
1972 }
1973
1974 iRec = FindCol(col,iRad,EmtTag,event,2,true);
1975 if ( (sign < 0) && (event[iRec].isFinal()) ) iRec = 0;
1976 if (iRec != 0
1977 && allowedClustering( iRad, EmtTag, iRec, iRec, event) ) {
1978 clus.push_back( Clustering(EmtTag, iRad, iRec, iRec,
1979 pTLund(event[iRad],event[EmtTag],event[iRec], pTdef) ));
1980 continue;
1981 }
1982 }
1983
1984 if (acl > 0) {
1985 iRec = FindCol(acl,iRad,EmtTag,event,1,true);
1986 if ( (sign < 0) && (event[iRec].isFinal()) ) iRec = 0;
1987 if (iRec != 0
1988 && allowedClustering( iRad, EmtTag, iRec, iRec, event) ) {
1989 clus.push_back( Clustering(EmtTag, iRad, iRec, iRec,
1990 pTLund(event[iRad],event[EmtTag],event[iRec], pTdef) ));
1991 continue;
1992 }
1993
1994 iRec = FindCol(acl,iRad,EmtTag,event,2,true);
1995 if ( (sign < 0) && (event[iRec].isFinal()) ) iRec = 0;
1996 if (iRec != 0
1997 && allowedClustering( iRad, EmtTag, iRec, iRec, event) ) {
1998 clus.push_back( Clustering(EmtTag, iRad, iRec, iRec,
1999 pTLund(event[iRad],event[EmtTag],event[iRec], pTdef) ));
2000 continue;
2001 }
2002 }
2003
2004 } else {
2005
2006 // For an initial state radiator, always set recoiler
2007 // to the other initial state parton (recoil is taken
2008
2009 // by full remaining system, so this is just a
2010 // labelling for such a process)
2011 int RecInit = 0;
2012 int iPartner = 0;
2013 for(int l = 0; l < int(PosInitPartn.size()); ++l)
2014 if (PosInitPartn[l] != iRad) RecInit = PosInitPartn[l];
2015
2016 // Find the colour connected partner
2017 // Find colour index of radiator before splitting
2018 col = getRadBeforeCol(iRad, EmtTag, event);
2019 acl = getRadBeforeAcol(iRad, EmtTag, event);
2020
2021 // Find the correct partner: If a colour line has split,
2022 // the partner is connected to the radiator before the splitting
2023 // by a colour line (same reasoning for anticolour). The colour
2024 // that split is the colour appearing twice in the
2025 // radiator + emitted pair.
2026 // Thus, if we remove a colour index with the clustering,
2027 // we should look for a colour partner, else look for
2028 // an anticolour partner
2029 int colRemove = (event[iRad].col() == event[EmtTag].col())
2030 ? event[iRad].col() : 0;
2031 iPartner = (colRemove > 0)
2032 ? FindCol(col,iRad,EmtTag,event,1,true)
2033 + FindCol(col,iRad,EmtTag,event,2,true)
2034 : FindCol(acl,iRad,EmtTag,event,1,true)
2035 + FindCol(acl,iRad,EmtTag,event,2,true);
2036
2037 if ( allowedClustering( iRad, EmtTag, RecInit, iPartner, event)) {
2038 clus.push_back( Clustering(EmtTag, iRad, RecInit, iPartner,
2039 pTLund(event[iRad],event[EmtTag],event[RecInit], pTdef)));
2040
2041 continue;
2042 }
2043 }
2044 }
2045 }
2046 }
2047 }
2048
2049 // Done
2050 return clus;
2051}
2052
2053//--------------------------------------------------------------------------
2054
2055// For the history-defining state (and if necessary interfering
2056// states), find all possible clusterings.
2057// NO INPUT
2058// OUT vector of all (rad,rec,emt) systems
2059
2060vector<Clustering> History::getAllEWClusterings() {
2061 vector<Clustering> ret;
2062
2063 // Get all clusterings for input state
2064 vector<Clustering> systems;
2065 systems = getEWClusterings(state);
2066 ret.insert(ret.end(), systems.begin(), systems.end());
2067 // Done
2068 return ret;
2069}
2070
2071//--------------------------------------------------------------------------
2072
2073// For one given state, find all possible clusterings.
2074// IN Event : state to be investigated
2075// OUT vector of all (rad,rec,emt) systems in the state
2076
2077vector<Clustering> History::getEWClusterings( const Event& event) {
2078 vector<Clustering> ret;
2079
2080 // Initialise vectors to keep track of position of partons in the
2081 // input event
2082 vector <int> PosFinalPartn;
2083 vector <int> PosInitPartn;
2084 vector <int> PosFinalW;
2085
2086 // Search event record for final state particles and store these in
2087 // quark, anti-quark and gluon vectors
2088 for ( int i=0; i < event.size(); ++i )
2089 if ( event[i].isFinal() && abs(event[i].colType()) == 1 ) {
2090 // Store final partons
2091 PosFinalPartn.push_back(i);
2092 } else if ( event[i].status() == -21 && abs(event[i].colType()) == 1 ) {
2093 // Store initial partons
2094 PosInitPartn.push_back(i);
2095 }
2096 // Search event record for final W
2097 for ( int i=0; i < event.size(); ++i )
2098 if ( event[i].isFinal() && event[i].idAbs() == 24 )
2099 PosFinalW.push_back( i );
2100
2101 vector<Clustering> systems;
2102 // Find rad + emt + rec systems:
2103 // (1) Start from W boson and find all (rad,rec,emt=W) triples
2104 for ( int i = 0; i < int(PosFinalW.size()); ++i ) {
2105 int EmtW = PosFinalW[i];
2106 systems = findEWTriple( EmtW, event, PosFinalPartn);
2107 ret.insert(ret.end(), systems.begin(), systems.end());
2108 systems.resize(0);
2109 }
2110
2111 return ret;
2112}
2113
2114//--------------------------------------------------------------------------
2115
2116// Function to construct (rad,rec,emt) triples from the event
2117// IN int : Position of Emitted in event record for which
2118// dipoles should be constructed
2119// int : Colour topogy to be tested
2120// 1= g -> qqbar, causing 2 -> 2 dipole splitting
2121// 2= q(bar) -> q(bar) g && g -> gg,
2122// causing a 2 -> 3 dipole splitting
2123// Event : event record to be checked for ptential partners
2124// OUT vector of all allowed radiator+recoiler+emitted triples
2125
2126vector<Clustering> History::findEWTriple ( int EmtTagIn, const Event& event,
2127 vector<int> PosFinalPartn ) {
2128 // Copy input parton tag
2129 int EmtTag = EmtTagIn;
2130 // Copy input colour topology tag
2131 // (1: g --> qqbar splitting present, 2:rest)
2132
2133 // Initialise FinalSize
2134 int FinalSize = int(PosFinalPartn.size());
2135
2136 vector<Clustering> clus;
2137
2138 // Search final partons to find partons colour-connected to
2139 // event[EmtTag], choose radiator, then choose recoiler
2140 for ( int a = 0; a < FinalSize; ++a ) {
2141 int iRad = PosFinalPartn[a];
2142 if (iRad != EmtTag ) {
2143 int pTdef = 1;
2144 // Find recoiler by flavour.
2145 int flavRad = event[iRad].id();
2146 int flavEmt = event[EmtTag].id();
2147
2148 // Loop through final partons and try to find matching flavours.
2149 for ( int i = 0; i < FinalSize; ++i ) {
2150 int iRec = PosFinalPartn[i];
2151 if ( i != a && flavEmt > 0
2152 && event[iRec].id() == -flavRad - 1 )
2153 clus.push_back( Clustering(EmtTag, iRad, iRec, iRec,
2154 pTLund(event[iRad],event[EmtTag],event[iRec], pTdef) ) );
2155 }
2156 }
2157 }
2158
2159 // Done
2160 return clus;
2161}
2162
2163//--------------------------------------------------------------------------
2164
2165// Calculate and return the probability of a clustering.
2166// IN Clustering : rad,rec,emt - System for which the splitting
2167// probability should be calcuated
2168// OUT splitting probability
2169
2170double History::getProb(const Clustering & SystemIn) {
2171
2172 // Get local copies of input system
2173 int Rad = SystemIn.emittor;
2174 int Rec = SystemIn.recoiler;
2175 int Emt = SystemIn.emitted;
2176
2177 // Initialise shower probability
2178 double showerProb = 0.0;
2179
2180 // If the splitting resulted in disallowed evolution variable,
2181 // disallow the splitting
2182 if (SystemIn.pT() <= 0.) return 0.;
2183
2184 // Initialise all combinatorical factors
2185 double CF = 4./3.;
2186 double NC = 3.;
2187 // Flavour is known when reclustring, thus n_f=1
2188 double TR = 1./2.;
2189
2190 // Split up in FSR and ISR
2191 bool isFSR = (state[Rad].isFinal() && state[Rec].isFinal());
2192 bool isFSRinREC = (state[Rad].isFinal() && !state[Rec].isFinal());
2193 bool isISR = !state[Rad].isFinal();
2194
2195 // Check if this is the clustering 2->3 to 2->2.
2196 // If so, use weight for joined evolution
2197 int nFinal = 0;
2198 for(int i=0; i < state.size(); ++i)
2199 if (state[i].isFinal()) nFinal++;
2200 bool isLast = (nFinal == (mergingHooksPtr->hardProcess.nQuarksOut()
2201 +mergingHooksPtr->hardProcess.nLeptonOut()+1));
2202
2203 if (isISR) {
2204 // Find incoming particles
2205
2206 int inP = 0;
2207 int inM = 0;
2208 for(int i=0;i< int(state.size()); ++i) {
2209 if (state[i].mother1() == 1) inP = i;
2210 if (state[i].mother1() == 2) inM = i;
2211 }
2212 // Construct dipole mass, eCM and sHat = x1*x2*s
2213 Vec4 sum = state[Rad].p() + state[Rec].p() - state[Emt].p();
2214 double m2Dip = sum.m2Calc();
2215 double sHat = (state[inM].p() + state[inP].p()).m2Calc();
2216 // Energy fraction z=E_q1/E_qi in branch q(i)q(2) -> q(1)g(3)q(2)
2217 double z1 = m2Dip / sHat;
2218 // Virtuality of the splittings
2219 Vec4 Q1( state[Rad].p() - state[Emt].p() );
2220 Vec4 Q2( state[Rec].p() - state[Emt].p() );
2221 // Q^2 for emission off radiator line
2222 double Q1sq = -Q1.m2Calc();
2223 // pT^2 for emission off radiator line
2224 double pT1sq = pow(SystemIn.pT(),2);
2225 // Remember if massive particles involved: Mass corrections for
2226 // to g->QQ and Q->Qg splittings
2227 bool g2QQmassive = mergingHooksPtr->includeMassive()
2228 && state[Rad].id() == 21
2229 && ( state[Emt].idAbs() >= 4 && state[Emt].idAbs() < 7);
2230 bool Q2Qgmassive = mergingHooksPtr->includeMassive()
2231 && state[Emt].id() == 21
2232 && ( state[Rad].idAbs() >= 4 && state[Rad].idAbs() < 7);
2233 bool isMassive = mergingHooksPtr->includeMassive()
2234 && (g2QQmassive || Q2Qgmassive);
2235 double m2Emt0 = pow(particleDataPtr->m0(state[Emt].id()),2);
2236 double m2Rad0 = pow(particleDataPtr->m0(state[Rad].id()),2);
2237
2238 // Correction of virtuality for massive splittings
2239 if ( g2QQmassive) Q1sq += m2Emt0;
2240 else if (Q2Qgmassive) Q1sq += m2Rad0;
2241
2242 // pT0 dependence!!!
2243 double pT0sq = pow(mergingHooksPtr->pT0ISR(),2);
2244 double Q2sq = -Q2.m2Calc();
2245
2246 // Correction of virtuality of other splitting
2247 bool g2QQmassiveRec = mergingHooksPtr->includeMassive()
2248 && state[Rec].id() == 21
2249 && ( state[Emt].idAbs() >= 4 && state[Emt].idAbs() < 7);
2250 bool Q2QgmassiveRec = mergingHooksPtr->includeMassive()
2251 && state[Emt].id() == 21
2252 && ( state[Rec].idAbs() >= 4 && state[Rec].idAbs() < 7);
2253 double m2Rec0 = pow(particleDataPtr->m0(state[Rad].id()),2);
2254 if ( g2QQmassiveRec) Q2sq += m2Emt0;
2255 else if (Q2QgmassiveRec) Q2sq += m2Rec0;
2256
2257 bool hasJoinedEvol = (state[Emt].id() == 21
2258 || state[Rad].id() == state[Rec].id());
2259
2260 // Initialise normalization factor multiplying the splitting
2261 // function numerator
2262 double fac = 1.;
2263 if ( mergingHooksPtr->pickByFull() || mergingHooksPtr->pickBySumPT()) {
2264 double facJoined = ( Q2sq + pT0sq/(1.-z1) )
2265 * 1./(Q1sq*Q2sq + pT0sq*sHat + pow(pT0sq/(1.-z1),2));
2266 double facSingle = mergingHooksPtr->nonJoinedNorm()*1./( pT1sq + pT0sq);
2267
2268 fac = (hasJoinedEvol && isLast) ? facJoined : facSingle;
2269
2270 } else if (mergingHooksPtr->pickByPoPT2()) {
2271 fac = 1./(pT1sq + pT0sq);
2272 }
2273
2274 // Calculate shower splitting probability:
2275 // Splitting functions*normalization*ME reweighting factors
2276
2277 // Calculate branching probability for q -> q g
2278 if ( state[Emt].id() == 21 && state[Rad].id() != 21) {
2279 // Find splitting kernel
2280 double num = CF*(1. + pow(z1,2)) / (1.-z1);
2281 if (isMassive) num -= CF * z1 * (1.-z1) * (m2Rad0/pT1sq);
2282
2283 // Find ME reweighting factor
2284 double meReweighting = 1.;
2285 // Find the number of final state coloured particles, apart
2286 // from those coming from the hard process
2287 int nCol = 0;
2288 for(int i=0; i < state.size(); ++i)
2289 if (state[i].isFinal() && state[i].colType() != 0
2290 && !mergingHooksPtr->hardProcess.matchesAnyOutgoing(i,state) )
2291 nCol++;
2292 // For first splitting of single vector boson production,
2293 // apply ME corrections
2294 if (nCol == 1
2295 && int(mergingHooksPtr->hardProcess.hardIntermediate.size()) == 1) {
2296 double sH = m2Dip / z1;
2297 double tH = -Q1sq;
2298 double uH = Q1sq - m2Dip * (1. - z1) / z1;
2299 double misMatch = (uH*tH - (uH + tH)*pT0sq/(1.-z1)
2300 + pow(pT0sq/(1.-z1),2) ) / (uH*tH);
2301 meReweighting *= (tH*tH + uH*uH + 2. * m2Dip * sH)
2302 / (sH*sH + m2Dip*m2Dip);
2303 meReweighting *= misMatch;
2304 }
2305 // Multiply factors
2306 showerProb = num*fac*meReweighting;
2307
2308 // Calculate branching probability for g -> g g
2309 } else if ( state[Emt].id() == 21 && state[Rad].id() == 21) {
2310 // Calculate splitting kernel
2311 double num = 2.*NC*pow2(1. - z1*(1.-z1)) / (z1*(1.-z1));
2312
2313 // Include ME reweighting for higgs!!
2314 // Find ME reweighting factor
2315 double meReweighting = 1.;
2316 // Find the number of final state coloured particles, apart
2317 // from those coming from the hard process
2318 int nCol = 0;
2319 for(int i=0; i < state.size(); ++i)
2320 if (state[i].isFinal() && state[i].colType() != 0
2321 && !mergingHooksPtr->hardProcess.matchesAnyOutgoing(i,state) )
2322 nCol++;
2323 // For first splitting of single vector boson production,
2324 // apply ME corrections
2325 if ( nCol == 1
2326 && mergingHooksPtr->getProcessString().compare("pp>h") == 0
2327 && int(mergingHooksPtr->hardProcess.hardIntermediate.size()) == 1 ) {
2328 double sH = m2Dip / z1;
2329 double tH = -Q1sq;
2330 double uH = Q1sq - m2Dip * (1. - z1) / z1;
2331 meReweighting *= 0.5
2332 * (pow4(sH) + pow4(tH) + pow4(uH) + pow4(m2Dip))
2333 / pow2(sH*sH - m2Dip * (sH - m2Dip));
2334 }
2335
2336 // Multiply factors
2337 showerProb = num*fac*meReweighting;
2338
2339 // Calculate branching probability for q -> g q
2340 } else if ( state[Emt].id() != 21 && state[Rad].id() != 21 ) {
2341 // Calculate splitting kernel
2342 double num = CF*(1. + pow2(1.-z1)) / z1;
2343
2344 // Include ME reweighting for higgs!!
2345 // Find ME reweighting factor
2346 double meReweighting = 1.;
2347 // Find the number of final state coloured particles, apart
2348 // from those coming from the hard process
2349 int nCol = 0;
2350 for ( int i=0; i < state.size(); ++i )
2351 if ( state[i].isFinal() && state[i].colType() != 0
2352 && !mergingHooksPtr->hardProcess.matchesAnyOutgoing(i,state) )
2353 nCol++;
2354 // For first splitting of single vector boson production,
2355 // apply ME corrections
2356 if (nCol == 1
2357 && mergingHooksPtr->getProcessString().compare("pp>h") == 0
2358 && int(mergingHooksPtr->hardProcess.hardIntermediate.size()) == 1) {
2359 double sH = m2Dip / z1;
2360 double uH = Q1sq - m2Dip * (1. - z1) / z1;
2361 meReweighting *= (sH*sH + uH*uH)
2362 / (sH*sH + pow2(sH -m2Dip));
2363 }
2364
2365 // Multiply factors
2366 showerProb = num*fac*meReweighting;
2367
2368 // Calculate branching probability for g -> q qbar
2369 } else if ( state[Emt].id() != 21 && state[Rad].id() == 21 ) {
2370 // Calculate splitting kernel
2371 double num = TR * ( pow(z1,2) + pow(1.-z1,2) );
2372 if (isMassive) num += TR * 2.*z1*(1.-z1)*(m2Emt0/pT1sq);
2373 // Calculate ME reweighting factor
2374 double meReweighting = 1.;
2375 // Find the number of final state coloured particles, apart
2376 // from those coming from the hard process
2377 int nCol = 0;
2378 for ( int i=0; i < state.size(); ++i )
2379 if ( state[i].isFinal() && state[i].colType() != 0
2380 && !mergingHooksPtr->hardProcess.matchesAnyOutgoing(i,state) )
2381 nCol++;
2382 // For first splitting of single vector boson production,
2383 // apply ME corrections
2384 if (nCol == 1
2385 && int(mergingHooksPtr->hardProcess.hardIntermediate.size()) == 1) {
2386 double sH = m2Dip / z1;
2387 double tH = -Q1sq;
2388 double uH = Q1sq - m2Dip * (1. - z1) / z1;
2389 swap( tH, uH);
2390 double misMatch = ( uH - pT0sq/(1.-z1) ) / uH;
2391 double me = (sH*sH + uH*uH + 2. * m2Dip * tH)
2392 / (pow2(sH - m2Dip) + m2Dip*m2Dip);
2393 // Weight with me/overestimate
2394 meReweighting *= me;
2395 meReweighting *= misMatch;
2396 }
2397 // Multiply factors
2398 showerProb = num*fac*meReweighting;
2399
2400 // Print error if no kernel calculated
2401 } else {
2402 string message="Error in History::getProb: Splitting kernel undefined";
2403 message+=" in ISR clustering.";
2404 infoPtr->errorMsg(message);
2405 }
2406
2407 // If corrected pT below zero in ISR, put probability to zero
2408 double m2Sister0 = pow(state[Emt].m0(),2);
2409 double pT2corr = (Q1sq - z1*(m2Dip + Q1sq)*(Q1sq + m2Sister0)/m2Dip);
2410 if (pT2corr < 0.) showerProb *= 1e-9;
2411
2412 // If creating heavy quark by Q -> gQ then next need g -> Q + Qbar.
2413 // So minimum total mass2 is 4 * m2Sister, but use more to be safe.
2414 if ( state[Emt].id() == state[Rad].id()
2415 && ( state[Rad].idAbs() == 4 || state[Rad].idAbs() == 5 )) {
2416 double m2QQsister = 2.*4.*m2Sister0;
2417 double pT2QQcorr = Q1sq - z1*(m2Dip + Q1sq)*(Q1sq + m2QQsister)
2418 / m2Dip;
2419 if (pT2QQcorr < 0.0) showerProb *= 1e-9;
2420 }
2421
2422 if (mergingHooksPtr->includeRedundant()) {
2423 // Initialise the spacelike shower alpha_S
2424 AlphaStrong* asISR = mergingHooksPtr->AlphaS_ISR();
2425 double as = (*asISR).alphaS(pT1sq + pT0sq) / (2.*M_PI);
2426 // Multiply with alpha_S
2427 showerProb *= as;
2428 }
2429
2430 // Done for ISR case, begin FSR case
2431
2432 } else if (isFSR || isFSRinREC) {
2433
2434 // Construct dipole mass
2435 Vec4 sum = state[Rad].p() + state[Rec].p() + state[Emt].p();
2436 double m2Dip = sum.m2Calc();
2437 // Construct 2->3 variables for FSR
2438 double x1 = 2. * (sum * state[Rad].p()) / m2Dip;
2439 double x2 = 2. * (sum * state[Rec].p()) / m2Dip;
2440 double prop1 = max(1e-12, 1. - x1);
2441 double prop2 = max(1e-12, 1. - x2);
2442 double x3 = max(1e-12, 2. - x1 - x2);
2443 // Energy fraction z=E_q1/E_qi in branch q(i)q(2) -> q(1)g(3)q(2)
2444 double z1 = x1/(x1 + x3);
2445
2446 // Virtuality of the splittings
2447 Vec4 Q1( state[Rad].p() + state[Emt].p() );
2448 Vec4 Q2( state[Rec].p() + state[Emt].p() );
2449
2450 // Q^2 for emission off radiator line
2451 double Q1sq = Q1.m2Calc();
2452 // pT^2 for emission off radiator line
2453 double pT1sq = pow(SystemIn.pT(),2);
2454 // Q^2 for emission off recoiler line
2455 double Q2sq = Q2.m2Calc();
2456
2457 // Correction of virtuality for massive splittings
2458 double m2Rad0 = pow(particleDataPtr->m0(state[Rad].id()),2);
2459 double m2Rec0 = pow(particleDataPtr->m0(state[Rad].id()),2);
2460 if ( state[Rad].idAbs() >= 4 && state[Rad].idAbs() < 7)
2461 Q1sq -= m2Rad0;
2462 if ( state[Rec].idAbs() >= 4 && state[Rec].idAbs() < 7)
2463 Q2sq -= m2Rec0;
2464
2465 // Initialise normalization factor multiplying the splitting
2466 // function numerator
2467 double fac = 1.;
2468 if ( mergingHooksPtr->pickByFull() || mergingHooksPtr->pickBySumPT()) {
2469 double facJoined = (1.-z1)/Q1sq * m2Dip/( Q1sq + Q2sq );
2470 double facSingle = mergingHooksPtr->fsrInRecNorm() * 1./ pT1sq;
2471 fac = (!isFSRinREC && isLast) ? facJoined : facSingle;
2472 } else if (mergingHooksPtr->pickByPoPT2()) {
2473 fac = 1. / pT1sq;
2474 }
2475 // Calculate shower splitting probability:
2476 // Splitting functions*normalization*ME reweighting factors
2477
2478 // Calculate branching probability for g -> g_1 g_2
2479 if ( state[Emt].id() == 21 && state[Rad].id() == 21) {
2480 // Calculate splitting kernel
2481 double num = 0.5* NC * (1. + pow3(z1)) / (1.-z1);
2482 // Multiply factors
2483 showerProb = num*fac;
2484
2485 // Calculate branching probability for q -> q g with quark recoiler
2486 } else if ( state[Emt].id() == 21
2487 && state[Rad].id() != 21 && state[Rec].id() != 21) {
2488 // For a qqbar dipole in FSR, ME corrections exist and the
2489 // splitting function "z-weight" is set to 1.0 (only for 2->2 ??)
2490 double num = CF * 2./(1.-z1);
2491 // Find the number of final state coloured particles, apart
2492 // from those coming from the hard process
2493 int nCol = 0;
2494 for(int i=0; i < state.size(); ++i)
2495 if (state[i].isFinal() && state[i].colType() != 0
2496 && !mergingHooksPtr->hardProcess.matchesAnyOutgoing(i,state) )
2497 nCol++;
2498 // Calculate splitting kernel
2499 if ( nCol > 3
2500 || int(mergingHooksPtr->hardProcess.hardIntermediate.size()) > 1)
2501 num = CF * (1. + pow2(z1)) /(1.-z1);
2502 // Calculate ME reweighting factor
2503 double meReweighting = 1.;
2504 // Correct if this is the process created by the first
2505 // FSR splitting of a 2->2 process
2506 if ( nCol == 3
2507 && int(mergingHooksPtr->hardProcess.hardIntermediate.size()) == 1 ) {
2508 // Calculate the ME reweighting factor
2509 double ShowerRate1 = 2./( x3 * prop2 );
2510 double meDividingFactor1 = prop1 / x3;
2511 double me = (pow(x1,2) + pow(x2,2))/(prop1*prop2);
2512 meReweighting = meDividingFactor1 * me / ShowerRate1;
2513 }
2514 // Multiply factors
2515 showerProb = num*fac*meReweighting;
2516
2517 // Calculate branching probability for q1 -> q2 w+- with quark recoiler
2518 } else if ( state[Emt].idAbs() == 24
2519 && state[Rad].id() != 21 && state[Rec].id() != 21 ) {
2520 double m2W = state[Emt].p().m2Calc();
2521 double num = ( 3.*pow2(m2W / m2Dip)
2522 + 2.* (m2W/m2Dip)*(x1 + x2)
2523 + pow2(x1) + pow2(x2) ) / ( prop1*prop2 )
2524 - (m2W/m2Dip) / pow2(prop1)
2525 - (m2W/m2Dip) / pow2(prop2);
2526 // Multiply factors
2527 showerProb = num*fac;
2528
2529 // Calculate branching probability for q -> q g with gluon recoiler
2530 } else if ( state[Emt].id() == 21 && state[Rad].id() != 21
2531 && state[Rec].id() == 21 ) {
2532 // For qg /qbarg dipoles, the splitting function is
2533 // calculated and not weighted by a ME correction factor
2534 // Shower splitting function
2535 double num = CF * (1. + pow2(z1)) / (1.-z1);
2536 showerProb = num*fac;
2537
2538 // Calculate branching probability for g -> q qbar
2539 } else if ( state[Emt].id() != 21 ) {
2540 // Get flavour of quark / antiquark
2541 int flavour = state[Emt].id();
2542 // Get correct masses for the quarks
2543 // (needed to calculate splitting function?)
2544 double mFlavour = particleDataPtr->m0(flavour);
2545 // Get mass of quark/antiquark pair
2546 double mDipole = m(state[Rad].p(), state[Emt].p());
2547 // Factor determining if gluon decay was allowed
2548 double beta = sqrtpos( 1. - 4.*pow2(mFlavour)/pow2(mDipole) );
2549 // Shower splitting function
2550 double num = 0.5*TR * ( z1*z1 + (1.-z1)*(1.-z1) );
2551
2552 showerProb = num*fac*beta;
2553
2554 // Print error if no kernel calculated
2555 } else {
2556 string message="Error in History::getProb: Splitting kernel undefined";
2557 message+=" in FSR clustering.";
2558 infoPtr->errorMsg(message);
2559 }
2560
2561 if (mergingHooksPtr->includeRedundant()) {
2562 // Initialise the spacelike shower alpha_S
2563 AlphaStrong* asFSR = mergingHooksPtr->AlphaS_FSR();
2564 double as = (*asFSR).alphaS(pT1sq) / (2.*M_PI);
2565 // Multiply with alpha_S
2566 showerProb *= as;
2567 }
2568
2569 // Done for FSR
2570 } else {
2571 string message="Error in History::getProb: Radiation could not be";
2572 message+=" interpreted as FSR or ISR.";
2573 infoPtr->errorMsg(message);
2574 }
2575
2576 if (showerProb <= 0.) showerProb = 0.;
2577
2578 //// Different coupling constants for qcd and ew splittings
2579 //if ( state[Emt].colType() != 0 ) {
2580 // AlphaStrong* asFSR = mergingHooksPtr->AlphaS_FSR();
2581 // double as = (*asFSR).alphaS(91.188*91.188) / (2.*M_PI);
2582 // showerProb *= as;
2583 //} else {
2584 // AlphaEM* aEMFSR = mergingHooksPtr->AlphaEM_FSR();
2585 // double aEM = (*aEMFSR).alphaEM(91.188*91.188) / (2.*M_PI);
2586 // showerProb *= aEM;
2587 //}
2588
2589 // Done
2590 return showerProb;
2591}
2592
2593
2594//--------------------------------------------------------------------------
2595
2596// Set up the beams (fill the beam particles with the correct
2597// current incoming particles) to allow calculation of splitting
2598// probability.
2599// For interleaved evolution, set assignments dividing PDFs into
2600// sea and valence content. This assignment is, until a history path
2601// is chosen and a first trial shower performed, not fully correct
2602// (since content is chosen form too high x and too low scale). The
2603// assignment used for reweighting will be corrected after trial
2604// showering
2605
2606void History::setupBeams() {
2607
2608 // Do nothing for empty event, possible if sequence of
2609 // clusterings was ill-advised in that it results in
2610 // colour-disconnected states
2611 if (state.size() < 4) return;
2612 // Do nothing for e+e- beams
2613 if ( state[3].colType() == 0 ) return;
2614 if ( state[4].colType() == 0 ) return;
2615
2616 // Incoming partons to hard process are stored in slots 3 and 4.
2617 int inS = 0;
2618 int inP = 0;
2619 int inM = 0;
2620 for(int i=0;i< int(state.size()); ++i) {
2621 if (state[i].mother1() == 1) inP = i;
2622 if (state[i].mother1() == 2) inM = i;
2623 }
2624
2625 // Save some info before clearing beams
2626 // Mothers of incoming partons companion code
2627 int motherPcompRes = -1;
2628 int motherMcompRes = -1;
2629
2630 bool sameFlavP = false;
2631 bool sameFlavM = false;
2632
2633 if (mother) {
2634 int inMotherP = 0;
2635 int inMotherM = 0;
2636 for(int i=0;i< int(mother->state.size()); ++i) {
2637 if (mother->state[i].mother1() == 1) inMotherP = i;
2638 if (mother->state[i].mother1() == 2) inMotherM = i;
2639 }
2640 sameFlavP = (state[inP].id() == mother->state[inMotherP].id());
2641 sameFlavM = (state[inM].id() == mother->state[inMotherM].id());
2642
2643 motherPcompRes = (sameFlavP) ? beamA[0].companion() : -2;
2644 motherMcompRes = (sameFlavM) ? beamB[0].companion() : -2;
2645 }
2646
2647 // Append the current incoming particles to the beam
2648 beamA.clear();
2649 beamB.clear();
2650
2651 // Get energy of incoming particles
2652 double Ep = 2. * state[inP].e();
2653 double Em = 2. * state[inM].e();
2654
2655 // If incoming partons are massive then recalculate to put them massless.
2656 if (state[inP].m() != 0. || state[inM].m() != 0.) {
2657 Ep = state[inP].pPos() + state[inM].pPos();
2658 Em = state[inP].pNeg() + state[inM].pNeg();
2659 }
2660
2661 // Add incoming hard-scattering partons to list in beam remnants.
2662 double x1 = Ep / state[inS].m();
2663 beamA.append( inP, state[inP].id(), x1);
2664 double x2 = Em / state[inS].m();
2665 beamB.append( inM, state[inM].id(), x2);
2666
2667 // Scale. For ME multiplicity history, put scale to mu_F
2668 // (since sea/valence quark content is chosen from this scale)
2669 double scalePDF = (mother) ? scale : infoPtr->QFac();
2670 // Find whether incoming partons are valence or sea. Store.
2671 // Can I do better, e.g. by setting the scale to the hard process
2672 // scale (= M_W) or by replacing one of the x values by some x/z??
2673 beamA.xfISR( 0, state[inP].id(), x1, scalePDF*scalePDF);
2674 if (!mother) {
2675 beamA.pickValSeaComp();
2676 } else {
2677 beamA[0].companion(motherPcompRes);
2678 }
2679 beamB.xfISR( 0, state[inM].id(), x2, scalePDF*scalePDF);
2680 if (!mother) {
2681 beamB.pickValSeaComp();
2682 } else {
2683 beamB[0].companion(motherMcompRes);
2684 }
2685
2686}
2687
2688//--------------------------------------------------------------------------
2689
2690// Calculate the PDF ratio used in the argument of the no-emission
2691// probability
2692
2693double History::pdfForSudakov() {
2694
2695 // Do nothing for e+e- beams
2696 if ( state[3].colType() == 0 ) return 1.0;
2697 if ( state[4].colType() == 0 ) return 1.0;
2698
2699 // Check if splittings was ISR or FSR
2700 bool FSR = ( mother->state[clusterIn.emittor].isFinal()
2701 && mother->state[clusterIn.recoiler].isFinal());
2702 bool FSRinRec = ( mother->state[clusterIn.emittor].isFinal()
2703 && !mother->state[clusterIn.recoiler].isFinal());
2704
2705 // Done for pure FSR
2706 if (FSR) return 1.0;
2707
2708 int iInMother = (FSRinRec)? clusterIn.recoiler : clusterIn.emittor;
2709 // Find side of event that was reclustered
2710 int side = ( mother->state[iInMother].pz() > 0 ) ? 1 : -1;
2711
2712 int inP = 0;
2713 int inM = 0;
2714 for(int i=0;i< int(state.size()); ++i) {
2715 if (state[i].mother1() == 1) inP = i;
2716 if (state[i].mother1() == 2) inM = i;
2717 }
2718
2719 // Save mother id
2720 int idMother = mother->state[iInMother].id();
2721 // Find daughter position and id
2722 int iDau = (side == 1) ? inP : inM;
2723 int idDaughter = state[iDau].id();
2724 // Get mother x value
2725 double xMother = 2. * mother->state[iInMother].e() / mother->state[0].e();
2726 // Get daughter x value of daughter
2727 double xDaughter = 2.*state[iDau].e() / state[0].e(); // x1 before isr
2728
2729 // Calculate pdf ratio
2730 double ratio = getPDFratio(side, true, idMother, xMother, scale,
2731 idDaughter, xDaughter, scale);
2732
2733 // For FSR with incoming recoiler, maximally return 1.0, as
2734 // is done in Pythia::TimeShower.
2735 // For ISR, return ratio
2736 return ( (FSRinRec)? min(1.,ratio) : ratio);
2737}
2738
2739//--------------------------------------------------------------------------
2740
2741// Perform the clustering of the current state and return the
2742// clustered state.
2743// IN Clustering : rad,rec,emt triple to be clustered to two partons
2744// OUT clustered state
2745
2746Event History::cluster( const Clustering & inSystem ) {
2747
2748 // Initialise tags of particles to be changed
2749 int Rad = inSystem.emittor;
2750 int Rec = inSystem.recoiler;
2751 int Emt = inSystem.emitted;
2752 // Initialise eCM,mHat
2753 double eCM = state[0].e();
2754 // Flags for type of radiation
2755 int radType = state[Rad].isFinal() ? 1 : -1;
2756 int recType = state[Rec].isFinal() ? 1 : -1;
2757
2758 // Construct the clustered event
2759 Event NewEvent = Event();
2760 NewEvent.init("(hard process-modified)", particleDataPtr);
2761 NewEvent.clear();
2762 // Copy all unchanged particles to NewEvent
2763 for (int i = 0; i < state.size(); ++i)
2764 if ( i != Rad && i != Rec && i != Emt )
2765 NewEvent.append( state[i] );
2766
2767 // Copy all the junctions one by one
2768 for (int i = 0; i < state.sizeJunction(); ++i)
2769 NewEvent.appendJunction( state.getJunction(i) );
2770 // Set particle data table pointer
2771 NewEvent.setPDTPtr();
2772 // Find an appropriate scale for the hard process
2773 double mu = choseHardScale(state);
2774 // Initialise scales for new event
2775 NewEvent.saveSize();
2776 NewEvent.saveJunctionSize();
2777 NewEvent.scale(mu);
2778 NewEvent.scaleSecond(mu);
2779
2780 // Set properties of radiator/recoiler after the clustering
2781 // Recoiler properties will be unchanged
2782 Particle RecBefore = Particle( state[Rec] );
2783 RecBefore.daughters(0,0);
2784 // Find flavour of radiator before splitting
2785 int radID = getRadBeforeFlav(Rad, Emt, state);
2786 Particle RadBefore = Particle( state[Rad] );
2787 RadBefore.id(radID);
2788 RadBefore.daughters(0,0);
2789 // Put dummy values for colours
2790 RadBefore.cols(RecBefore.acol(),RecBefore.col());
2791 // Put mass for radiator and recoiler
2792 RecBefore.m(particleDataPtr->m0(state[Rec].id()));
2793 RadBefore.m(particleDataPtr->m0(radID));
2794
2795 // Construct momenta and colours of clustered particles
2796 // ISR/FSR splittings are treated differently
2797 if ( radType + recType == 2 && state[Emt].idAbs() != 24 ) {
2798 // Clustering of final(rad)/final(rec) dipole splitting
2799 // Get eCM of (rad,rec,emt) triple
2800 Vec4 sum = state[Rad].p() + state[Rec].p() + state[Emt].p();
2801 double eCMME = sum.mCalc();
2802
2803 // Define radiator and recoiler back-to-back in the dipole
2804 // rest frame [=(state[rad]+state[emt])+state[rec] rest frame]
2805 Vec4 Rad4mom;
2806 Vec4 Rec4mom;
2807 Rad4mom.p( 0., 0., 0.5*eCMME, 0.5*eCMME);
2808 Rec4mom.p( 0., 0.,-0.5*eCMME, 0.5*eCMME);
2809
2810 // Find boost from Rad4mom+Rec4mom rest frame to event cm frame
2811 Vec4 old1 = Vec4(state[Rad].p() + state[Emt].p());
2812 Vec4 old2 = Vec4(state[Rec].p());
2813 RotBstMatrix fromCM;
2814 fromCM.fromCMframe(old1, old2);
2815 // Transform momenta
2816 Rad4mom.rotbst(fromCM);
2817 Rec4mom.rotbst(fromCM);
2818
2819 RadBefore.p(Rad4mom);
2820 RecBefore.p(Rec4mom);
2821
2822 } else if ( radType + recType == 2 && state[Emt].idAbs() == 24 ) {
2823 // Clustering of final(rad)/final(rec) dipole splitting
2824 // Get eCM of (rad,rec,emt) triple
2825 Vec4 sum = state[Rad].p() + state[Rec].p() + state[Emt].p();
2826 double eCMME = sum.mCalc();
2827
2828 // Define radiator and recoiler back-to-back in the dipole
2829 // rest frame [=(state[rad]+state[emt])+state[rec] rest frame]
2830 Vec4 Rad4mom;
2831 Vec4 Rec4mom;
2832 Rad4mom.p( 0., 0., 0.5*eCMME, 0.5*eCMME);
2833 Rec4mom.p( 0., 0.,-0.5*eCMME, 0.5*eCMME);
2834
2835 // Find boost from Rad4mom+Rec4mom rest frame to event cm frame
2836 Vec4 old1 = Vec4(state[Rad].p() + state[Emt].p());
2837 Vec4 old2 = Vec4(state[Rec].p());
2838 RotBstMatrix fromCM;
2839 fromCM.fromCMframe(old1, old2);
2840 // Transform momenta
2841 Rad4mom.rotbst(fromCM);
2842 Rec4mom.rotbst(fromCM);
2843
2844 RadBefore.p(Rad4mom);
2845 RecBefore.p(Rec4mom);
2846
2847 } else if ( radType + recType == 0 ) {
2848 // Clustering of final(rad)/initial(rec) dipole splitting
2849 // Get eCM of (rad,rec,emt) triple
2850 Vec4 sum = state[Rad].p() + state[Rec].p() + state[Emt].p();
2851 double eCMME = sum.mCalc();
2852 // Define radiator and recoiler back-to-back in the dipole
2853 // rest frame [=(state[rad]+state[emt])+state[rec] rest frame]
2854 Vec4 Rad4mom;
2855 Vec4 Rec4mom;
2856 Rad4mom.p( 0., 0., 0.5*eCMME, 0.5*eCMME);
2857 Rec4mom.p( 0., 0.,-0.5*eCMME, 0.5*eCMME);
2858
2859 // Find boost from Rad4mom+Rec4mom rest frame to event cm frame
2860 Vec4 old1 = Vec4(state[Rad].p() + state[Emt].p());
2861 Vec4 old2 = Vec4(state[Rec].p());
2862 RotBstMatrix fromCM;
2863 fromCM.fromCMframe(old1, old2);
2864 // Transform momenta
2865 Rad4mom.rotbst(fromCM);
2866 Rec4mom.rotbst(fromCM);
2867
2868 // Rescale recoiler momentum
2869 Rec4mom = 2.*state[Rec].p() - Rec4mom;
2870
2871 RadBefore.p(Rad4mom);
2872 RecBefore.p(Rec4mom);
2873
2874 // Set mass of initial recoiler to zero
2875 RecBefore.m( 0.0 );
2876
2877 } else {
2878 // Clustering of initial(rad)/initial(rec) dipole splitting
2879 // We want to cluster: Meaning doing the inverse of a process
2880 // ( pDaughter + pRecoiler -> pOut )
2881 // ==> ( pMother + pPartner -> pOut' + pSister )
2882 // produced by an initial state splitting. The matrix element
2883 // provides us with pMother, pPartner, pSister and pOut'
2884 Vec4 pMother( state[Rad].p() );
2885 Vec4 pSister( state[Emt].p() );
2886 Vec4 pPartner( state[Rec].p() );
2887 Vec4 pDaughter( 0.,0.,0.,0. );
2888 Vec4 pRecoiler( 0.,0.,0.,0. );
2889
2890 // Find side that radiates event (mother moving in
2891 // sign * p_z direction)
2892
2893 int sign = state[Rad].pz() > 0 ? 1 : -1;
2894
2895 // Find rotation by phi that would have been done for a
2896 // splitting daughter -> mother + sister
2897 double phi = pSister.phi();
2898 // Find rotation with -phi
2899 RotBstMatrix rot_by_mphi;
2900 rot_by_mphi.rot(0.,-phi);
2901 // Find rotation with +phi
2902 RotBstMatrix rot_by_pphi;
2903 rot_by_pphi.rot(0.,phi);
2904
2905 // Transform pMother and outgoing momenta
2906 pMother.rotbst( rot_by_mphi );
2907 pSister.rotbst( rot_by_mphi );
2908 pPartner.rotbst( rot_by_mphi );
2909 for(int i=3; i< NewEvent.size(); ++i)
2910 NewEvent[i].rotbst( rot_by_mphi );
2911
2912 // Get mother and partner x values
2913 // x1 after isr
2914 double x1 = 2. * pMother.e() / eCM;
2915 // x2 after isr
2916 double x2 = 2. * pPartner.e() / eCM;
2917
2918 pDaughter.p( pMother - pSister);
2919 pRecoiler.p( pPartner );
2920
2921 // Find boost from event cm frame to rest frame of
2922 // of-shell daughter + on-shell recoiler
2923 RotBstMatrix from_CM_to_DR;
2924 if (sign == 1)
2925 from_CM_to_DR.toCMframe(pDaughter, pRecoiler);
2926 else
2927 from_CM_to_DR.toCMframe(pRecoiler, pDaughter);
2928
2929 // Transform all momenta
2930 pMother.rotbst( from_CM_to_DR );
2931 pPartner.rotbst( from_CM_to_DR );
2932 pSister.rotbst( from_CM_to_DR );
2933 for(int i=3; i< NewEvent.size(); ++i)
2934 NewEvent[i].rotbst( from_CM_to_DR );
2935
2936 // Find theta angle between pMother and z-axis and undo
2937 // rotation that would have been done by shower
2938 double theta = pMother.theta();
2939 if ( pMother.px() < 0. ) theta *= -1.;
2940 if (sign == -1) theta += M_PI;
2941 // Find rotation by +theta
2942 RotBstMatrix rot_by_ptheta;
2943 rot_by_ptheta.rot(theta, 0.);
2944
2945 // Transform all momenta
2946 pMother.rotbst( rot_by_ptheta );
2947 pPartner.rotbst( rot_by_ptheta );
2948 pSister.rotbst( rot_by_ptheta );
2949 for(int i=3; i< NewEvent.size(); ++i)
2950 NewEvent[i].rotbst( rot_by_ptheta );
2951
2952 // Find z of the splitting
2953 Vec4 qDip( pMother - pSister);
2954 Vec4 qAfter(pMother + pPartner);
2955 Vec4 qBefore(qDip + pPartner);
2956 double z = qBefore.m2Calc() / qAfter.m2Calc();
2957
2958 // Calculate new e_CM^2
2959 double x1New = z*x1; // x1 before isr
2960 double x2New = x2; // x2 before isr
2961 double sHat = x1New*x2New*eCM*eCM;
2962
2963 // Construct daughter and recoiler momenta
2964 pDaughter.p( 0., 0., sign*0.5*sqrt(sHat), 0.5*sqrt(sHat));
2965 pRecoiler.p( 0., 0., -sign*0.5*sqrt(sHat), 0.5*sqrt(sHat));
2966
2967 // Find boost from current (daughter+recoiler rest frame)
2968 // frame to rest frame of daughter+unchanged recoiler to
2969 // recover the old x2 value
2970 RotBstMatrix from_DR_to_CM;
2971 from_DR_to_CM.bst( 0., 0., sign*( x1New - x2New ) / ( x1New + x2New ) );
2972
2973 // Correct for momentum mismatch by transforming all momenta
2974 pMother.rotbst( from_DR_to_CM );
2975 pPartner.rotbst( from_DR_to_CM );
2976 pSister.rotbst( from_DR_to_CM );
2977 pDaughter.rotbst( from_DR_to_CM );
2978 pRecoiler.rotbst( from_DR_to_CM );
2979 for(int i=3; i< NewEvent.size(); ++i)
2980 NewEvent[i].rotbst( from_DR_to_CM );
2981
2982 // Transform pMother and outgoing momenta
2983 pMother.rotbst( rot_by_pphi );
2984 pPartner.rotbst( rot_by_pphi );
2985 pSister.rotbst( rot_by_pphi );
2986 pDaughter.rotbst( rot_by_pphi );
2987 pRecoiler.rotbst( rot_by_pphi );
2988 for(int i=3; i< NewEvent.size(); ++i)
2989 NewEvent[i].rotbst( rot_by_pphi );
2990
2991 // Set momenta of particles to be attached to new event record
2992 RecBefore.p( pRecoiler );
2993 RadBefore.p( pDaughter );
2994
2995 }
2996
2997 // Put some dummy production scales for RecBefore, RadBefore
2998 RecBefore.scale(mu);
2999 RadBefore.scale(mu);
3000 RecBefore.setPDTPtr(particleDataPtr);
3001 RadBefore.setPDTPtr(particleDataPtr);
3002
3003 // Append new recoiler and find new radiator colour
3004 NewEvent.append(RecBefore);
3005
3006 // Assign the correct colour to re-clustered radiator.
3007 // Keep old radiator colours for electroweak emission.
3008 int emtID = state[Emt].id();
3009 if ( emtID == 22 || emtID == 23 || abs(emtID) == 24 )
3010 RadBefore.cols( state[Rad].col(), state[Rad].acol() );
3011 // For QCD, carefully construct colour.
3012 else if ( !connectRadiator( RadBefore, radType, RecBefore, recType,
3013 NewEvent ) ) {
3014 // Could happen if previous clustering produced several colour
3015 // singlett subsystems in the event
3016 NewEvent.reset();
3017 return NewEvent;
3018 }
3019
3020 // Build the clustered event
3021 Event outState = Event();
3022 outState.init("(hard process-modified)", particleDataPtr);
3023 outState.clear();
3024
3025 // Copy system and incoming beam particles to outState
3026 for (int i = 0; i < 3; ++i)
3027 outState.append( NewEvent[i] );
3028 // Copy all the junctions one by one
3029 for (int i = 0; i < state.sizeJunction(); ++i)
3030 outState.appendJunction( state.getJunction(i) );
3031 // Set particle data table pointer
3032 outState.setPDTPtr();
3033 // Initialise scales for new event
3034 outState.saveSize();
3035 outState.saveJunctionSize();
3036 outState.scale(mu);
3037 outState.scaleSecond(mu);
3038 bool radAppended = false;
3039 bool recAppended = false;
3040 int size = int(outState.size());
3041 // Save position of radiator in new event record
3042 int radPos = 0;
3043 // Append first incoming particle
3044 if ( RecBefore.mother1() == 1) {
3045 outState.append( RecBefore );
3046 recAppended = true;
3047 } else if ( RadBefore.mother1() == 1 ) {
3048 radPos = outState.append( RadBefore );
3049 radAppended = true;
3050 } else {
3051 // Find second incoming in input event
3052 int in1 = 0;
3053 for(int i=0; i < int(state.size()); ++i)
3054 if (state[i].mother1() == 1) in1 =i;
3055 outState.append( state[in1] );
3056 size++;
3057 }
3058 // Append second incoming particle
3059 if ( RecBefore.mother1() == 2) {
3060 outState.append( RecBefore );
3061 recAppended = true;
3062 } else if ( RadBefore.mother1() == 2 ) {
3063 radPos = outState.append( RadBefore );
3064 radAppended = true;
3065 } else {
3066 // Find second incoming in input event
3067 int in2 = 0;
3068 for(int i=0; i < int(state.size()); ++i)
3069 if (state[i].mother1() == 2) in2 =i;
3070
3071 outState.append( state[in2] );
3072 size++;
3073 }
3074
3075 // Append new recoiler if not done already
3076 if (!recAppended && !RecBefore.isFinal()) {
3077 recAppended = true;
3078 outState.append( RecBefore);
3079 }
3080 // Append new radiator if not done already
3081 if (!radAppended && !RadBefore.isFinal()) {
3082 radAppended = true;
3083 radPos = outState.append( RadBefore);
3084 }
3085
3086 // Append intermediate particle
3087 // (careful not to append reclustered recoiler)
3088 for (int i = 0; i < int(NewEvent.size()-1); ++i)
3089 if (NewEvent[i].status() == -22) outState.append( NewEvent[i] );
3090
3091 if (!recAppended) outState.append(RecBefore);
3092 if (!radAppended) radPos = outState.append(RadBefore);
3093
3094 // Append final state particles, partons first (not reclustered recoiler)
3095 for(int i = 0; i < int(NewEvent.size()-1); ++i)
3096 if (NewEvent[i].colType() != 0 && NewEvent[i].isFinal())
3097 outState.append( NewEvent[i] );
3098
3099 for(int i = 0; i < int(NewEvent.size()-1); ++i)
3100 if (NewEvent[i].colType() == 0 && NewEvent[i].isFinal())
3101 outState.append( NewEvent[i]);
3102
3103 // Find intermediate and respective daughters
3104 vector<int> PosIntermediate;
3105 vector<int> PosDaughter1;
3106 vector<int> PosDaughter2;
3107 for(int i=0; i < int(outState.size()); ++i)
3108 if (outState[i].status() == -22) {
3109 PosIntermediate.push_back(i);
3110 int d1 = outState[i].daughter1();
3111 int d2 = outState[i].daughter2();
3112 // Find daughters in output state
3113 int daughter1 = FindParticle( state[d1], outState);
3114 int daughter2 = FindParticle( state[d2], outState);
3115 // If both daughters found, done
3116 // Else put first final particle as first daughter
3117 // and last final particle as second daughter
3118 if (daughter1 > 0)
3119 PosDaughter1.push_back( daughter1);
3120 else {
3121 daughter1 = 0;
3122 while(!outState[daughter1].isFinal() ) daughter1++;
3123 PosDaughter1.push_back( daughter1);
3124 }
3125 if (daughter2 > 0)
3126 PosDaughter2.push_back( daughter2);
3127 else {
3128 daughter2 = outState.size()-1;
3129 while(!outState[daughter2].isFinal() ) daughter2--;
3130 PosDaughter2.push_back( daughter2);
3131 }
3132 }
3133 // Set daughters and mothers
3134 for(int i=0; i < int(PosIntermediate.size()); ++i) {
3135 outState[PosIntermediate[i]].daughters(PosDaughter1[i],PosDaughter2[i]);
3136 outState[PosDaughter1[i]].mother1(PosIntermediate[i]);
3137 outState[PosDaughter2[i]].mother1(PosIntermediate[i]);
3138 }
3139
3140 // Find range of final state partons
3141 int minParFinal = int(outState.size());
3142 int maxParFinal = 0;
3143 for(int i=0; i < int(outState.size()); ++i)
3144 if (outState[i].mother1() == 3 && outState[i].mother2() == 4) {
3145 minParFinal = min(i,minParFinal);
3146 maxParFinal = max(i,maxParFinal);
3147 }
3148
3149 if (minParFinal == maxParFinal) maxParFinal = 0;
3150 outState[3].daughters(minParFinal,maxParFinal);
3151 outState[4].daughters(minParFinal,maxParFinal);
3152
3153 // Update event properties
3154 outState.saveSize();
3155 outState.saveJunctionSize();
3156
3157 // Almost there...
3158 // If an intermediate coloured parton exists which was directly
3159 // colour connected to the radiator before the splitting, and the
3160 // radiator before and after the splitting had only one colour, problems
3161 // will arise since the colour of the radiator will be changed, whereas
3162 // the intermediate parton still has the old colour. In effect, this
3163 // means that when setting up a event for trial showering, one colour will
3164 // be free.
3165 // Hence, check for an intermediate coloured triplet resonance has been
3166 // colour-connected to the "old" radiator.
3167 // Find resonance
3168 int iColRes = 0;
3169 if ( radType == -1 && state[Rad].colType() == 1) {
3170 // Find resonance connected to initial colour
3171 for(int i=0; i < int(state.size()); ++i)
3172 if ( i != Rad && i != Emt && i != Rec
3173 && state[i].status() == -22
3174 && state[i].col() == state[Rad].col() )
3175 iColRes = i;
3176 } else if ( radType == -1 && state[Rad].colType() == -1) {
3177 // Find resonance connected to initial anticolour
3178 for(int i=0; i < int(state.size()); ++i)
3179 if ( i != Rad && i != Emt && i != Rec
3180 && state[i].status() == -22
3181 && state[i].acol() == state[Rad].acol() )
3182 iColRes = i;
3183 } else if ( radType == 1 && state[Rad].colType() == 1) {
3184 // Find resonance connected to final state colour
3185 for(int i=0; i < int(state.size()); ++i)
3186 if ( i != Rad && i != Emt && i != Rec
3187 && state[i].status() == -22
3188 && state[i].col() == state[Rad].col() )
3189 iColRes = i;
3190 } else if ( radType == 1 && state[Rad].colType() == -1) {
3191 // Find resonance connected to final state anticolour
3192 for(int i=0; i < int(state.size()); ++i)
3193 if ( i != Rad && i != Emt && i != Rec
3194 && state[i].status() == -22
3195 && state[i].acol() == state[Rad].acol() )
3196 iColRes = i;
3197 }
3198
3199 if (iColRes > 0) {
3200 // Now find this resonance in the reclustered state
3201 int iColResNow = FindParticle( state[iColRes], outState);
3202 // Find reclustered radiator colours
3203 int radCol = outState[radPos].col();
3204 int radAcl = outState[radPos].acol();
3205 // Find resonance radiator colours
3206 int resCol = outState[iColResNow].col();
3207 int resAcl = outState[iColResNow].acol();
3208 // Check if any of the reclustered radiators colours match the resonance
3209 bool matchesRes = (radCol > 0
3210 && ( radCol == resCol || radCol == resAcl))
3211 || (radAcl > 0
3212 && ( radAcl == resCol || radAcl == resAcl));
3213
3214 // If a resonance has been found, but no colours match, change
3215 // the colour of the resonance
3216 if (!matchesRes && iColResNow > 0) {
3217 if ( radType == -1 && outState[radPos].colType() == 1)
3218 outState[iColResNow].col(radCol);
3219 else if ( radType ==-1 && outState[radPos].colType() ==-1)
3220 outState[iColResNow].acol(radAcl);
3221 else if ( radType == 1 && outState[radPos].colType() == 1)
3222 outState[iColResNow].col(radCol);
3223 else if ( radType == 1 && outState[radPos].colType() ==-1)
3224 outState[iColResNow].acol(radAcl);
3225 }
3226
3227 }
3228
3229 // If event is not constructed properly, return false
3230 if ( !validEvent(outState) ) {
3231 outState.reset();
3232 return outState;
3233 }
3234
3235 // Remember position of reclustered radiator in state
3236 iReclusteredNew = radPos;
3237
3238 // Done
3239 return outState;
3240}
3241
3242//--------------------------------------------------------------------------
3243
3244// Function to get the flavour of the radiator before the splitting
3245// for clustering
3246// IN int : Flavour of the radiator after the splitting
3247// int : Flavour of the emitted after the splitting
3248// OUT int : Flavour of the radiator before the splitting
3249
3250int History::getRadBeforeFlav(const int RadAfter, const int EmtAfter,
3251 const Event& event) {
3252
3253 int type = event[RadAfter].isFinal() ? 1 :-1;
3254 int emtID = event[EmtAfter].id();
3255 int radID = event[RadAfter].id();
3256 int emtCOL = event[EmtAfter].col();
3257 int radCOL = event[RadAfter].col();
3258 int emtACL = event[EmtAfter].acol();
3259 int radACL = event[RadAfter].acol();
3260
3261 bool colConnected = ((type == 1) && ( (emtCOL !=0 && (emtCOL ==radACL))
3262 || (emtACL !=0 && (emtACL ==radCOL)) ))
3263 ||((type ==-1) && ( (emtCOL !=0 && (emtCOL ==radCOL))
3264 || (emtACL !=0 && (emtACL ==radACL)) ));
3265 // QCD splittings
3266 // Gluon radiation
3267 if ( emtID == 21 )
3268 return radID;
3269 // Final state gluon splitting
3270 if ( type == 1 && emtID == -radID && !colConnected )
3271 return 21;
3272 // Initial state s-channel gluon splitting
3273 if ( type ==-1 && radID == 21 )
3274 return -emtID;
3275 // Initial state t-channel gluon splitting
3276 if ( type ==-1 && emtID != 21 && radID != 21 && !colConnected )
3277 return 21;
3278
3279 // Electroweak splittings splittings
3280 // Photon / Z radiation: Calculate invariant mass of system
3281 double m2final = (event[RadAfter].p()+ event[EmtAfter].p()).m2Calc();
3282
3283 if ( emtID == 22 || emtID == 23 ) return radID;
3284 // Final state Photon splitting
3285 if ( type == 1 && emtID == -radID && colConnected && sqrt(m2final) <= 10. )
3286 return 22;
3287 // Final state Photon splitting
3288 if ( type == 1 && emtID == -radID && colConnected && sqrt(m2final) > 10. )
3289 return 23;
3290 // Initial state s-channel photon/ Z splitting
3291 if ( type ==-1 && (radID == 22 || radID == 23) )
3292 return -emtID;
3293 // Initial state t-channel photon / Z splitting: Always bookkeep as photon
3294 if ( type ==-1 && abs(emtID) < 10 && abs(radID) < 10 && colConnected )
3295 return 22;
3296
3297 // W+ radiation
3298 // Final state W+ splitting
3299 if ( emtID == 24 && radID < 0 ) return radID + 1;
3300 if ( emtID == 24 && radID > 0 ) return radID + 1;
3301
3302 // W- radiation
3303 // Final state W- splitting
3304 if ( emtID ==-24 && radID < 0 ) return radID - 1;
3305 if ( emtID ==-24 && radID > 0 ) return radID - 1;
3306
3307 return 0;
3308
3309}
3310
3311//--------------------------------------------------------------------------
3312
3313// Function to properly colour-connect the radiator to the rest of
3314// the event, as needed during clustering
3315// IN Particle& : Particle to be connected
3316// Particle : Recoiler forming a dipole with Radiator
3317// Event : event to which Radiator shall be appended
3318// OUT true : Radiator could be connected to the event
3319// false : Radiator could not be connected to the
3320// event or the resulting event was
3321// non-valid
3322
3323bool History::connectRadiator( Particle& Radiator, const int RadType,
3324 const Particle& Recoiler, const int RecType,
3325 const Event& event ) {
3326
3327 // Start filling radiator colour indices with dummy values
3328 Radiator.cols( -1, -1 );
3329
3330 // Radiator should always be colour-connected to recoiler.
3331 // Three cases (rad = Anti-Quark, Quark, Gluon) to be considered
3332 if ( Radiator.colType() == -1 ) {
3333 // For final state antiquark radiator, the anticolour is fixed
3334 // by the final / initial state recoiler colour / anticolour
3335 if ( RadType + RecType == 2 )
3336 Radiator.cols( 0, Recoiler.col());
3337 else if ( RadType + RecType == 0 )
3338 Radiator.cols( 0, Recoiler.acol());
3339 // For initial state antiquark radiator, the anticolour is fixed
3340 // by the colour of the emitted gluon (which will be the
3341 // leftover anticolour of a final state particle or the leftover
3342 // colour of an initial state particle ( = the recoiler))
3343 else {
3344 // Set colour of antiquark radiator to zero
3345 Radiator.col( 0 );
3346 for (int i = 0; i < event.size(); ++i) {
3347 int col = event[i].col();
3348 int acl = event[i].acol();
3349
3350 if ( event[i].isFinal()) {
3351 // Search for leftover anticolour in final / initial state
3352 if ( acl > 0 && FindCol(acl,i,0,event,1,true) == 0
3353 && FindCol(acl,i,0,event,2,true) == 0 )
3354 Radiator.acol(event[i].acol());
3355 } else {
3356 // Search for leftover colour in initial / final state
3357 if ( col > 0 && FindCol(col,i,0,event,1,true) == 0
3358 && FindCol(col,i,0,event,2,true) == 0 )
3359 Radiator.acol(event[i].col());
3360 }
3361 } // end loop over particles in event record
3362 }
3363
3364 } else if ( Radiator.colType() == 1 ) {
3365 // For final state quark radiator, the colour is fixed
3366 // by the final / initial state recoiler anticolour / colour
3367 if ( RadType + RecType == 2 )
3368 Radiator.cols( Recoiler.acol(), 0);
3369
3370 else if ( RadType + RecType == 0 )
3371 Radiator.cols( Recoiler.col(), 0);
3372 // For initial state quark radiator, the colour is fixed
3373 // by the anticolour of the emitted gluon (which will be the
3374 // leftover colour of a final state particle or the leftover
3375 // anticolour of an initial state particle ( = the recoiler))
3376
3377 else {
3378 // Set anticolour of quark radiator to zero
3379 Radiator.acol( 0 );
3380 for (int i = 0; i < event.size(); ++i) {
3381 int col = event[i].col();
3382 int acl = event[i].acol();
3383
3384 if ( event[i].isFinal()) {
3385 // Search for leftover colour in final / initial state
3386 if ( col > 0 && FindCol(col,i,0,event,1,true) == 0
3387 && FindCol(col,i,0,event,2,true) == 0)
3388 Radiator.col(event[i].col());
3389 } else {
3390 // Search for leftover anticolour in initial / final state
3391 if ( acl > 0 && FindCol(acl,i,0,event,1,true) == 0
3392 && FindCol(acl,i,0,event,2,true) == 0)
3393 Radiator.col(event[i].acol());
3394 }
3395 } // end loop over particles in event record
3396
3397 } // end distinction between fsr / fsr+initial recoiler / isr
3398
3399 } else if ( Radiator.colType() == 2 ) {
3400 // For a gluon radiator, one (anticolour) colour index is defined
3401 // by the recoiler colour (anticolour).
3402 // The remaining index is chosen to match the free index in the
3403 // event
3404 // Search for leftover colour (anticolour) in the final state
3405 for (int i = 0; i < event.size(); ++i) {
3406 int col = event[i].col();
3407 int acl = event[i].acol();
3408 int iEx = i;
3409
3410 if ( event[i].isFinal()) {
3411 if ( col > 0 && FindCol(col,iEx,0,event,1,true) == 0
3412 && FindCol(col,iEx,0,event,2,true) == 0) {
3413 if (Radiator.status() < 0 ) Radiator.col(event[i].col());
3414 else Radiator.acol(event[i].col());
3415 }
3416 if ( acl > 0 && FindCol(acl,iEx,0,event,2,true) == 0
3417 && FindCol(acl,iEx,0,event,1,true) == 0 ) {
3418 if (Radiator.status() < 0 ) Radiator.acol(event[i].acol());
3419 else Radiator.col(event[i].acol());
3420 }
3421 } else {
3422 if ( col > 0 && FindCol(col,iEx,0,event,1,true) == 0
3423 && FindCol(col,iEx,0,event,2,true) == 0) {
3424 if (Radiator.status() < 0 ) Radiator.acol(event[i].col());
3425 else Radiator.col(event[i].col());
3426 }
3427 if ( acl > 0 && (FindCol(acl,iEx,0,event,2,true) == 0
3428 && FindCol(acl,iEx,0,event,1,true) == 0)) {
3429 if (Radiator.status() < 0 ) Radiator.col(event[i].acol());
3430 else Radiator.acol(event[i].acol());
3431 }
3432 }
3433 } // end loop over particles in event record
3434 } // end cases of different radiator colour type
3435
3436 // If either colour or anticolour has not been set, return false
3437 if (Radiator.col() < 0 || Radiator.acol() < 0) return false;
3438 // Done
3439 return true;
3440}
3441
3442//--------------------------------------------------------------------------
3443
3444// Function to find a colour (anticolour) index in the input event
3445// IN int col : Colour tag to be investigated
3446// int iExclude1 : Identifier of first particle to be excluded
3447// from search
3448// int iExclude2 : Identifier of second particle to be excluded
3449// from search
3450// Event event : event to be searched for colour tag
3451// int type : Tag to define if col should be counted as
3452// colour (type = 1) [->find anti-colour index
3453// contracted with col]
3454// anticolour (type = 2) [->find colour index
3455// contracted with col]
3456// OUT int : Position of particle in event record
3457// contraced with col [0 if col is free tag]
3458
3459int History::FindCol(int col, int iExclude1, int iExclude2,
3460 const Event& event, int type, bool isHardIn) {
3461
3462 bool isHard = isHardIn;
3463 int index = 0;
3464
3465 if (isHard) {
3466 // Search event record for matching colour & anticolour
3467 for(int n = 0; n < event.size(); ++n) {
3468 if ( n != iExclude1 && n != iExclude2
3469 && event[n].colType() != 0
3470 &&( event[n].status() > 0 // Check outgoing
3471 || event[n].status() == -21) ) { // Check incoming
3472 if ( event[n].acol() == col ) {
3473 index = -n;
3474 break;
3475 }
3476 if ( event[n].col() == col ) {
3477 index = n;
3478 break;
3479 }
3480 }
3481 }
3482 } else {
3483
3484 // Search event record for matching colour & anticolour
3485 for(int n = 0; n < event.size(); ++n) {
3486 if ( n != iExclude1 && n != iExclude2
3487 && event[n].colType() != 0
3488 &&( event[n].status() == 43 // Check outgoing from ISR
3489 || event[n].status() == 51 // Check outgoing from FSR
3490 || event[n].status() == -41 // first initial
3491 || event[n].status() == -42) ) { // second initial
3492 if ( event[n].acol() == col ) {
3493 index = -n;
3494 break;
3495 }
3496 if ( event[n].col() == col ) {
3497 index = n;
3498 break;
3499 }
3500 }
3501 }
3502 }
3503 // if no matching colour / anticolour has been found, return false
3504 if ( type == 1 && index < 0) return abs(index);
3505 if ( type == 2 && index > 0) return abs(index);
3506
3507 return 0;
3508}
3509
3510//--------------------------------------------------------------------------
3511
3512// Function to in the input event find a particle with quantum
3513// numbers matching those of the input particle
3514// IN Particle : Particle to be searched for
3515// Event : Event to be searched in
3516// OUT int : > 0 : Position of matching particle in event
3517// < 0 : No match in event
3518
3519int History::FindParticle( const Particle& particle, const Event& event,
3520 bool checkStatus ) {
3521
3522 int index = -1;
3523
3524 for ( int i = int(event.size()) - 1; i > 0; --i )
3525 if ( event[i].id() == particle.id()
3526 && event[i].colType() == particle.colType()
3527 && event[i].chargeType() == particle.chargeType()
3528 && event[i].col() == particle.col()
3529 && event[i].acol() == particle.acol()
3530 && event[i].charge() == particle.charge() ) {
3531 index = i;
3532 break;
3533 }
3534
3535 if ( checkStatus && event[index].status() != particle.status() )
3536 index = -1;
3537
3538 return index;
3539}
3540
3541//--------------------------------------------------------------------------
3542
3543// Function to get the colour of the radiator before the splitting
3544// for clustering
3545// IN int : Position of the radiator after the splitting, in the event
3546// int : Position of the emitted after the splitting, in the event
3547// Event : Reference event
3548// OUT int : Colour of the radiator before the splitting
3549
3550int History::getRadBeforeCol(const int rad, const int emt,
3551 const Event& event) {
3552
3553 // Save type of splitting
3554 int type = (event[rad].isFinal()) ? 1 :-1;
3555 // Get flavour of radiator after potential clustering
3556 int radBeforeFlav = getRadBeforeFlav(rad,emt,event);
3557 // Get colours of the radiator before the potential clustering
3558 int radBeforeCol = -1;
3559 // Get reconstructed gluon colours
3560 if (radBeforeFlav == 21) {
3561
3562 // Start with quark emissions in FSR
3563 if (type == 1 && event[emt].id() != 21) {
3564 radBeforeCol = (event[rad].col() > 0)
3565 ? event[rad].col() : event[emt].col();
3566 // Quark emissions in ISR
3567 } else if (type == -1 && event[emt].id() != 21) {
3568 radBeforeCol = (event[rad].col() > 0)
3569 ? event[rad].col() : event[emt].acol();
3570 //Gluon emissions in FSR
3571 } else if (type == 1 && event[emt].id() == 21) {
3572 // If emitted is a gluon, remove the repeated index, and take
3573 // the remaining indices as colour and anticolour
3574 int colRemove = (event[rad].col() == event[emt].acol())
3575 ? event[rad].acol() : event[rad].col();
3576 radBeforeCol = (event[rad].col() == colRemove)
3577 ? event[emt].col() : event[rad].col();
3578 //Gluon emissions in ISR
3579 } else if (type == -1 && event[emt].id() == 21) {
3580 // If emitted is a gluon, remove the repeated index, and take
3581 // the remaining indices as colour and anticolour
3582 int colRemove = (event[rad].col() == event[emt].col())
3583 ? event[rad].col() : event[rad].acol();
3584 radBeforeCol = (event[rad].col() == colRemove)
3585 ? event[emt].acol() : event[rad].col();
3586 }
3587
3588 // Get reconstructed quark colours
3589 } else if ( radBeforeFlav != 21 && radBeforeFlav > 0) {
3590
3591 // Quark emission in FSR
3592 if (type == 1 && event[emt].id() != 21) {
3593 // If radiating is a quark, remove the repeated index, and take
3594 // the remaining indices as colour and anticolour
3595 int colRemove = (event[rad].col() == event[emt].acol())
3596 ? event[rad].acol() : 0;
3597 radBeforeCol = (event[rad].col() == colRemove)
3598 ? event[emt].col() : event[rad].col();
3599 //Gluon emissions in FSR
3600 } else if (type == 1 && event[emt].id() == 21) {
3601 // If emitted is a gluon, remove the repeated index, and take
3602 // the remaining indices as colour and anticolour
3603 int colRemove = (event[rad].col() == event[emt].acol())
3604 ? event[rad].col() : 0;
3605 radBeforeCol = (event[rad].col() == colRemove)
3606 ? event[emt].col() : event[rad].col();
3607 //Quark emissions in ISR
3608 } else if (type == -1 && event[emt].id() != 21) {
3609 // If emitted is a quark, remove the repeated index, and take
3610 // the remaining indices as colour and anticolour
3611 int colRemove = (event[rad].col() == event[emt].col())
3612 ? event[rad].col() : 0;
3613 radBeforeCol = (event[rad].col() == colRemove)
3614 ? event[emt].acol() : event[rad].col();
3615 //Gluon emissions in ISR
3616 } else if (type == -1 && event[emt].id() == 21) {
3617 // If emitted is a gluon, remove the repeated index, and take
3618 // the remaining indices as colour and anticolour
3619 int colRemove = (event[rad].col() == event[emt].col())
3620 ? event[rad].col() : 0;
3621 radBeforeCol = (event[rad].col() == colRemove)
3622 ? event[emt].acol() : event[rad].col();
3623 }
3624 // Other particles are assumed uncoloured
3625 } else {
3626 radBeforeCol = 0;
3627 }
3628
3629 return radBeforeCol;
3630
3631}
3632
3633//--------------------------------------------------------------------------
3634
3635// Function to get the anticolour of the radiator before the splitting
3636// for clustering
3637// IN int : Position of the radiator after the splitting, in the event
3638// int : Position of the emitted after the splitting, in the event
3639// Event : Reference event
3640// OUT int : Anticolour of the radiator before the splitting
3641
3642int History::getRadBeforeAcol(const int rad, const int emt,
3643 const Event& event) {
3644
3645 // Save type of splitting
3646 int type = (event[rad].isFinal()) ? 1 :-1;
3647 // Get flavour of radiator after potential clustering
3648 int radBeforeFlav = getRadBeforeFlav(rad,emt,event);
3649 // Get colours of the radiator before the potential clustering
3650 int radBeforeAcl = -1;
3651 // Get reconstructed gluon colours
3652 if (radBeforeFlav == 21) {
3653
3654 // Start with quark emissions in FSR
3655 if (type == 1 && event[emt].id() != 21) {
3656 radBeforeAcl = (event[rad].acol() > 0)
3657 ? event[rad].acol() : event[emt].acol();
3658 // Quark emissions in ISR
3659 } else if (type == -1 && event[emt].id() != 21) {
3660 radBeforeAcl = (event[rad].acol() > 0)
3661 ? event[rad].acol() : event[emt].col();
3662 //Gluon emissions in FSR
3663 } else if (type == 1 && event[emt].id() == 21) {
3664 // If emitted is a gluon, remove the repeated index, and take
3665 // the remaining indices as colour and anticolour
3666 int colRemove = (event[rad].col() == event[emt].acol())
3667 ? event[rad].acol() : event[rad].col();
3668 radBeforeAcl = (event[rad].acol() == colRemove)
3669 ? event[emt].acol() : event[rad].acol();
3670 //Gluon emissions in ISR
3671 } else if (type == -1 && event[emt].id() == 21) {
3672 // If emitted is a gluon, remove the repeated index, and take
3673 // the remaining indices as colour and anticolour
3674 int colRemove = (event[rad].col() == event[emt].col())
3675 ? event[rad].col() : event[rad].acol();
3676 radBeforeAcl = (event[rad].acol() == colRemove)
3677 ? event[emt].col() : event[rad].acol();
3678 }
3679
3680 // Get reconstructed anti-quark colours
3681 } else if ( radBeforeFlav != 21 && radBeforeFlav < 0) {
3682
3683 // Antiquark emission in FSR
3684 if (type == 1 && event[emt].id() != 21) {
3685 // If radiating is a antiquark, remove the repeated index, and take
3686 // the remaining indices as colour and anticolour
3687 int colRemove = (event[rad].col() == event[emt].acol())
3688 ? event[rad].acol() : 0;
3689 radBeforeAcl = (event[rad].acol() == colRemove)
3690 ? event[emt].acol() : event[rad].acol();
3691 //Gluon emissions in FSR
3692 } else if (type == 1 && event[emt].id() == 21) {
3693 // If emitted is a gluon, remove the repeated index, and take
3694 // the remaining indices as colour and anticolour
3695 int colRemove = (event[rad].acol() == event[emt].col())
3696 ? event[rad].acol() : 0;
3697 radBeforeAcl = (event[rad].acol() == colRemove)
3698 ? event[emt].acol() : event[rad].acol();
3699 //Antiquark emissions in ISR
3700 } else if (type == -1 && event[emt].id() != 21) {
3701 // If emitted is an antiquark, remove the repeated index, and take
3702 // the remaining indices as colour and anticolour
3703 int colRemove = (event[rad].acol() == event[emt].acol())
3704 ? event[rad].acol() : 0;
3705 radBeforeAcl = (event[rad].acol() == colRemove)
3706 ? event[emt].col() : event[rad].acol();
3707 //Gluon emissions in ISR
3708 } else if (type == -1 && event[emt].id() == 21) {
3709 // If emitted is a gluon, remove the repeated index, and take
3710 // the remaining indices as colour and anticolour
3711 int colRemove = (event[rad].acol() == event[emt].acol())
3712 ? event[rad].acol() : 0;
3713 radBeforeAcl = (event[rad].acol() == colRemove)
3714 ? event[emt].col() : event[rad].acol();
3715 }
3716 // Other particles are considered uncoloured
3717 } else {
3718 radBeforeAcl = 0;
3719 }
3720
3721 return radBeforeAcl;
3722
3723}
3724
3725//--------------------------------------------------------------------------
3726
3727 // Function to get the parton connected to in by a colour line
3728 // IN int : Position of parton for which partner should be found
3729 // Event : Reference event
3730 // OUT int : If a colour line connects the "in" parton with another
3731 // parton, return the Position of the partner, else return 0
3732
3733int History::getColPartner(const int in, const Event& event) {
3734
3735 if (event[in].col() == 0) return 0;
3736
3737 int partner = 0;
3738 // Try to find anticolour index first
3739 partner = FindCol(event[in].col(),in,0,event,1,true);
3740 // If no anticolour index has been found, try colour
3741 if (partner == 0)
3742 partner = FindCol(event[in].col(),in,0,event,2,true);
3743
3744 return partner;
3745
3746}
3747
3748//--------------------------------------------------------------------------
3749
3750 // Function to get the parton connected to in by an anticolour line
3751 // IN int : Position of parton for which partner should be found
3752 // Event : Reference event
3753 // OUT int : If an anticolour line connects the "in" parton with another
3754 // parton, return the Position of the partner, else return 0
3755
3756int History::getAcolPartner(const int in, const Event& event) {
3757
3758 if (event[in].acol() == 0) return 0;
3759
3760 int partner = 0;
3761 // Try to find colour index first
3762 partner = FindCol(event[in].acol(),in,0,event,2,true);
3763 // If no colour index has been found, try anticolour
3764 if (partner == 0)
3765 partner = FindCol(event[in].acol(),in,0,event,1,true);
3766
3767 return partner;
3768
3769}
3770
3771//--------------------------------------------------------------------------
3772
3773// Function to get the list of partons connected to the particle
3774// formed by reclusterinf emt and rad by colour and anticolour lines
3775// IN int : Position of radiator in the clustering
3776// IN int : Position of emitted in the clustering
3777// Event : Reference event
3778// OUT vector<int> : List of positions of all partons that are connected
3779// to the parton that will be formed
3780// by clustering emt and rad.
3781
3782vector<int> History::getReclusteredPartners(const int rad, const int emt,
3783 const Event& event) {
3784
3785 // Save type
3786 int type = event[rad].isFinal() ? 1 : -1;
3787 // Get reclustered colours
3788 int radBeforeCol = getRadBeforeCol(rad, emt, event);
3789 int radBeforeAcl = getRadBeforeAcol(rad, emt, event);
3790 // Declare output
3791 vector<int> partners;
3792
3793 // Start with FSR clusterings
3794 if (type == 1) {
3795
3796 for(int i=0; i < int(event.size()); ++i) {
3797 // Check all initial state partons
3798 if ( i != emt && i != rad
3799 && event[i].status() == -21
3800 && event[i].col() > 0
3801 && event[i].col() == radBeforeCol)
3802 partners.push_back(i);
3803 // Check all final state partons
3804 if ( i != emt && i != rad
3805 && event[i].isFinal()
3806 && event[i].acol() > 0
3807 && event[i].acol() == radBeforeCol)
3808 partners.push_back(i);
3809 // Check all initial state partons
3810 if ( i != emt && i != rad
3811 && event[i].status() == -21
3812 && event[i].acol() > 0
3813 && event[i].acol() == radBeforeAcl)
3814 partners.push_back(i);
3815 // Check all final state partons
3816 if ( i != emt && i != rad
3817 && event[i].isFinal()
3818 && event[i].col() > 0
3819 && event[i].col() == radBeforeAcl)
3820 partners.push_back(i);
3821 }
3822 // Start with ISR clusterings
3823 } else {
3824
3825 for(int i=0; i < int(event.size()); ++i) {
3826 // Check all initial state partons
3827 if ( i != emt && i != rad
3828 && event[i].status() == -21
3829 && event[i].acol() > 0
3830 && event[i].acol() == radBeforeCol)
3831 partners.push_back(i);
3832 // Check all final state partons
3833 if ( i != emt && i != rad
3834 && event[i].isFinal()
3835 && event[i].col() > 0
3836 && event[i].col() == radBeforeCol)
3837 partners.push_back(i);
3838 // Check all initial state partons
3839 if ( i != emt && i != rad
3840 && event[i].status() == -21
3841 && event[i].col() > 0
3842 && event[i].col() == radBeforeAcl)
3843 partners.push_back(i);
3844 // Check all final state partons
3845 if ( i != emt && i != rad
3846 && event[i].isFinal()
3847 && event[i].acol() > 0
3848 && event[i].acol() == radBeforeAcl)
3849 partners.push_back(i);
3850 }
3851
3852 }
3853 // Done
3854 return partners;
3855}
3856
3857//--------------------------------------------------------------------------
3858
3859// Function to extract a chain of colour-connected partons in
3860// the event
3861// IN int : Type of parton from which to start extracting a
3862// parton chain. If the starting point is a quark
3863// i.e. flavType = 1, a chain of partons that are
3864// consecutively connected by colour-lines will be
3865// extracted. If the starting point is an antiquark
3866// i.e. flavType =-1, a chain of partons that are
3867// consecutively connected by anticolour-lines
3868// will be extracted.
3869// IN int : Position of the parton from which a
3870// colour-connected chain should be derived
3871// IN Event : Refernence event
3872// IN/OUT vector<int> : Partons that should be excluded from the search.
3873// OUT vector<int> : Positions of partons along the chain
3874// OUT bool : Found singlet / did not find singlet
3875
3876bool History::getColSinglet( const int flavType, const int iParton,
3877 const Event& event, vector<int>& exclude, vector<int>& colSinglet) {
3878
3879 // If no possible flavour to start from has been found
3880 if (iParton < 0) return false;
3881
3882 // If no further partner has been found in a previous iteration,
3883 // and the whole final state has been excluded, we're done
3884 if (iParton == 0) {
3885
3886 // Count number of final state partons
3887 int nFinal = 0;
3888 for(int i=0; i < int(event.size()); ++i)
3889 if ( event[i].isFinal() && event[i].colType() != 0)
3890 nFinal++;
3891
3892 // Get number of initial state partons in the list of
3893 // excluded partons
3894 int nExclude = int(exclude.size());
3895 int nInitExclude = 0;
3896 if (!event[exclude[2]].isFinal())
3897 nInitExclude++;
3898 if (!event[exclude[3]].isFinal())
3899 nInitExclude++;
3900
3901 // If the whole final state has been considered, return
3902 if (nFinal == nExclude - nInitExclude)
3903 return true;
3904 else
3905 return false;
3906
3907 }
3908
3909 // Declare colour partner
3910 int colP = 0;
3911 // Save the colour partner
3912 colSinglet.push_back(iParton);
3913 // Remove the partner from the list
3914 exclude.push_back(iParton);
3915 // When starting out from a quark line, follow the colour lines
3916 if (flavType == 1)
3917 colP = getColPartner(iParton,event);
3918 // When starting out from an antiquark line, follow the anticolour lines
3919 else
3920 colP = getAcolPartner(iParton,event);
3921
3922 // Do not count excluded partons twice
3923 for(int i = 0; i < int(exclude.size()); ++i)
3924 if (colP == exclude[i])
3925 return true;
3926
3927 // Recurse
3928 return getColSinglet(flavType,colP,event,exclude,colSinglet);
3929
3930}
3931
3932//--------------------------------------------------------------------------
3933
3934// Function to check that a set of partons forms a colour singlet
3935// IN Event : Reference event
3936// IN vector<int> : Positions of the partons in the set
3937// OUT bool : Is a colour singlet / is not
3938
3939bool History::isColSinglet( const Event& event,
3940 vector<int> system ) {
3941
3942 // Check if system forms a colour singlet
3943 for(int i=0; i < int(system.size()); ++i ) {
3944 // Match quark and gluon colours
3945 if ( system[i] > 0
3946 && (event[system[i]].colType() == 1
3947 || event[system[i]].colType() == 2) ) {
3948 for(int j=0; j < int(system.size()); ++j)
3949 // If flavour matches, remove both partons and continue
3950 if ( system[i] > 0
3951 && system[j] > 0
3952 && event[system[i]].col() == event[system[j]].acol()) {
3953 // Remove index and break
3954 system[i] = 0;
3955 system[j] = 0;
3956 break;
3957 }
3958 }
3959 // Match antiquark and gluon anticolours
3960 if ( system[i] > 0
3961 && (event[system[i]].colType() == -1
3962 || event[system[i]].colType() == 2) ) {
3963 for(int j=0; j < int(system.size()); ++j)
3964 // If flavour matches, remove both partons and continue
3965 if ( system[i] > 0
3966 && system[j] > 0
3967 && event[system[i]].acol() == event[system[j]].col()) {
3968 // Remove index and break
3969 system[i] = 0;
3970 system[j] = 0;
3971 break;
3972 }
3973 }
3974
3975 }
3976
3977 // The system is a colour singlet if for all colours,
3978 // an anticolour was found
3979 bool isColSing = true;
3980 for(int i=0; i < int(system.size()); ++i)
3981 if ( system[i] != 0 )
3982 isColSing = false;
3983
3984 // Return
3985 return isColSing;
3986
3987}
3988
3989//--------------------------------------------------------------------------
3990
3991// Function to check that a set of partons forms a flavour singlet
3992// IN Event : Reference event
3993// IN vector<int> : Positions of the partons in the set
3994// IN int : Flavour of all the quarks in the set, if
3995// all quarks in a set should have a fixed flavour
3996// OUT bool : Is a flavour singlet / is not
3997
3998bool History::isFlavSinglet( const Event& event,
3999 vector<int> system, int flav) {
4000
4001 // If a decoupled colour singlet has been found, check if this is also
4002 // a flavour singlet
4003 // Check that each quark matches an antiquark
4004 for(int i=0; i < int(system.size()); ++i)
4005 if ( system[i] > 0 ) {
4006 for(int j=0; j < int(system.size()); ++j) {
4007 // If flavour of outgoing partons matches,
4008 // remove both partons and continue.
4009 // Skip all bosons
4010 if ( event[i].idAbs() != 21
4011 && event[i].idAbs() != 22
4012 && event[i].idAbs() != 23
4013 && event[i].idAbs() != 24
4014 && system[i] > 0
4015 && system[j] > 0
4016 && event[system[i]].isFinal()
4017 && event[system[j]].isFinal()
4018 && event[system[i]].id() == -1*event[system[j]].id()) {
4019 // If we want to check if only one flavour of quarks
4020 // exists
4021 if (abs(flav) > 0 && event[system[i]].idAbs() != flav)
4022 return false;
4023 // Remove index and break
4024 system[i] = 0;
4025 system[j] = 0;
4026 break;
4027 }
4028 // If flavour of outgoing and incoming partons match,
4029 // remove both partons and continue.
4030 // Skip all bosons
4031 if ( event[i].idAbs() != 21
4032 && event[i].idAbs() != 22
4033 && event[i].idAbs() != 23
4034 && event[i].idAbs() != 24
4035 && system[i] > 0
4036 && system[j] > 0
4037 && ( ( !event[system[i]].isFinal() && event[system[j]].isFinal())
4038 ||( !event[system[j]].isFinal() && event[system[i]].isFinal()) )
4039 && event[system[i]].id() == event[system[j]].id()) {
4040 // If we want to check if only one flavour of quarks
4041 // exists
4042 if (abs(flav) > 0 && event[system[i]].idAbs() != flav)
4043 return false;
4044 // Remove index and break
4045 system[i] = 0;
4046 system[j] = 0;
4047 break;
4048 }
4049
4050 }
4051 }
4052
4053 // The colour singlet is a flavour singlet if for all quarks,
4054 // an antiquark was found
4055 bool isFlavSing = true;
4056 for(int i=0; i < int(system.size()); ++i)
4057 if ( system[i] != 0 )
4058 isFlavSing = false;
4059
4060 // Return
4061 return isFlavSing;
4062
4063}
4064
4065
4066//--------------------------------------------------------------------------
4067
4068// Function to check if rad,emt,rec triple is allowed for clustering
4069// IN int rad,emt,rec : Positions (in event record) of the three
4070// particles considered for clustering
4071// Event event : Reference event
4072
4073bool History::allowedClustering( int rad, int emt, int rec, int partner,
4074 const Event& event ) {
4075
4076 // Declare output
4077 bool allowed = true;
4078
4079 // CONSTRUCT SOME PROPERTIES FOR LATER INVESTIGATION
4080
4081 // Check if the triple forms a colour singlett
4082 bool isSing = isSinglett(rad,emt,partner,event);
4083 int type = (event[rad].isFinal()) ? 1 :-1;
4084 // Get flavour of radiator after potential clustering
4085 int radBeforeFlav = getRadBeforeFlav(rad,emt,event);
4086 // Get colours of the radiator before the potential clustering
4087 int radBeforeCol = getRadBeforeCol(rad,emt,event);
4088 int radBeforeAcl = getRadBeforeAcol(rad,emt,event);
4089 // Get colour partner of reclustered parton
4090 vector<int> radBeforeColP = getReclusteredPartners(rad, emt, event);
4091
4092 // Count coloured partons in hard process
4093 int nPartonInHard = 0;
4094 for(int i=0; i < int(event.size()); ++i)
4095 // Check all final state partons
4096 if ( event[i].isFinal()
4097 && event[i].colType() != 0
4098 && mergingHooksPtr->hardProcess.matchesAnyOutgoing(i, event) )
4099 nPartonInHard++;
4100
4101
4102 // Count coloured final state partons in event, excluding
4103 // rad, rec, emt and hard process
4104 int nPartons = 0;
4105 for(int i=0; i < int(event.size()); ++i)
4106 // Check all final state partons
4107 if ( i!=emt && i!=rad && i!=rec
4108 && event[i].isFinal()
4109 && event[i].colType() != 0
4110 && !mergingHooksPtr->hardProcess.matchesAnyOutgoing(i, event) )
4111 nPartons++;
4112
4113 // Count number of initial state partons
4114 int nInitialPartons = 0;
4115 for(int i=0; i < int(event.size()); ++i)
4116 if ( event[i].status() == -21
4117 && event[i].colType() != 0 )
4118 nInitialPartons++;
4119
4120 // Get number of non-charged final state particles
4121 int nFinalEW = 0;
4122 for(int i=0; i < int(event.size()); ++i)
4123 if ( event[i].isFinal()
4124 &&( event[i].id() == 22
4125 || event[i].id() == 23
4126 || event[i].id() == 24
4127 ||(event[i].idAbs() > 10 && event[i].idAbs() < 20)))
4128 nFinalEW++;
4129
4130 // Check if event after potential clustering contains an even
4131 // number of quarks and/or antiquarks
4132 // (otherwise no electroweak vertex could be formed!)
4133 // Get number of final quarks
4134 int nFinalQuark = 0;
4135 // Get number of excluded final state quarks as well
4136 int nFinalQuarkExc = 0;
4137 for(int i=0; i < int(event.size()); ++i) {
4138 if (i !=rad && i != emt && i != rec) {
4139 if (event[i].isFinal() && event[i].isQuark() ) {
4140 if ( !mergingHooksPtr->hardProcess.matchesAnyOutgoing(i,event) )
4141 nFinalQuark++;
4142 else
4143 nFinalQuarkExc++;
4144 }
4145 }
4146 }
4147
4148 // Add recoiler to number of final quarks
4149 if (event[rec].isFinal() && event[rec].isQuark()) nFinalQuark++;
4150 // Add radiator after clustering to number of final quarks
4151 if (event[rad].isFinal() && abs(radBeforeFlav) < 10) nFinalQuark++;
4152
4153 // Get number of initial quarks
4154 int nInitialQuark = 0;
4155 if (type == 1) {
4156 if (event[rec].isFinal()) {
4157 if (event[3].isQuark()) nInitialQuark++;
4158 if (event[4].isQuark()) nInitialQuark++;
4159 } else {
4160 int iOtherIn = (rec == 3) ? 4 : 3;
4161 if (event[rec].isQuark()) nInitialQuark++;
4162 if (event[iOtherIn].isQuark()) nInitialQuark++;
4163 }
4164 } else {
4165 // Add recoiler to number of initial quarks
4166 if (event[rec].isQuark()) nInitialQuark++;
4167 // Add radiator after clustering to number of initial quarks
4168 if (abs(radBeforeFlav) < 10) nInitialQuark++;
4169 }
4170
4171 // If only odd number of quarks in state,
4172 // reject (no electroweak vertex can be formed).
4173 // This is only true of no primary partonic resonance could have produced
4174 // electroweak bosons.
4175 // Check for tops
4176 int nTop = 0;
4177 for(int i=0; i < int(event.size()); ++i)
4178 if (event[i].idAbs() == 6)
4179 nTop++;
4180
4181 // BEGIN CHECKING THE CLUSTERING
4182
4183 // Check if colour is conserved
4184 vector<int> unmatchedCol;
4185 vector<int> unmatchedAcl;
4186 // Check all unmatched colours
4187 for ( int i = 0; i < event.size(); ++i)
4188 if ( i != emt && i != rad
4189 && (event[i].isFinal() || event[i].status() == -21)
4190 && event[i].colType() != 0 ) {
4191
4192 int colP = getColPartner(i,event);
4193 int aclP = getAcolPartner(i,event);
4194
4195 if (event[i].col() > 0
4196 && (colP == emt || colP == rad || colP == 0) )
4197 unmatchedCol.push_back(i);
4198 if (event[i].acol() > 0
4199 && (aclP == emt || aclP == rad || aclP == 0) )
4200 unmatchedAcl.push_back(i);
4201
4202 }
4203
4204 // If more than one colour or more than one anticolour are unmatched,
4205 // there is no way to make this clustering work
4206 if (int(unmatchedCol.size()) + int(unmatchedAcl.size()) > 2)
4207 return false;
4208
4209 // If triple forms colour singlett, check that resulting state
4210 // matches hard core process
4211 if (isSing)
4212 allowed = false;
4213 if (isSing && (abs(radBeforeFlav)<10 && event[rec].isQuark()) )
4214 allowed = true;
4215
4216 // Never recluster any outgoing partons of the core V -> qqbar' splitting!
4217 if ( mergingHooksPtr->hardProcess.matchesAnyOutgoing(emt,event) )
4218 allowed = false;
4219
4220 // Never allow clustering of any outgoing partons of the hard process
4221 // which would change the flavour of one of the hard process partons!
4222 if ( mergingHooksPtr->hardProcess.matchesAnyOutgoing(rad,event)
4223 && event[rad].id() != radBeforeFlav )
4224 allowed = false;
4225
4226 // If only gluons in initial state and no quarks in final state,
4227 // reject (no electroweak vertex can be formed)
4228 if (nFinalEW != 0 && nInitialQuark == 0
4229 && nFinalQuark == 0 && nFinalQuarkExc == 0)
4230 allowed = false;
4231
4232 if ( (nInitialQuark + nFinalQuark + nFinalQuarkExc)%2 != 0 )
4233 allowed = false;
4234
4235 // Do not allow final state splitting that produces only
4236 // allowed final state gluons, and has a colour-connected initial state
4237 // This means forbidding clusterings that do not allow for a
4238 // t-channel gluon, which is needed to have a quark-antiquark initial state.
4239 // Here, partons excluded from clustering are not counted as possible
4240 // partners to form a t-channel gluon
4241 if (event[3].col() == event[4].acol()
4242 && event[3].acol() == event[4].col()
4243 && nFinalQuark == 0)
4244 allowed = false;
4245
4246 // No problems with gluon radiation
4247 if (event[emt].id() == 21)
4248 return allowed;
4249
4250 // Save all hard process candidates
4251 vector<int> outgoingParticles;
4252 int nOut1 = int(mergingHooksPtr->hardProcess.PosOutgoing1.size());
4253 for ( int i=0; i < nOut1; ++i ) {
4254 int iPos = mergingHooksPtr->hardProcess.PosOutgoing1[i];
4255 outgoingParticles.push_back(
4256 mergingHooksPtr->hardProcess.state[iPos].id() );
4257 }
4258 int nOut2 = int(mergingHooksPtr->hardProcess.PosOutgoing2.size());
4259 for ( int i=0; i < nOut2; ++i ) {
4260 int iPos = mergingHooksPtr->hardProcess.PosOutgoing2[i];
4261 outgoingParticles.push_back(
4262 mergingHooksPtr->hardProcess.state[iPos].id() );
4263 }
4264
4265 // Start more involved checks. g -> q_1 qbar_1 splittings are
4266 // particularly problematic if more than one quark of the emitted
4267 // flavour is present.
4268 // Count number of initial quarks of radiator or emitted flavour
4269 vector<int> iInQuarkFlav;
4270 for(int i=0; i < int(event.size()); ++i)
4271 // Check all initial state partons
4272 if ( i != emt && i != rad
4273 && event[i].status() == -21
4274 && event[i].idAbs() == event[emt].idAbs() )
4275 iInQuarkFlav.push_back(i);
4276
4277 // Count number of final quarks of radiator or emitted flavour
4278 vector<int> iOutQuarkFlav;
4279 for(int i=0; i < int(event.size()); ++i)
4280 // Check all final state partons
4281 if ( i != emt && i != rad
4282 && event[i].isFinal()
4283 && event[i].idAbs() == event[emt].idAbs() ) {
4284
4285 // Loop through final state hard particles. If one matches, remove the
4286 // matching one, and do not count.
4287 bool matchOut = false;
4288 for (int j = 0; j < int(outgoingParticles.size()); ++j)
4289 if ( event[i].idAbs() == abs(outgoingParticles[j])) {
4290 matchOut = true;
4291 outgoingParticles[j] = 99;
4292 }
4293 if (!matchOut) iOutQuarkFlav.push_back(i);
4294
4295 }
4296
4297 // Save number of potentially dangerous quarks
4298 int nInQuarkFlav = int(iInQuarkFlav.size());
4299 int nOutQuarkFlav = int(iOutQuarkFlav.size());
4300
4301 // Easiest problem 0:
4302 // Radiator before splitting exactly matches the partner
4303 // after the splitting
4304 if ( event[partner].isFinal()
4305 && event[partner].id() == 21
4306 && radBeforeFlav == 21
4307 && event[partner].col() == radBeforeCol
4308 && event[partner].acol() == radBeforeAcl)
4309 return false;
4310
4311 // If there are no ambiguities in qqbar pairs, return
4312 if (nInQuarkFlav + nOutQuarkFlav == 0)
4313 return allowed;
4314
4315
4316 // Save all quarks and gluons that will not change colour
4317 vector<int> gluon;
4318 vector<int> quark;
4319 vector<int> antiq;
4320 vector<int> partons;
4321 for(int i=0; i < int(event.size()); ++i)
4322 // Check initial and final state partons
4323 if ( i!=emt && i!=rad
4324 && event[i].colType() != 0
4325 && (event[i].isFinal() || event[i].status() == -21) ) {
4326 // Save index
4327 partons.push_back(i);
4328 // Split into components
4329 if (event[i].colType() == 2)
4330 gluon.push_back(i);
4331 else if (event[i].colType() == 1)
4332 quark.push_back(i);
4333 else if (event[i].colType() == -1)
4334 antiq.push_back(i);
4335 }
4336
4337 // We split up the test of the g->qq splitting into final state
4338 // and initial state problems
4339 bool isFSRg2qq = ((type == 1) && (event[rad].id() == -1*event[emt].id()) );
4340 bool isISRg2qq = ((type ==-1) && (event[rad].id() == event[emt].id()) );
4341
4342 // First check general things about colour connections
4343 // Check that clustering does not produce a gluon that is exactly
4344 // matched in the final state, or does not have any colour connections
4345 if ( (isFSRg2qq || isISRg2qq)
4346 && int(quark.size()) + int(antiq.size())
4347 + int(gluon.size()) > nPartonInHard ) {
4348
4349 vector<int> colours;
4350 vector<int> anticolours;
4351 // Add the colour and anticolour of the gluon before the emission
4352 // to the list, bookkeep initial colour as final anticolour, and
4353 // initial anticolour as final colour
4354 if (type == 1) {
4355 colours.push_back(radBeforeCol);
4356 anticolours.push_back(radBeforeAcl);
4357 } else {
4358 colours.push_back(radBeforeAcl);
4359 anticolours.push_back(radBeforeCol);
4360 }
4361 // Now store gluon colours and anticolours.
4362 for(int i=0; i < int(gluon.size()); ++i)
4363 if (event[gluon[i]].isFinal()) {
4364 colours.push_back(event[gluon[i]].col());
4365 anticolours.push_back(event[gluon[i]].acol());
4366 } else {
4367 colours.push_back(event[gluon[i]].acol());
4368 anticolours.push_back(event[gluon[i]].col());
4369 }
4370
4371 // Loop through colours and check if any match with
4372 // anticolours. If colour matches, remove from list
4373 for(int i=0; i < int(colours.size()); ++i)
4374 for(int j=0; j < int(anticolours.size()); ++j)
4375 if (colours[i] > 0 && anticolours[j] > 0
4376 && colours[i] == anticolours[j]) {
4377 colours[i] = 0;
4378 anticolours[j] = 0;
4379 }
4380
4381
4382 // If all gluon anticolours and all colours matched, disallow
4383 // the clustering
4384 bool allMatched = true;
4385 for(int i=0; i < int(colours.size()); ++i)
4386 if (colours[i] != 0)
4387 allMatched = false;
4388 for(int i=0; i < int(anticolours.size()); ++i)
4389 if (anticolours[i] != 0)
4390 allMatched = false;
4391
4392 if (allMatched)
4393 return false;
4394
4395 // Now add the colours of the hard process, and check if all
4396 // colours match.
4397 for(int i=0; i < int(quark.size()); ++i)
4398 if ( event[quark[i]].isFinal()
4399 && mergingHooksPtr->hardProcess.matchesAnyOutgoing(quark[i], event) )
4400 colours.push_back(event[quark[i]].col());
4401
4402 for(int i=0; i < int(antiq.size()); ++i)
4403 if ( event[antiq[i]].isFinal()
4404 && mergingHooksPtr->hardProcess.matchesAnyOutgoing(antiq[i], event) )
4405 anticolours.push_back(event[antiq[i]].acol());
4406
4407 // Loop through colours again and check if any match with
4408 // anticolours. If colour matches, remove from list
4409 for(int i=0; i < int(colours.size()); ++i)
4410
4411 for(int j=0; j < int(anticolours.size()); ++j)
4412 if (colours[i] > 0 && anticolours[j] > 0
4413 && colours[i] == anticolours[j]) {
4414 colours[i] = 0;
4415 anticolours[j] = 0;
4416 }
4417
4418 // Check if clustering would produce the hard process
4419 int nNotInHard = 0;
4420 for ( int i=0; i < int(quark.size()); ++i )
4421 if ( !mergingHooksPtr->hardProcess.matchesAnyOutgoing( quark[i],
4422 event) )
4423 nNotInHard++;
4424 for ( int i=0; i < int(antiq.size()); ++i )
4425 if ( !mergingHooksPtr->hardProcess.matchesAnyOutgoing( antiq[i],
4426 event) )
4427 nNotInHard++;
4428 for(int i=0; i < int(gluon.size()); ++i)
4429 if ( event[gluon[i]].isFinal() )
4430 nNotInHard++;
4431 if ( type == 1 )
4432 nNotInHard++;
4433
4434 // If all colours are matched now, and since we have more quarks than
4435 // present in the hard process, disallow the clustering
4436 allMatched = true;
4437 for(int i=0; i < int(colours.size()); ++i)
4438 if (colours[i] != 0)
4439 allMatched = false;
4440 for(int i=0; i < int(anticolours.size()); ++i)
4441 if (anticolours[i] != 0)
4442 allMatched = false;
4443
4444 if (allMatched && nNotInHard > 0)
4445 return false;
4446
4447 }
4448
4449 // FSR PROBLEMS
4450
4451 if (isFSRg2qq && nInQuarkFlav + nOutQuarkFlav > 0) {
4452
4453 // Easiest problem 1:
4454 // RECLUSTERED FINAL STATE GLUON MATCHES INITIAL STATE GLUON
4455 for(int i=0; i < int(gluon.size()); ++i) {
4456 if (!event[gluon[i]].isFinal()
4457 && event[gluon[i]].col() == radBeforeCol
4458 && event[gluon[i]].acol() == radBeforeAcl)
4459 return false;
4460 }
4461
4462 // Easiest problem 2:
4463 // RECLUSTERED FINAL STATE GLUON MATCHES FINAL STATE GLUON
4464 for(int i=0; i < int(gluon.size()); ++i) {
4465 if (event[gluon[i]].isFinal()
4466 && event[gluon[i]].col() == radBeforeAcl
4467 && event[gluon[i]].acol() == radBeforeCol)
4468 return false;
4469 }
4470
4471 // Easiest problem 3:
4472 // RECLUSTERED FINAL STATE GLUON MATCHES FINAL STATE Q-QBAR PAIR
4473 if ( int(radBeforeColP.size()) == 2
4474 && event[radBeforeColP[0]].isFinal()
4475 && event[radBeforeColP[1]].isFinal()
4476 && event[radBeforeColP[0]].id() == -1*event[radBeforeColP[1]].id() ) {
4477
4478 // This clustering is allowed if there is no colour in the
4479 // initial state
4480 if (nInitialPartons > 0)
4481 return false;
4482 }
4483
4484 // Next-to-easiest problem 1:
4485 // RECLUSTERED FINAL STATE GLUON MATCHES ONE FINAL STARE Q_1
4486 // AND ONE INITIAL STATE Q_1
4487 if ( int(radBeforeColP.size()) == 2
4488 && (( event[radBeforeColP[0]].status() == -21
4489 && event[radBeforeColP[1]].isFinal())
4490 ||( event[radBeforeColP[0]].isFinal()
4491 && event[radBeforeColP[1]].status() == -21))
4492 && event[radBeforeColP[0]].id() == event[radBeforeColP[1]].id() ) {
4493
4494 // In principle, clustering this splitting can disconnect
4495 // the colour lines of a graph. However, the colours can be connected
4496 // again if a final or initial partons of the correct flavour exists.
4497
4498 // Check which of the partners are final / initial
4499 int incoming = (event[radBeforeColP[0]].isFinal())
4500 ? radBeforeColP[1] : radBeforeColP[0];
4501 int outgoing = (event[radBeforeColP[0]].isFinal())
4502 ? radBeforeColP[0] : radBeforeColP[1];
4503
4504 // Loop through event to find "recovery partons"
4505 bool clusPossible = false;
4506 for(int i=0; i < int(event.size()); ++i)
4507 if ( i != emt && i != rad
4508 && i != incoming && i != outgoing
4509 && !mergingHooksPtr->hardProcess.matchesAnyOutgoing(i,event) ) {
4510 // Check if an incoming parton matches
4511 if ( event[i].status() == -21
4512 && (event[i].id() == event[outgoing].id()
4513 ||event[i].id() == -1*event[incoming].id()) )
4514 clusPossible = true;
4515 // Check if a final parton matches
4516 if ( event[i].isFinal()
4517 && (event[i].id() == -1*event[outgoing].id()
4518 ||event[i].id() == event[incoming].id()) )
4519 clusPossible = true;
4520 }
4521
4522 // There can be a further complication: If e.g. in
4523 // t-channel photon exchange topologies, both incoming
4524 // partons are quarks, and form colour singlets with any
4525 // number of final state partons, at least try to
4526 // recluster as much as possible.
4527 // For this, check if the incoming parton
4528 // connected to the radiator is connected to a
4529 // colour and flavour singlet
4530 vector<int> excludeIn1;
4531 for(int i=0; i < 4; ++i)
4532 excludeIn1.push_back(0);
4533 vector<int> colSingletIn1;
4534 int flavIn1Type = (event[incoming].id() > 0) ? 1 : -1;
4535 // Try finding colour singlets
4536 bool isColSingIn1 = getColSinglet(flavIn1Type,incoming,event,
4537 excludeIn1,colSingletIn1);
4538 // Check if colour singlet also is a flavour singlet
4539 bool isFlavSingIn1 = isFlavSinglet(event,colSingletIn1);
4540
4541 // Check if the incoming parton not
4542 // connected to the radiator is connected to a
4543 // colour and flavour singlet
4544 int incoming2 = (incoming == 3) ? 4 : 3;
4545 vector<int> excludeIn2;
4546 for(int i=0; i < 4; ++i)
4547 excludeIn2.push_back(0);
4548 vector<int> colSingletIn2;
4549 int flavIn2Type = (event[incoming2].id() > 0) ? 1 : -1;
4550 // Try finding colour singlets
4551 bool isColSingIn2 = getColSinglet(flavIn2Type,incoming2,event,
4552 excludeIn2,colSingletIn2);
4553 // Check if colour singlet also is a flavour singlet
4554 bool isFlavSingIn2 = isFlavSinglet(event,colSingletIn2);
4555
4556 // If no "recovery clustering" is possible, reject clustering
4557 if (!clusPossible
4558 && (!isColSingIn1 || !isFlavSingIn1
4559 || !isColSingIn2 || !isFlavSingIn2))
4560 return false;
4561
4562 }
4563
4564 // Next-to-easiest problem 2:
4565 // FINAL STATE Q-QBAR CLUSTERING DISCONNECTS SINGLETT SUBSYSTEM WITH
4566 // FINAL STATE Q-QBAR PAIR FROM GRAPH
4567
4568 // Prepare to check for colour singlet combinations of final state quarks
4569 // Start by building a list of partons to exclude when checking for
4570 // colour singlet combinations
4571 int flav = event[emt].id();
4572 vector<int> exclude;
4573 exclude.push_back(emt);
4574 exclude.push_back(rad);
4575 exclude.push_back(radBeforeColP[0]);
4576 exclude.push_back(radBeforeColP[1]);
4577 vector<int> colSinglet;
4578 // Now find parton from which to start checking colour singlets
4579 int iOther = -1;
4580 // Loop through event to find a parton of correct flavour
4581 for(int i=0; i < int(event.size()); ++i)
4582 // Check final state for parton equalling emitted flavour.
4583 // Exclude the colour system coupled to the clustering
4584 if ( i != emt
4585 && i != rad
4586 && i != radBeforeColP[0]
4587 && i != radBeforeColP[1]
4588 && event[i].isFinal() ) {
4589 // Stop if one parton of the correct flavour is found
4590 if (event[i].id() == flav) {
4591 iOther = i;
4592 break;
4593 }
4594 }
4595 // Save the type of flavour
4596 int flavType = (event[iOther].id() > 0) ? 1 : -1;
4597 // Try finding colour singlets
4598 bool isColSing = getColSinglet(flavType,iOther,event,exclude,colSinglet);
4599 // Check if colour singlet also is a flavour singlet
4600 bool isFlavSing = isFlavSinglet(event,colSinglet);
4601
4602 // Nearly there...
4603 if (isColSing && isFlavSing) {
4604
4605 // In a final check, ensure that the final state does not only
4606 // consist of colour singlets that are also flavour singlets
4607 // of the identical (!) flavours
4608 // Loop through event and save all final state partons
4609 vector<int> allFinal;
4610 for(int i=0; i < int(event.size()); ++i)
4611 if ( event[i].isFinal() )
4612 allFinal.push_back(i);
4613
4614 // Check if all final partons form a colour singlet
4615 bool isFullColSing = isColSinglet(event,allFinal);
4616 // Check if all final partons form a flavour singlet
4617 bool isFullFlavSing = isFlavSinglet(event,allFinal,flav);
4618
4619 // If all final quarks are of identical flavour,
4620 // no possible clustering should be discriminated.
4621 // Otherwise, disallow
4622 if (!isFullColSing || !isFullFlavSing)
4623 return false;
4624 }
4625 }
4626
4627 // ISR PROBLEMS
4628
4629 if (isISRg2qq && nInQuarkFlav + nOutQuarkFlav > 0) {
4630
4631 // Easiest problem 1:
4632 // RECLUSTERED INITIAL STATE GLUON MATCHES FINAL STATE GLUON
4633 for(int i=0; i < int(gluon.size()); ++i) {
4634 if (event[gluon[i]].isFinal()
4635 && event[gluon[i]].col() == radBeforeCol
4636 && event[gluon[i]].acol() == radBeforeAcl)
4637 return false;
4638 }
4639
4640 // Easiest problem 2:
4641 // RECLUSTERED INITIAL STATE GLUON MATCHES INITIAL STATE GLUON
4642 for(int i=0; i < int(gluon.size()); ++i) {
4643 if (event[gluon[i]].status() == -21
4644 && event[gluon[i]].acol() == radBeforeCol
4645 && event[gluon[i]].col() == radBeforeAcl)
4646 return false;
4647 }
4648
4649 // Next-to-easiest problem 1:
4650 // RECLUSTERED INITIAL STATE GLUON MATCHES FINAL STATE Q-QBAR PAIR
4651 if ( int(radBeforeColP.size()) == 2
4652 && event[radBeforeColP[0]].isFinal()
4653 && event[radBeforeColP[1]].isFinal()
4654 && event[radBeforeColP[0]].id() == -1*event[radBeforeColP[1]].id() ) {
4655
4656 // In principle, clustering this splitting can disconnect
4657 // the colour lines of a graph. However, the colours can be connected
4658 // again if final state partons of the correct (anti)flavour, or
4659 // initial state partons of the correct flavour exist
4660 // Loop through event to check
4661 bool clusPossible = false;
4662 for(int i=0; i < int(event.size()); ++i)
4663 if ( i != emt && i != rad
4664 && i != radBeforeColP[0]
4665 && i != radBeforeColP[1]
4666 && !mergingHooksPtr->hardProcess.matchesAnyOutgoing(i,event) ) {
4667 if (event[i].status() == -21
4668 && ( event[radBeforeColP[0]].id() == event[i].id()
4669 || event[radBeforeColP[1]].id() == event[i].id() ))
4670
4671 clusPossible = true;
4672 if (event[i].isFinal()
4673 && ( event[radBeforeColP[0]].id() == -1*event[i].id()
4674 || event[radBeforeColP[1]].id() == -1*event[i].id() ))
4675 clusPossible = true;
4676 }
4677
4678 // There can be a further complication: If e.g. in
4679 // t-channel photon exchange topologies, both incoming
4680 // partons are quarks, and form colour singlets with any
4681 // number of final state partons, at least try to
4682 // recluster as much as possible.
4683 // For this, check if the incoming parton
4684 // connected to the radiator is connected to a
4685 // colour and flavour singlet
4686 int incoming1 = 3;
4687 vector<int> excludeIn1;
4688 for(int i=0; i < 4; ++i)
4689 excludeIn1.push_back(0);
4690 vector<int> colSingletIn1;
4691 int flavIn1Type = (event[incoming1].id() > 0) ? 1 : -1;
4692 // Try finding colour singlets
4693 bool isColSingIn1 = getColSinglet(flavIn1Type,incoming1,event,
4694 excludeIn1,colSingletIn1);
4695 // Check if colour singlet also is a flavour singlet
4696 bool isFlavSingIn1 = isFlavSinglet(event,colSingletIn1);
4697
4698 // Check if the incoming parton not
4699 // connected to the radiator is connected to a
4700 // colour and flavour singlet
4701 int incoming2 = 4;
4702 vector<int> excludeIn2;
4703 for(int i=0; i < 4; ++i)
4704 excludeIn2.push_back(0);
4705 vector<int> colSingletIn2;
4706 int flavIn2Type = (event[incoming2].id() > 0) ? 1 : -1;
4707 // Try finding colour singlets
4708 bool isColSingIn2 = getColSinglet(flavIn2Type,incoming2,event,
4709 excludeIn2,colSingletIn2);
4710 // Check if colour singlet also is a flavour singlet
4711 bool isFlavSingIn2 = isFlavSinglet(event,colSingletIn2);
4712
4713 // If no "recovery clustering" is possible, reject clustering
4714 if (!clusPossible
4715 && (!isColSingIn1 || !isFlavSingIn1
4716 || !isColSingIn2 || !isFlavSingIn2))
4717 return false;
4718
4719 }
4720
4721 }
4722
4723 // Done
4724 return allowed;
4725}
4726
4727//--------------------------------------------------------------------------
4728
4729// Function to check if rad,emt,rec triple is results in
4730// colour singlet radBefore+recBefore
4731// IN int rad,emt,rec : Positions (in event record) of the three
4732
4733// particles considered for clustering
4734// Event event : Reference event
4735
4736bool History::isSinglett( int rad, int emt, int rec, const Event& event ) {
4737
4738 int radCol = event[rad].col();
4739 int emtCol = event[emt].col();
4740 int recCol = event[rec].col();
4741 int radAcl = event[rad].acol();
4742 int emtAcl = event[emt].acol();
4743 int recAcl = event[rec].acol();
4744 int recType = event[rec].isFinal() ? 1 : -1;
4745
4746 bool isSing = false;
4747
4748 if ( ( recType == -1
4749 && radCol + emtCol == recCol && radAcl + emtAcl == recAcl)
4750 ||( recType == 1
4751 && radCol + emtCol == recAcl && radAcl + emtAcl == recCol) )
4752 isSing = true;
4753
4754 return isSing;
4755
4756}
4757
4758//--------------------------------------------------------------------------
4759
4760// Function to check if event is sensibly constructed: Meaning
4761// that all colour indices are contracted and that the charge in
4762// initial and final states matches
4763// IN event : event to be checked
4764// OUT TRUE : event is properly construced
4765// FALSE : event not valid
4766
4767bool History::validEvent( const Event& event ) {
4768
4769 // Check if event is coloured
4770 bool validColour = true;
4771 for ( int i = 0; i < event.size(); ++i)
4772 // Check colour of quarks
4773 if ( event[i].isFinal() && event[i].colType() == 1
4774 // No corresponding anticolour in final state
4775 && ( FindCol(event[i].col(),i,0,event,1,true) == 0
4776 // No corresponding colour in initial state
4777 && FindCol(event[i].col(),i,0,event,2,true) == 0 )) {
4778 validColour = false;
4779 break;
4780 // Check anticolour of antiquarks
4781 } else if ( event[i].isFinal() && event[i].colType() == -1
4782 // No corresponding colour in final state
4783 && ( FindCol(event[i].acol(),i,0,event,2,true) == 0
4784 // No corresponding anticolour in initial state
4785 && FindCol(event[i].acol(),i,0,event,1,true) == 0 )) {
4786 validColour = false;
4787 break;
4788 // No uncontracted colour (anticolour) charge of gluons
4789 } else if ( event[i].isFinal() && event[i].colType() == 2
4790 // No corresponding anticolour in final state
4791 && ( FindCol(event[i].col(),i,0,event,1,true) == 0
4792 // No corresponding colour in initial state
4793 && FindCol(event[i].col(),i,0,event,2,true) == 0 )
4794 // No corresponding colour in final state
4795 && ( FindCol(event[i].acol(),i,0,event,2,true) == 0
4796 // No corresponding anticolour in initial state
4797 && FindCol(event[i].acol(),i,0,event,1,true) == 0 )) {
4798 validColour = false;
4799 break;
4800 }
4801
4802 // Check charge sum in initial and final state
4803 bool validCharge = true;
4804 double initCharge = event[3].charge() + event[4].charge();
4805 double finalCharge = 0.0;
4806 for(int i = 0; i < event.size(); ++i)
4807 if (event[i].isFinal()) finalCharge += event[i].charge();
4808 if (abs(initCharge-finalCharge) > 1e-12) validCharge = false;
4809
4810 return (validColour && validCharge);
4811
4812}
4813
4814//--------------------------------------------------------------------------
4815
4816// Function to check whether two clusterings are identical, used
4817// for finding the history path in the mother -> children direction
4818
4819bool History::equalClustering( Clustering clus1 , Clustering clus2 ) {
4820 return ( (clus1.emittor == clus2.emittor)
4821 && (clus1.emitted == clus2.emitted)
4822 && (clus1.recoiler == clus2.recoiler)
4823 && (clus1.partner == clus2.partner)
4824 && (clus1.pT() == clus2.pT()) );
4825}
4826
4827//--------------------------------------------------------------------------
4828
4829// Chose dummy scale for event construction. By default, choose
4830// sHat for 2->Boson(->2)+ n partons processes and
4831// M_Boson for 2->Boson(->) processes
4832
4833double History::choseHardScale( const Event& event ) const {
4834
4835 // Get sHat
4836 double mHat = (event[3].p() + event[4].p()).mCalc();
4837
4838 // Find number of final state particles and bosons
4839 int nFinal = 0;
4840 int nFinBos= 0;
4841 int nBosons= 0;
4842 double mBos = 0.0;
4843 for(int i = 0; i < event.size(); ++i)
4844 if ( event[i].isFinal() ) {
4845 nFinal++;
4846 // Remember final state unstable bosons
4847 if ( event[i].idAbs() == 23
4848 || event[i].idAbs() == 24 ) {
4849 nFinBos++;
4850 nBosons++;
4851 mBos += event[i].m();
4852 }
4853 } else if ( abs(event[i].status()) == 22
4854 && ( event[i].idAbs() == 23
4855 || event[i].idAbs() == 24 )) {
4856 nBosons++;
4857 mBos += event[i].m(); // Real mass
4858 }
4859
4860 // Return averaged boson masses
4861 if ( nBosons > 0 && (nFinal + nFinBos*2) <= 3)
4862 return (mBos / double(nBosons));
4863 else return
4864 mHat;
4865}
4866
4867//--------------------------------------------------------------------------
4868
4869// If the state has an incoming hadron return the flavour of the
4870// parton entering the hard interaction. Otherwise return 0
4871
4872int History::getCurrentFlav(const int side) const {
4873 int in = (side == 1) ? 3 : 4;
4874 return state[in].id();
4875}
4876
4877//--------------------------------------------------------------------------
4878
4879double History::getCurrentX(const int side) const {
4880 int in = (side == 1) ? 3 : 4;
4881 return ( 2.*state[in].e()/state[0].e() );
4882}
4883
4884//--------------------------------------------------------------------------
4885
4886double History::getCurrentZ(const int rad,
4887 const int rec, const int emt) const {
4888
4889 int type = state[rad].isFinal() ? 1 : -1;
4890 double z = 0.;
4891
4892 if (type == 1) {
4893 // Construct 2->3 variables for FSR
4894 Vec4 sum = state[rad].p() + state[rec].p()
4895 + state[emt].p();
4896 double m2Dip = sum.m2Calc();
4897 double x1 = 2. * (sum * state[rad].p()) / m2Dip;
4898 double x3 = 2. * (sum * state[emt].p()) / m2Dip;
4899 // Calculate z of splitting, different for FSR
4900 z = x1/(x1+x3);
4901 } else {
4902 // Construct momenta of dipole before/after splitting for ISR
4903 Vec4 qBR(state[rad].p() - state[emt].p() + state[rec].p());
4904 Vec4 qAR(state[rad].p() + state[rec].p());
4905 // Calculate z of splitting, different for ISR
4906 z = (qBR.m2Calc())/( qAR.m2Calc());
4907 }
4908
4909 return z;
4910
4911}
4912
4913//--------------------------------------------------------------------------
4914
4915// Function to compute "pythia pT separation" from Particle input
4916
4917double History::pTLund(const Particle& RadAfterBranch,
4918 const Particle& EmtAfterBranch,
4919 const Particle& RecAfterBranch, int ShowerType) {
4920
4921 // Save type: 1 = FSR pT definition, else ISR definition
4922 int Type = ShowerType;
4923 // Calculate virtuality of splitting
4924 int sign = (Type==1) ? 1 : -1;
4925 Vec4 Q(RadAfterBranch.p() + sign*EmtAfterBranch.p());
4926 double Qsq = sign * Q.m2Calc();
4927 // Mass term of radiator
4928 double m2Rad = (mergingHooksPtr->includeMassive()
4929 && RadAfterBranch.idAbs() >= 4
4930 && RadAfterBranch.idAbs() < 7)
4931 ? pow(particleDataPtr->m0(RadAfterBranch.id()), 2)
4932 : 0.;
4933 // Construct 2->3 variables for FSR
4934 Vec4 sum = RadAfterBranch.p() + RecAfterBranch.p()
4935 + EmtAfterBranch.p();
4936 double m2Dip = sum.m2Calc();
4937 double x1 = 2. * (sum * RadAfterBranch.p()) / m2Dip;
4938 double x3 = 2. * (sum * EmtAfterBranch.p()) / m2Dip;
4939 // Construct momenta of dipole before/after splitting for ISR
4940 Vec4 qBR(RadAfterBranch.p() - EmtAfterBranch.p() + RecAfterBranch.p());
4941 Vec4 qAR(RadAfterBranch.p() + RecAfterBranch.p());
4942 // Calculate z of splitting, different for FSR and ISR
4943 double z = (Type==1) ? x1/(x1+x3)
4944 : (qBR.m2Calc())/( qAR.m2Calc());
4945 // Separation of splitting, different for FSR and ISR
4946 double pTpyth = (Type==1) ? z*(1.-z) : (1.-z);
4947 // pT^2 = separation*virtuality
4948 pTpyth *= (Qsq - sign*m2Rad);
4949 if ( pTpyth < 0. ) pTpyth = 0.;
4950
4951 // Return pT
4952 return sqrt(pTpyth);
4953}
4954
4955//--------------------------------------------------------------------------
4956
4957// Function to return the position of the initial line before (or after)
4958// a single (!) splitting.
4959
4960int History::posChangedIncoming(const Event& event, bool before) {
4961
4962 // Check for initial state splittings.
4963 // Consider a splitting to exist if both mother and sister were found.
4964 // Find sister
4965 int iSister = 0;
4966 for (int i =0; i < event.size(); ++i)
4967 if (event[i].status() == 43) {
4968 iSister = i;
4969 break;
4970 }
4971 // Find mother
4972 int iMother = 0;
4973 if (iSister > 0) iMother = event[iSister].mother1();
4974
4975 // Initial state splitting has been found.
4976 if (iSister > 0 && iMother > 0) {
4977
4978 // Find flavour, mother flavour
4979 int flavSister = event[iSister].id();
4980 int flavMother = event[iMother].id();
4981
4982 // Find splitting flavour
4983 int flavDaughter = 0;
4984 if ( abs(flavMother) < 21 && flavSister == 21)
4985 flavDaughter = flavMother;
4986 else if ( flavMother == 21 && flavSister == 21)
4987 flavDaughter = flavMother;
4988 else if ( flavMother == 21 && abs(flavSister) < 21)
4989 flavDaughter = -1*flavSister;
4990 else if ( abs(flavMother) < 21 && abs(flavSister) < 21)
4991 flavDaughter = 21;
4992
4993 // Find initial state (!) daughter
4994 int iDaughter = 0;
4995 for (int i =0; i < event.size(); ++i)
4996 if ( !event[i].isFinal()
4997 && event[i].mother1() == iMother
4998 && event[i].id() == flavDaughter )
4999 iDaughter = i;
5000
5001 // Done for initial state splitting.
5002 if ( !before ) return iMother;
5003 else return iDaughter;
5004
5005 }
5006
5007 // Check for final state splittings with initial state recoiler.
5008 // Consider a splitting to exist if both mother and daughter were found.
5009 // Find new mother
5010 iMother = 0;
5011 for (int i =0; i < event.size(); ++i)
5012 if ( abs(event[i].status()) == 53 || abs(event[i].status()) == 54) {
5013 iMother = i;
5014 break;
5015
5016 }
5017 // Find daughter
5018 int iDaughter = 0;
5019 if (iMother > 0) iDaughter = event[iMother].daughter1();
5020
5021 // Done if final state splitting has been found.
5022 if (iDaughter > 0 && iMother > 0) {
5023
5024 // Done for final state splitting.
5025 if ( !before ) return iMother;
5026 else return iDaughter;
5027
5028 }
5029
5030 // If no splitting has been found, return zero.
5031 return 0;
5032
5033}
5034
5035//==========================================================================
5036
5037} // end namespace Pythia8