StRoot  1
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
MergingHooks.cc
1 // MergingHooks.cc is a part of the PYTHIA event generator.
2 // Copyright (C) 2018 Torbjorn Sjostrand.
3 // PYTHIA is licenced under the GNU GPL v2 or later, see COPYING for details.
4 // Please respect the MCnet Guidelines, see GUIDELINES for details.
5 
6 // This file is written by Stefan Prestel.
7 // Function definitions (not found in the header) for the HardProcess and
8 // MergingHooks classes.
9 
10 #include "Pythia8/MergingHooks.h"
11 #include "Pythia8/PartonLevel.h"
12 
13 namespace Pythia8 {
14 
15 //==========================================================================
16 
17 // The HardProcess class.
18 
19 //--------------------------------------------------------------------------
20 
21 // Declaration of hard process class
22 // This class holds information on the desired hard 2->2 process to be merged
23 // This class is a container class for History class use.
24 
25 // Initialisation on the process string
26 
27 void HardProcess::initOnProcess( string process, ParticleData* particleData) {
28  state.init("(hard process)", particleData);
29  translateProcessString(process);
30 }
31 
32 //--------------------------------------------------------------------------
33 
34 // Initialisation on the path to LHE file
35 
36 void HardProcess::initOnLHEF( string LHEfile, ParticleData* particleData) {
37  state.init("(hard process)", particleData);
38  translateLHEFString(LHEfile);
39 }
40 
41 //--------------------------------------------------------------------------
42 
43 // Function to access the LHE file and read relevant information.
44 // The merging scale will be read from the +1 jet sample, called
45 // LHEpath_1.lhe
46 // while the hard process will be read from
47 // LHEpath_0.lhe
48 // Currently, only read from MadEvent- or Sherpa-generated LHE files
49 // is automatic, else the user is asked to supply the necessary
50 // information.
51 
52 void HardProcess::translateLHEFString( string LHEpath){
53 
54  // Open path to LHEF and extract merging scale
55  ifstream infile;
56  infile.open( (char*)( LHEpath +"_0.lhe").c_str());
57 
58  // Check with ME generator has been used
59  int iLine =0;
60  int nLinesMax = 200;
61  string lineGenerator;
62  while( iLine < nLinesMax
63  && lineGenerator.find("SHERPA", 0) == string::npos
64  && lineGenerator.find("POWHEG-BOX", 0) == string::npos
65  && lineGenerator.find("Pythia8", 0) == string::npos
66  && lineGenerator.find("MadGraph", 0) == string::npos){
67  iLine++;
68  lineGenerator = " ";
69  getline(infile,lineGenerator);
70  }
71  infile.close();
72 
73  vector <int> incom;
74  vector <int> inter;
75  vector <int> outgo;
76  // Particle identifiers, ordered in such a way that e.g. the "u"
77  // in a mu is not mistaken for an u quark
78  int inParticleNumbers[] = {
79  // Leptons
80  -11,11,-12,12,-13,13,-14,14,-15,15,-16,16,
81  // Jet container
82  2212,2212,0,0,0,0,
83  // Quarks
84  -1,1,-2,2,-3,3,-4,4,-5,5,-6,6};
85 
86  string inParticleNamesSH[] = {
87  // Leptons
88  "-11","11","-12","12","-13","13","-14","14","-15","15","-16","16",
89  // Jet container
90  "-93","93","-90","90","-91","91",
91  // Quarks
92  "-1","1","-2","2","-3","3","-4","4","-5","5","-6","6"};
93  string inParticleNamesMG[] = {
94  // Leptons
95  "e+","e-","ve~","ve","mu+","mu-","vm~","vm","ta+","ta-","vt~","vt",
96  // Jet container
97  "p~","p","l+","l-","vl~","vl",
98  // Quarks
99  "d~","d","u~","u","s~","s","c~","c","b~","b","t~","t"};
100 
101  // Declare intermediate particle identifiers
102  int interParticleNumbers[] = {
103  // Electroweak gauge bosons
104  22,23,-24,24,25,2400,
105  // Top quarks
106  -6,6,
107  // Dummy index as back-up
108  0,
109  // All squarks
110  -1000001,1000001,-1000002,1000002,-1000003,1000003,-1000004,1000004,
111  -1000005,1000005,-1000006,1000006,-2000001,2000001,-2000002,2000002,
112  -2000003,2000003,-2000004,2000004,-2000005,2000005,-2000006,2000006};
113  // Declare names of intermediate particles
114  string interParticleNamesMG[] = {
115  // Electroweak gauge bosons
116  "a","z","w-","w+","h","W",
117  // Top quarks
118  "t~","t",
119  // Dummy index as back-up
120  "xx",
121  // All squarks
122  "dl~","dl","ul~","ul","sl~","sl","cl~","cl","b1~","b1","t1~","t1",
123  "dr~","dr","ur~","ur","sr~","sr","cr~","cr","b2~","b2","t2~","t2"};
124 
125  // Declare final state particle identifiers
126  int outParticleNumbers[] = {
127  // Leptons
128  -11,11,-12,12,-13,13,-14,14,-15,15,-16,16,
129  // Jet container and lepton containers
130  2212,2212,0,0,0,0,1200,1100,5000,
131  // Quarks
132  -1,1,-2,2,-3,3,-4,4,-5,5,-6,6,
133  // SM uncoloured bosons
134  22,23,-24,24,25,2400,
135  // Neutralino in SUSY
136  1000022,
137  // All squarks
138  -1000001,1000001,-1000002,1000002,-1000003,1000003,-1000004,1000004,
139  -1000005,1000005,-1000006,1000006,-2000001,2000001,-2000002,2000002,
140  -2000003,2000003,-2000004,2000004,-2000005,2000005,-2000006,2000006};
141  // Declare names of final state particles
142  string outParticleNamesMG[] = {
143  // Leptons
144  "e+","e-","ve~","ve","mu+","mu-","vm~","vm","ta+","ta-","vt~","vt",
145  // Jet container and lepton containers
146  "j~","j","l+","l-","vl~","vl","NEUTRINOS","LEPTONS","BQUARKS",
147  // Quarks
148  "d~","d","u~","u","s~","s","c~","c","b~","b","t~","t",
149  // SM uncoloured bosons
150  "a","z","w-","w+","h","W",
151  // Neutralino in SUSY
152  "n1",
153  // All squarks
154  "dl~","dl","ul~","ul","sl~","sl","cl~","cl","b1~","b1","t1~","t1",
155  "dr~","dr","ur~","ur","sr~","sr","cr~","cr","b2~","b2","t2~","t2"};
156 
157  string outParticleNamesSH[] = {
158  // Leptons
159  "-11","11","-12","12","-13","13","-14","14","-15","15","-16","16",
160  // Jet container and lepton containers
161  "-93","93","-90","90","-91","91","0","0","0",
162  // Quarks
163  "-1","1","-2","2","-3","3","-4","4","-5","5","-6","6",
164  // SM uncoloured bosons
165  "22","23","-24","24","25","0",
166  // Neutralino in SUSY
167  "1000022",
168  // All squarks
169  "-1000001","1000001","-1000002","1000002","-1000003","1000003",
170  "-1000004","1000004",
171  "-1000005","1000005","-1000006","1000006","-2000001","2000001",
172  "-2000002","2000002",
173  "-2000003","2000003","-2000004","2000004","-2000005","2000005",
174  "-2000006","2000006"};
175 
176  // Declare size of particle name arrays
177  int nIn = 30;
178  int nInt = 33;
179  int nOut = 64;
180 
181  // Save type of the generator, in order to be able to extract
182  // the tms definition
183  int meGenType = (lineGenerator.find("MadGraph", 0) != string::npos) ? -1
184  : (lineGenerator.find("SHERPA", 0) != string::npos) ? -2
185  : (lineGenerator.find("POWHEG-BOX", 0) != string::npos) ? -3
186  : (lineGenerator.find("Pythia8", 0) != string::npos) ? -4
187  : 0;
188 
189  if (meGenType == -2){
190  // Now read merging scale
191  // Open path to LHEF and extract merging scale
192  infile.open( (char*)( LHEpath +"_1.lhe").c_str());
193  string lineTMS;
194  while(lineTMS.find("NJetFinder ", 0) == string::npos){
195  lineTMS = " ";
196  getline(infile,lineTMS);
197  }
198  infile.close();
199  lineTMS = lineTMS.substr(0,lineTMS.find(" 0.0 ",0));
200  lineTMS = lineTMS.substr(lineTMS.find(" ", 0)+3,lineTMS.size());
201  // Remove whitespaces
202  while(lineTMS.find(" ", 0) != string::npos)
203  lineTMS.erase(lineTMS.begin()+lineTMS.find(" ",0));
204  // Replace d with e
205  if ( lineTMS.find("d", 0) != string::npos)
206  lineTMS.replace(lineTMS.find("d", 0),1,1,'e');
207  tms = atof((char*)lineTMS.c_str());
208 
209  // Now read hard process
210  // Open path to LHEF and extract hard process
211  infile.open( (char*)( LHEpath +"_0.lhe").c_str());
212  string line;
213  while(line.find("Process", 0) == string::npos){
214  line = " ";
215  getline(infile,line);
216  }
217  infile.close();
218  line = line.substr(line.find(" ",0),line.size());
219 
220  // Cut string into incoming and outgoing pieces
221  vector <string> pieces;
222  pieces.push_back( line.substr(0,line.find("->", 0)) );
223  // Do not count additional final jets
224  int end = (line.find("{", 0) != string::npos) ? line.find("{", 0)-2
225  : line.size();
226  pieces.push_back( line.substr(line.find("->", 0)+2, end) );
227 
228  // Get incoming particles
229  for(int i=0; i < nIn; ++i) {
230  for(int n = pieces[0].find(inParticleNamesSH[i], 0);
231  n != int(string::npos);
232  n = pieces[0].find(inParticleNamesSH[i], n)) {
233  incom.push_back(inParticleNumbers[i]);
234  pieces[0].erase(pieces[0].begin()+n,
235  pieces[0].begin()+n+inParticleNamesSH[i].size());
236  n=0;
237  }
238  }
239  // Get intermediate particles
240  // If intermediates are still empty, fill intermediate with default value
241  inter.push_back(0);
242  // Get final particles
243  for(int i=0; i < nOut; ++i) {
244  for(int n = pieces[1].find(outParticleNamesSH[i], 0);
245  n != int(string::npos);
246  n = pieces[1].find(outParticleNamesSH[i], n)) {
247  outgo.push_back(outParticleNumbers[i]);
248  pieces[1].erase(pieces[1].begin()+n,
249  pieces[1].begin()+n+outParticleNamesSH[i].size());
250  n=0;
251  }
252  }
253 
254  } else if (meGenType == -1 || meGenType == -3 || meGenType == -4){
255 
256  // Now read merging scale
257  string lineTMS;
258 
259  if (meGenType == -1) {
260  // Open path to LHEF and extract merging scale
261  infile.open( (char*)( LHEpath +"_1.lhe").c_str());
262  while(lineTMS.find("ktdurham", 0) == string::npos){
263  lineTMS = " ";
264  getline(infile,lineTMS);
265  }
266  lineTMS = lineTMS.substr(0,lineTMS.find("=",0));
267  infile.close();
268  } else {
269  lineTMS = "30.";
270  }
271 
272  // Remove whitespaces
273  while(lineTMS.find(" ", 0) != string::npos)
274  lineTMS.erase(lineTMS.begin()+lineTMS.find(" ",0));
275  // Replace d with e
276  if ( lineTMS.find("d", 0) != string::npos)
277  lineTMS.replace(lineTMS.find("d", 0),1,1,'e');
278  tms = atof((char*)lineTMS.c_str());
279 
280  // Now read hard process
281  // Open path to LHEF and extract hard process
282  infile.open( (char*)( LHEpath +"_0.lhe").c_str());
283  string line;
284  while(line.find("@1", 0) == string::npos){
285  line = " ";
286  getline(infile,line);
287  }
288  infile.close();
289  line = line.substr(0,line.find("@",0));
290 
291  // Count number of resonances
292  int appearances = 0;
293  for(int n = line.find("(", 0); n != int(string::npos);
294  n = line.find("(", n)) {
295  appearances++;
296  n++;
297  }
298 
299  // Cut string in incoming, resonance+decay and outgoing pieces
300  vector <string> pieces;
301  for(int i =0; i < appearances;++i) {
302  int n = line.find("(", 0);
303  pieces.push_back(line.substr(0,n));
304  line = line.substr(n+1,line.size());
305  }
306  // Cut last resonance from rest
307  if (appearances > 0) {
308  pieces.push_back( line.substr(0,line.find(")",0)) );
309  pieces.push_back( line.substr(line.find(")",0)+1,line.size()) );
310  }
311 
312  // If the string was not cut into pieces, i.e. no resonance was
313  // required, cut string using '>' as delimiter
314  if (pieces.empty() ){
315  appearances = 0;
316  for(int n = line.find(">", 0); n != int(string::npos);
317  n = line.find(">", n)) {
318  appearances++;
319  n++;
320  }
321 
322  // Cut string in incoming and outgoing pieces
323  for(int i =0; i < appearances;++i) {
324  int n = line.find(">", 0);
325  pieces.push_back(line.substr(0,n));
326  line = line.substr(n+1,line.size());
327  }
328 
329  if (appearances == 1) pieces.push_back(line);
330  if (appearances > 1) {
331  pieces.push_back( line.substr(0,line.find(">",0)) );
332  pieces.push_back( line.substr(line.find(">",0)+1,line.size()) );
333  }
334  }
335 
336  // Get incoming particles
337  for(int i=0; i < nIn; ++i) {
338  for(int n = pieces[0].find(inParticleNamesMG[i], 0);
339  n != int(string::npos);
340  n = pieces[0].find(inParticleNamesMG[i], n)) {
341  incom.push_back(inParticleNumbers[i]);
342  pieces[0].erase(pieces[0].begin()+n,
343  pieces[0].begin()+n+inParticleNamesMG[i].size());
344  n=0;
345  }
346  }
347 
348  // Check intermediate resonances and decay products
349  for(int i =1; i < int(pieces.size()); ++i){
350  // Seperate strings into intermediate and outgoing, if not already done
351  int k = pieces[i].find(">", 0);
352 
353  string intermediate = (pieces[i].find(">", 0) != string::npos) ?
354  pieces[i].substr(0,k) : "";
355  string outgoing = (pieces[i].find(">", 0) != string::npos) ?
356  pieces[i].substr(k+1,pieces[i].size()) : pieces[i];
357 
358  // Get intermediate particles
359  for(int j=0; j < nInt; ++j) {
360  for(int n = intermediate.find(interParticleNamesMG[j], 0);
361  n != int(string::npos);
362  n = intermediate.find(interParticleNamesMG[j], n)) {
363  inter.push_back(interParticleNumbers[j]);
364  intermediate.erase(intermediate.begin()+n,
365  intermediate.begin()+n+interParticleNamesMG[j].size());
366  n=0;
367  }
368  }
369 
370  // Get outgoing particles
371  for(int j=0; j < nOut; ++j) {
372  for(int n = outgoing.find(outParticleNamesMG[j], 0);
373  n != int(string::npos);
374  n = outgoing.find(outParticleNamesMG[j], n)) {
375  outgo.push_back(outParticleNumbers[j]);
376  outgoing.erase(outgoing.begin()+n,
377  outgoing.begin()+n+outParticleNamesMG[j].size());
378  n=0;
379  }
380  }
381 
382  // For arbitrary or non-existing intermediate, remember zero for each
383  // two outgoing particles, without bosons.
384  if (inter.empty()) {
385 
386  // For final state bosons, bookkeep the final state boson as
387  // intermediate as well.
388  int nBosons = 0;
389  for(int l=0; l < int(outgo.size()); ++l)
390  if ( (abs(outgo[l]) > 20 && abs(outgo[l]) <= 25) || outgo[l] == 2400)
391  nBosons++;
392 
393  int nZeros = (outgo.size() - nBosons)/2;
394  for(int l=0; l < nZeros; ++l)
395  inter.push_back(0);
396  }
397 
398  // For final state bosons, bookkeep the final state boson as
399  // intermediate as well.
400  for(int l=0; l < int(outgo.size()); ++l)
401  if ( (abs(outgo[l]) > 20 && abs(outgo[l]) <= 25) || outgo[l] == 2400)
402  inter.push_back(outgo[l]);
403 
404  }
405 
406  } else {
407 
408  cout << "Reading of tms and hard process information from LHEF currently"
409  << " only automated for MadEvent- or SHERPA-produced LHEF" << endl;
410  int tempInt = 0;
411  cout << "Use default process pp -> e+ve + jets? (0:no / 1:yes): ";
412  cin >> tempInt;
413  cout << endl;
414 
415  if (tempInt == 0){
416  tempInt = 0;
417  double tempDouble = 0.0;
418  cout << "Please specify merging scale (kT Durham, in GeV): ";
419  cin >> tempDouble;
420  tms = tempDouble;
421  cout << endl;
422  cout << "Please specify first incoming particle ";
423  cout << "(p+/p- = 2212, e- = 11, e+ = -11): ";
424  cin >> tempInt;
425  incom.push_back(tempInt);
426  tempInt = 0;
427  cout << endl;
428  cout << "Please specify second incoming particle ";
429  cout << "(p+/p- = 2212, e- = 11, e+ = -11): ";
430  cin >> tempInt;
431  incom.push_back(tempInt);
432  tempInt = 0;
433  cout << endl;
434  cout << "Please specify intermediate particle, if any ";
435  cout << "(0 for none, else PDG code): ";
436  cin >> tempInt;
437  inter.push_back(tempInt);
438  cout << endl;
439  do {
440  tempInt = 0;
441  cout << "Please specify outgoing particle ";
442  cout << "(jet=2212, else PDG code, exit with 99): ";
443  cin >> tempInt;
444  if (tempInt != 99) outgo.push_back(tempInt);
445  } while(tempInt != 99);
446  cout << endl;
447  } else {
448  cout << "LHE file not produced by SHERPA or MG/ME - ";
449  cout << "Using default process and tms" << endl;
450  incom.push_back(2212);
451  incom.push_back(2212);
452  inter.push_back(24);
453  outgo.push_back(-11);
454  outgo.push_back(12);
455  tms = 10.;
456  }
457  }
458 
459  // Now store incoming, intermediate and outgoing
460  // Set intermediate tags
461  for(int i=0; i < int(inter.size()); ++i)
462  hardIntermediate.push_back(inter[i]);
463 
464  // Set the incoming particle tags
465  if (incom.size() != 2)
466  cout << "Only two incoming particles allowed" << endl;
467  else {
468  hardIncoming1 = incom[0];
469  hardIncoming2 = incom[1];
470  }
471 
472  // Remember final state bosons
473  int nBosons = 0;
474  for(int i=0; i < int(outgo.size()); ++i)
475  if ( (abs(outgo[i]) > 20 && abs(outgo[i]) <= 25) || outgo[i] == 2400)
476  nBosons++;
477  // Remember b-quark container
478  int nBQuarks = 0;
479  for(int i=0; i < int(outgo.size()); ++i)
480  if ( outgo[i] == 5000)
481  nBQuarks++;
482  // Remember jet container
483  int nJets = 0;
484  for(int i=0; i < int(outgo.size()); ++i)
485  if ( outgo[i] == 2212)
486  nJets++;
487  // Remember lepton container
488  int nLeptons = 0;
489  for(int i=0; i < int(outgo.size()); ++i)
490  if ( outgo[i] == 1100)
491  nLeptons++;
492  // Remember lepton container
493  int nNeutrinos = 0;
494  for(int i=0; i < int(outgo.size()); ++i)
495  if ( outgo[i] == 1200)
496  nNeutrinos++;
497  int nContainers = nLeptons + nNeutrinos + nJets + nBQuarks;
498 
499  // Set final particle identifiers
500  if ( (outgo.size() - nBosons - nContainers)%2 == 1) {
501  cout << "Only even number of outgoing particles allowed" << endl;
502  for(int i=0; i < int(outgo.size()); ++i)
503  cout << outgo[i] << endl;
504  } else {
505 
506  // Push back particles / antiparticles
507  for(int i=0; i < int(outgo.size()); ++i)
508  if (outgo[i] > 0
509  && outgo[i] != 2212
510  && outgo[i] != 5000
511  && outgo[i] != 1100
512  && outgo[i] != 1200
513  && outgo[i] != 2400
514  && outgo[i] != 1000022)
515  hardOutgoing2.push_back( outgo[i]);
516  else if (outgo[i] < 0)
517  hardOutgoing1.push_back( outgo[i]);
518 
519  // Save final state W-boson container as particle
520  for(int i=0; i < int(outgo.size()); ++i)
521  if ( outgo[i] == 2400)
522  hardOutgoing2.push_back( outgo[i]);
523 
524  // Push back jets, distribute evenly amongst particles / antiparticles
525  // Push back majorana particles, distribute evenly
526  int iNow = 0;
527  for(int i=0; i < int(outgo.size()); ++i)
528  if ( (outgo[i] == 2212
529  || outgo[i] == 5000
530  || outgo[i] == 1200
531  || outgo[i] == 1000022)
532  && iNow%2 == 0 ){
533  hardOutgoing2.push_back( outgo[i]);
534  iNow++;
535  } else if ( (outgo[i] == 2212
536  || outgo[i] == 5000
537  || outgo[i] == 1100
538  || outgo[i] == 1000022)
539  && iNow%2 == 1 ){
540  hardOutgoing1.push_back( outgo[i]);
541  iNow++;
542  }
543  }
544 
545  // Done
546 }
547 
548 //--------------------------------------------------------------------------
549 
550 // Function to translate a string specitying the core process into the
551 // internal notation
552 // Currently, the input string has to be in MadEvent notation
553 
554 void HardProcess::translateProcessString( string process){
555 
556  vector <int> incom;
557  vector <int> inter;
558  vector <int> outgo;
559  // Particle identifiers, ordered in such a way that e.g. the "u"
560  // in a mu is not mistaken for an u quark
561  int inParticleNumbers[] = {
562  // Leptons
563  -11,11,-12,12,-13,13,-14,14,-15,15,-16,16,
564  // Jet container
565  2212,2212,0,0,0,0,
566  // Quarks
567  -1,1,-2,2,-3,3,-4,4,-5,5,-6,6};
568  string inParticleNamesMG[] = {
569  // Leptons
570  "e+","e-","ve~","ve","mu+","mu-","vm~","vm","ta+","ta-","vt~","vt",
571  // Jet container
572  "p~","p","l+","l-","vl~","vl",
573  // Quarks
574  "d~","d","u~","u","s~","s","c~","c","b~","b","t~","t"};
575 
576  // Declare intermediate particle identifiers
577  int interParticleNumbers[] = {
578  // Electroweak gauge bosons
579  22,23,-24,24,25,2400,
580  // All squarks
581  -1000001,1000001,-1000002,1000002,-1000003,1000003,-1000004,1000004,
582  -1000005,1000005,-1000006,1000006,-2000001,2000001,-2000002,2000002,
583  -2000003,2000003,-2000004,2000004,-2000005,2000005,-2000006,2000006,
584  // Top quarks
585  -6,6,
586  // Dummy index as back-up
587  0};
588  // Declare names of intermediate particles
589  string interParticleNamesMG[] = {
590  // Electroweak gauge bosons
591  "a","z","w-","w+","h","W",
592  // All squarks
593  "dl~","dl","ul~","ul","sl~","sl","cl~","cl","b1~","b1","t1~","t1",
594  "dr~","dr","ur~","ur","sr~","sr","cr~","cr","b2~","b2","t2~","t2",
595  // Top quarks
596  "t~","t",
597  // Dummy index as back-up
598  "xx"};
599 
600  // Declare final state particle identifiers
601  int outParticleNumbers[] = {
602  // Leptons
603  -11,11,-12,12,-13,13,-14,14,-15,15,-16,16,
604  // Jet container and lepton containers
605  2212,2212,0,0,0,0,1200,1100,5000,
606  // Containers for inclusive handling for weak bosons and jets
607  10000022,10000023,10000024,10002212,
608  // All squarks
609  -1000001,1000001,-1000002,1000002,-1000003,1000003,-1000004,1000004,
610  -1000005,1000005,-1000006,1000006,-2000001,2000001,-2000002,2000002,
611  -2000003,2000003,-2000004,2000004,-2000005,2000005,-2000006,2000006,
612  // Quarks
613  -1,1,-2,2,-3,3,-4,4,-5,5,-6,6,
614  // SM uncoloured bosons
615  22,23,-24,24,25,2400,
616  // Neutralino in SUSY
617  1000022};
618  // Declare names of final state particles
619  string outParticleNamesMG[] = {
620  // Leptons
621  "e+","e-","ve~","ve","mu+","mu-","vm~","vm","ta+","ta-","vt~","vt",
622  // Jet container and lepton containers
623  "j~","j","l+","l-","vl~","vl","NEUTRINOS","LEPTONS","BQUARKS",
624  // Containers for inclusive handling for weak bosons and jets
625  "Ainc","Zinc","Winc","Jinc",
626  // All squarks
627  "dl~","dl","ul~","ul","sl~","sl","cl~","cl","b1~","b1","t1~","t1",
628  "dr~","dr","ur~","ur","sr~","sr","cr~","cr","b2~","b2","t2~","t2",
629  // Quarks
630  "d~","d","u~","u","s~","s","c~","c","b~","b","t~","t",
631  // SM uncoloured bosons
632  "a","z","w-","w+","h","W",
633  // Neutralino in SUSY
634  "n1"};
635 
636  // Declare size of particle name arrays
637  int nIn = 30;
638  int nInt = 33;
639  int nOut = 68;
640 
641  // Start mapping user-defined particles onto particle ids.
642  string fullProc = process;
643 
644  // Remove whitespaces
645  while(fullProc.find(" ", 0) != string::npos)
646  fullProc.erase(fullProc.begin()+fullProc.find(" ",0));
647 
648  // Find user-defined hard process content
649  // Count number of user particles
650  int nUserParticles = 0;
651  for(int n = fullProc.find("{", 0); n != int(string::npos);
652  n = fullProc.find("{", n)) {
653  nUserParticles++;
654  n++;
655  }
656 
657  // Cut user-defined particles from remaining process
658  vector <string> userParticleStrings;
659  for(int i =0; i < nUserParticles;++i) {
660  int n = fullProc.find("{", 0);
661  userParticleStrings.push_back(fullProc.substr(0,n));
662  fullProc = fullProc.substr(n+1,fullProc.size());
663  }
664 
665  // Cut remaining process string from rest
666  if (nUserParticles > 0)
667  userParticleStrings.push_back(
668  fullProc.substr( 0, fullProc.find("}",0) ) );
669  // Remove curly brackets and whitespace
670  for(int i =0; i < int(userParticleStrings.size());++i) {
671  while(userParticleStrings[i].find("{", 0) != string::npos)
672  userParticleStrings[i].erase(userParticleStrings[i].begin()
673  +userParticleStrings[i].find("{", 0));
674  while(userParticleStrings[i].find("}", 0) != string::npos)
675  userParticleStrings[i].erase(userParticleStrings[i].begin()
676  +userParticleStrings[i].find("}", 0));
677  while(userParticleStrings[i].find(" ", 0) != string::npos)
678  userParticleStrings[i].erase(userParticleStrings[i].begin()
679  +userParticleStrings[i].find(" ", 0));
680  }
681 
682  // Convert particle numbers in user particle to integers
683  vector<int>userParticleNumbers;
684  if ( int(userParticleStrings.size()) > 1) {
685  for( int i = 1; i < int(userParticleStrings.size()); ++i) {
686  userParticleNumbers.push_back(
687  atoi((char*)userParticleStrings[i].substr(
688  userParticleStrings[i].find(",",0)+1,
689  userParticleStrings[i].size()).c_str() ) );
690  }
691  }
692 
693  // Save remaining process string
694  if (nUserParticles > 0)
695  userParticleStrings.push_back(
696  fullProc.substr(
697  fullProc.find("}",0)+1, fullProc.size() ) );
698  // Remove curly brackets and whitespace
699  for( int i = 0; i < int(userParticleStrings.size()); ++i) {
700  while(userParticleStrings[i].find("{", 0) != string::npos)
701  userParticleStrings[i].erase(userParticleStrings[i].begin()
702  +userParticleStrings[i].find("{", 0));
703  while(userParticleStrings[i].find("}", 0) != string::npos)
704  userParticleStrings[i].erase(userParticleStrings[i].begin()
705  +userParticleStrings[i].find("}", 0));
706  while(userParticleStrings[i].find(" ", 0) != string::npos)
707  userParticleStrings[i].erase(userParticleStrings[i].begin()
708  +userParticleStrings[i].find(" ", 0));
709  }
710 
711  // Start mapping residual process string onto particle IDs.
712  // Declare leftover process after user-defined particles have been converted
713  string residualProc;
714  if ( int(userParticleStrings.size()) > 1 )
715  residualProc = userParticleStrings.front() + userParticleStrings.back();
716  else
717  residualProc = fullProc;
718 
719  // Remove comma separation
720  while(residualProc.find(",", 0) != string::npos)
721  residualProc.erase(residualProc.begin()+residualProc.find(",",0));
722 
723  // Count number of resonances
724  int appearances = 0;
725  for(int n = residualProc.find("(", 0); n != int(string::npos);
726  n = residualProc.find("(", n)) {
727  appearances++;
728  n++;
729  }
730 
731  // Cut string in incoming, resonance+decay and outgoing pieces
732  vector <string> pieces;
733  for(int i =0; i < appearances;++i) {
734  int n = residualProc.find("(", 0);
735  pieces.push_back(residualProc.substr(0,n));
736  residualProc = residualProc.substr(n+1,residualProc.size());
737  }
738 
739  // Cut last resonance from rest
740  if (appearances > 0) {
741  pieces.push_back( residualProc.substr(0,residualProc.find(")",0)) );
742  pieces.push_back( residualProc.substr(
743  residualProc.find(")",0)+1, residualProc.size()) );
744  }
745 
746  // If the string was not cut into pieces, i.e. no resonance was
747  // required, cut string using '>' as delimiter
748  if (pieces.empty() ){
749  appearances = 0;
750  for(int n = residualProc.find(">", 0); n != int(string::npos);
751  n = residualProc.find(">", n)) {
752  appearances++;
753  n++;
754  }
755 
756  // Cut string in incoming and outgoing pieces
757  for(int i =0; i < appearances;++i) {
758  int n = residualProc.find(">", 0);
759  pieces.push_back(residualProc.substr(0,n));
760  residualProc = residualProc.substr(n+1,residualProc.size());
761  }
762 
763  if (appearances == 1) pieces.push_back(residualProc);
764  if (appearances > 1) {
765  pieces.push_back( residualProc.substr(0,residualProc.find(">",0)) );
766  pieces.push_back( residualProc.substr(
767  residualProc.find(">",0)+1, residualProc.size()) );
768  }
769  }
770 
771  // Get incoming particles
772  for(int i=0; i < nIn; ++i) {
773  for(int n = pieces[0].find(inParticleNamesMG[i], 0);
774  n != int(string::npos);
775  n = pieces[0].find(inParticleNamesMG[i], n)) {
776  incom.push_back(inParticleNumbers[i]);
777  pieces[0].erase(pieces[0].begin()+n,
778  pieces[0].begin()+n+inParticleNamesMG[i].size());
779  n=0;
780  }
781  }
782 
783  // Check intermediate resonances and decay products
784  for(int i =1; i < int(pieces.size()); ++i){
785  // Seperate strings into intermediate and outgoing, if not already done
786  int k = pieces[i].find(">", 0);
787 
788  string intermediate = (pieces[i].find(">", 0) != string::npos) ?
789  pieces[i].substr(0,k) : "";
790  string outgoing = (pieces[i].find(">", 0) != string::npos) ?
791  pieces[i].substr(k+1,pieces[i].size()) : pieces[i];
792 
793  // Get intermediate particles
794  for(int j=0; j < nInt; ++j) {
795  for(int n = intermediate.find(interParticleNamesMG[j], 0);
796  n != int(string::npos);
797  n = intermediate.find(interParticleNamesMG[j], n)) {
798  inter.push_back(interParticleNumbers[j]);
799  intermediate.erase(intermediate.begin()+n,
800  intermediate.begin()+n+interParticleNamesMG[j].size());
801  n=0;
802  }
803  }
804 
805  // Get outgoing particles
806  for(int j=0; j < nOut; ++j) {
807  for(int n = outgoing.find(outParticleNamesMG[j], 0);
808  n != int(string::npos);
809  n = outgoing.find(outParticleNamesMG[j], n)) {
810  outgo.push_back(outParticleNumbers[j]);
811  outgoing.erase(outgoing.begin()+n,
812  outgoing.begin()+n+outParticleNamesMG[j].size());
813  n=0;
814  }
815  }
816 
817  // For arbitrary or non-existing intermediate, remember zero for each
818  // two outgoing particles, without bosons.
819  if (inter.empty()) {
820 
821  // For final state bosons, bookkeep the final state boson as
822  // intermediate as well.
823  int nBosons = 0;
824  for(int l=0; l < int(outgo.size()); ++l)
825  if ( (abs(outgo[l]) > 20 && abs(outgo[l]) <= 25) || outgo[l] == 2400)
826  nBosons++;
827 
828  int nZeros = (outgo.size() - nBosons)/2;
829  for(int l=0; l < nZeros; ++l)
830  inter.push_back(0);
831  }
832 
833  // For final state bosons, bookkeep the final state boson as
834  // intermediate as well.
835  for(int l=0; l < int(outgo.size()); ++l)
836  if ( (abs(outgo[l]) > 20 && abs(outgo[l]) <= 25) || outgo[l] == 2400)
837  inter.push_back(outgo[l]);
838 
839  }
840 
841  // Now store incoming, intermediate and outgoing
842  // Set intermediate tags
843  for(int i=0; i < int(inter.size()); ++i)
844  hardIntermediate.push_back(inter[i]);
845 
846  // Set the incoming particle tags
847  if (incom.size() != 2)
848  cout << "Only two incoming particles allowed" << endl;
849  else {
850  hardIncoming1 = incom[0];
851  hardIncoming2 = incom[1];
852  }
853 
854  // Now store final particle identifiers
855  // Start with user-defined particles.
856  for( int i = 0; i < int(userParticleNumbers.size()); ++i)
857  if (userParticleNumbers[i] > 0) {
858  hardOutgoing2.push_back( userParticleNumbers[i]);
859  hardIntermediate.push_back(0);
860  // For non-existing intermediate, remember zero.
861  } else if (userParticleNumbers[i] < 0) {
862  hardOutgoing1.push_back( userParticleNumbers[i]);
863  // For non-existing intermediate, remember zero.
864  hardIntermediate.push_back(0);
865  }
866 
867  // Push back particles / antiparticles
868  for(int i=0; i < int(outgo.size()); ++i)
869  if (outgo[i] > 0
870  && outgo[i] != 2212
871  && outgo[i] != 5000
872  && outgo[i] != 1100
873  && outgo[i] != 1200
874  && outgo[i] != 2400
875  && outgo[i] != 1000022
876  && outgo[i] < 10000000)
877  hardOutgoing2.push_back( outgo[i]);
878  else if (outgo[i] < 0)
879  hardOutgoing1.push_back( outgo[i]);
880 
881  // Save final state W-boson container as particle
882  for(int i=0; i < int(outgo.size()); ++i)
883  if ( outgo[i] == 2400)
884  hardOutgoing2.push_back( outgo[i]);
885 
886  // Push back jets, distribute evenly among particles / antiparticles
887  // Push back majorana particles, distribute evenly
888  int iNow = 0;
889  for(int i=0; i < int(outgo.size()); ++i)
890  if ( (outgo[i] == 2212
891  || outgo[i] == 5000
892  || outgo[i] == 1200
893  || outgo[i] == 1000022
894  || outgo[i] > 10000000)
895  && iNow%2 == 0 ){
896  hardOutgoing2.push_back( outgo[i]);
897  iNow++;
898  } else if ( (outgo[i] == 2212
899  || outgo[i] == 5000
900  || outgo[i] == 1100
901  || outgo[i] == 1000022
902  || outgo[i] > 10000000)
903  && iNow%2 == 1 ){
904  hardOutgoing1.push_back( outgo[i]);
905  iNow++;
906  }
907 
908  // Done
909 }
910 
911 //--------------------------------------------------------------------------
912 
913 // Function to check if the candidates stored in Pos1 and Pos2, together with
914 // a proposed candidate iPos are allowed.
915 
916 bool HardProcess::allowCandidates(int iPos, vector<int> Pos1,
917  vector<int> Pos2, const Event& event){
918 
919  bool allowed = true;
920 
921  // Find colour-partner of new candidate
922  int type = (event[iPos].col() > 0) ? 1 : (event[iPos].acol() > 0) ? -1 : 0;
923 
924  if (type == 0) return true;
925 
926  if (type == 1){
927  int col = event[iPos].col();
928  int iPartner = 0;
929  for(int i=0; i < int(event.size()); ++i)
930  if ( i != iPos
931  && (( event[i].isFinal() && event[i].acol() == col)
932  ||( event[i].status() == -21 && event[i].col() == col) ))
933  iPartner = i;
934 
935  vector<int> partners;
936  for(int i=0; i < int(event.size()); ++i)
937  for(int j=0; j < int(Pos1.size()); ++j)
938  if ( Pos1[j] != 0 && i != Pos1[j] && event[Pos1[j]].colType() != 0
939  && (( event[i].isFinal() && event[i].col() == event[Pos1[j]].acol())
940  ||( event[i].status() == -21
941  && event[i].acol() == event[Pos1[j]].acol()) ))
942  partners.push_back(i);
943 
944  // Never allow equal initial partners!
945  if (event[iPartner].status() == -21){
946  for(int i=0; i < int(partners.size()); ++i)
947  if ( partners[i] == iPartner)
948  allowed = false;
949  }
950 
951  } else {
952  int col = event[iPos].acol();
953  int iPartner = 0;
954  for(int i=0; i < int(event.size()); ++i)
955  if ( i != iPos
956  && (( event[i].isFinal() && event[i].col() == col)
957  ||(!event[i].isFinal() && event[i].acol() == col) ))
958  iPartner = i;
959 
960  vector<int> partners;
961  for(int i=0; i < int(event.size()); ++i)
962  for(int j=0; j < int(Pos2.size()); ++j)
963  if ( Pos2[j] != 0 && i != Pos2[j] && event[Pos2[j]].colType() != 0
964  && (( event[i].isFinal() && event[i].acol() == event[Pos2[j]].col())
965  ||( event[i].status() == -21
966  && event[i].col() == event[Pos2[j]].col()) ))
967  partners.push_back(i);
968 
969  // Never allow equal initial partners!
970  if (event[iPartner].status() == -21){
971  for(int i=0; i < int(partners.size()); ++i){
972  if ( partners[i] == iPartner)
973  allowed = false;
974  }
975  }
976 
977  }
978 
979  return allowed;
980 
981 }
982 
983 //--------------------------------------------------------------------------
984 
985 // Function to identify the hard subprocess in the current event
986 
987 void HardProcess::storeCandidates( const Event& event, string process){
988 
989  // Store the reference event
990  state.clear();
991  state = event;
992 
993  // Local copy of intermediate bosons
994  vector<int> intermediates;
995  for(int i =0; i < int(hardIntermediate.size());++i)
996  intermediates.push_back( hardIntermediate[i]);
997 
998  // Local copy of outpoing partons
999  vector<int> outgoing1;
1000  for(int i =0; i < int(hardOutgoing1.size());++i)
1001  outgoing1.push_back( hardOutgoing1[i]);
1002  vector<int> outgoing2;
1003  for(int i =0; i < int(hardOutgoing2.size());++i)
1004  outgoing2.push_back( hardOutgoing2[i]);
1005 
1006  // Clear positions of intermediate and outgoing particles
1007  PosIntermediate.resize(0);
1008  PosOutgoing1.resize(0);
1009  PosOutgoing2.resize(0);
1010  for(int i =0; i < int(hardIntermediate.size());++i)
1011  PosIntermediate.push_back(0);
1012  for(int i =0; i < int(hardOutgoing1.size());++i)
1013  PosOutgoing1.push_back(0);
1014  for(int i =0; i < int(hardOutgoing2.size());++i)
1015  PosOutgoing2.push_back(0);
1016 
1017  // For QCD dijet or e+e- > jets hard process, do not store any candidates,
1018  // as to not discriminate clusterings
1019  if ( process.compare("pp>jj") == 0
1020  || process.compare("e+e->jj") == 0
1021  || process.compare("e+e->(z>jj)") == 0 ){
1022  for(int i =0; i < int(hardOutgoing1.size());++i)
1023  PosOutgoing1[i] = 0;
1024  for(int i =0; i < int(hardOutgoing2.size());++i)
1025  PosOutgoing2[i] = 0;
1026  // Done
1027  return;
1028  }
1029 
1030  // For inclusive merging, do not store any candidates,
1031  // as to not discriminate clusterings
1032  bool isInclusive = true;
1033  for(int i =0; i < int(hardOutgoing1.size());++i)
1034  if (hardOutgoing1[i] < 10000000) isInclusive = false;
1035  for(int i =0; i < int(hardOutgoing2.size());++i)
1036  if (hardOutgoing2[i] < 10000000) isInclusive = false;
1037  if ( isInclusive ){
1038  for(int i =0; i < int(hardOutgoing1.size());++i)
1039  PosOutgoing1[i] = 0;
1040  for(int i =0; i < int(hardOutgoing2.size());++i)
1041  PosOutgoing2[i] = 0;
1042  // Done
1043  return;
1044  }
1045 
1046  // Initialise vector of particles that were already identified as
1047  // hard process particles
1048  vector<int> iPosChecked;
1049 
1050  // If the hard process is specified only by containers, then add all
1051  // particles matching with the containers to the hard process.
1052  bool hasOnlyContainers = true;
1053  for(int i =0; i < int(hardOutgoing1.size());++i)
1054  if ( hardOutgoing1[i] != 1100
1055  && hardOutgoing1[i] != 1200
1056  && hardOutgoing1[i] != 5000)
1057  hasOnlyContainers = false;
1058  for(int i =0; i < int(hardOutgoing2.size());++i)
1059  if ( hardOutgoing2[i] != 1100
1060  && hardOutgoing2[i] != 1200
1061  && hardOutgoing2[i] != 5000)
1062  hasOnlyContainers = false;
1063 
1064  if (hasOnlyContainers){
1065 
1066  PosOutgoing1.resize(0);
1067  PosOutgoing2.resize(0);
1068 
1069  // Try to find all unmatched hard process leptons.
1070  // Loop through event to find outgoing lepton
1071  for(int i=0; i < int(event.size()); ++i){
1072 
1073  // Skip non-final particles
1074  if ( !event[i].isFinal() ) continue;
1075 
1076  // Skip all particles that have already been identified
1077  bool skip = false;
1078  for(int k=0; k < int(iPosChecked.size()); ++k){
1079  if (i == iPosChecked[k])
1080  skip = true;
1081  }
1082  if (skip) continue;
1083 
1084  for(int j=0; j < int(outgoing2.size()); ++j){
1085 
1086  // If the particle matches an outgoing neutrino, save it
1087  if ( outgoing2[j] == 1100
1088  && ( event[i].idAbs() == 11
1089  || event[i].idAbs() == 13
1090  || event[i].idAbs() == 15) ){
1091  PosOutgoing2.push_back(i);
1092  iPosChecked.push_back(i);
1093  }
1094 
1095  // If the particle matches an outgoing lepton, save it
1096  if ( outgoing2[j] == 1200
1097  && ( event[i].idAbs() == 12
1098  || event[i].idAbs() == 14
1099  || event[i].idAbs() == 16) ){
1100  PosOutgoing2.push_back(i);
1101  iPosChecked.push_back(i);
1102  }
1103 
1104  // If the particle matches an outgoing b-quark, save it
1105  if ( outgoing2[j] == 5000 && event[i].idAbs() == 5 ){
1106  PosOutgoing2.push_back(i);
1107  iPosChecked.push_back(i);
1108  }
1109 
1110  }
1111 
1112  // Skip all particles that have already been identified
1113  skip = false;
1114  for(int k=0; k < int(iPosChecked.size()); ++k){
1115  if (i == iPosChecked[k])
1116  skip = true;
1117  }
1118  if (skip) continue;
1119 
1120  for(int j=0; j < int(outgoing1.size()); ++j){
1121 
1122  // If the particle matches an outgoing neutrino, save it
1123  if ( outgoing1[j] == 1100
1124  && ( event[i].idAbs() == 11
1125  || event[i].idAbs() == 13
1126  || event[i].idAbs() == 15) ){
1127  PosOutgoing1.push_back(i);
1128  iPosChecked.push_back(i);
1129  }
1130 
1131  // If the particle matches an outgoing lepton, save it
1132  if ( outgoing1[j] == 1200
1133  && ( event[i].idAbs() == 12
1134  || event[i].idAbs() == 14
1135  || event[i].idAbs() == 16) ){
1136  PosOutgoing1.push_back(i);
1137  iPosChecked.push_back(i);
1138  }
1139 
1140  // If the particle matches an outgoing b-quark, save it
1141  if ( outgoing1[j] == 5000 && event[i].idAbs() == 5 ){
1142  PosOutgoing1.push_back(i);
1143  iPosChecked.push_back(i);
1144  }
1145 
1146  }
1147  }
1148 
1149  // Done
1150  return;
1151  }
1152 
1153  // Now begin finding candidates when not only containers are used.
1154 
1155  // First try to find final state bosons
1156  for(int i=0; i < int(intermediates.size()); ++i){
1157 
1158  // Do nothing if the intermediate boson is absent
1159  if (intermediates[i] == 0) continue;
1160 
1161  // Do nothing if this boson does not match any final state boson
1162  bool matchesFinalBoson = false;
1163  for(int j =0; j< int(outgoing1.size()); ++j){
1164  if ( intermediates[i] == outgoing1[j] )
1165  matchesFinalBoson = true;
1166  }
1167  for(int j =0; j< int(outgoing2.size()); ++j){
1168  if ( intermediates[i] == outgoing2[j] )
1169  matchesFinalBoson = true;
1170  }
1171  if (!matchesFinalBoson) continue;
1172 
1173  // Loop through event
1174  for(int j=0; j < int(event.size()); ++j) {
1175 
1176  // Skip all particles that have already been identified
1177  bool skip = false;
1178  for(int m=0; m < int(iPosChecked.size()); ++m)
1179  if (j == iPosChecked[m]) skip = true;
1180  if (skip) continue;
1181 
1182  // If the particle has a requested intermediate id, check if
1183  // if is a final state boson
1184  if ( (event[j].id() == intermediates[i])
1185  ||(event[j].idAbs() == 24 && intermediates[i] == 2400) ) {
1186 
1187  PosIntermediate[i] = j;
1188  intermediates[i] = 0;
1189  // Be careful only to replace one index at a time!
1190  bool indexSet = false;
1191 
1192  for(int k=0; k < int(outgoing1.size()); ++k) {
1193  if (event[j].id() == outgoing1[k] && !indexSet){
1194  PosOutgoing1[k] = j;
1195  outgoing1[k] = 99;
1196  indexSet = true;
1197  }
1198  }
1199 
1200  for(int k=0; k < int(outgoing2.size()); ++k) {
1201  if (event[j].id() == outgoing2[k] && !indexSet){
1202  PosOutgoing2[k] = j;
1203  outgoing2[k] = 99;
1204  indexSet = true;
1205  }
1206  }
1207 
1208  // Check for W-boson container
1209  for(int k=0; k < int(outgoing2.size()); ++k) {
1210  if (event[j].idAbs() == 24 && outgoing2[k] == 2400 && !indexSet ){
1211  PosOutgoing2[k] = j;
1212  outgoing2[k] = 99;
1213  indexSet = true;
1214  }
1215  }
1216 
1217  iPosChecked.push_back(j);
1218 
1219  }
1220  }
1221  }
1222 
1223  // Second try to find particles coupled to intermediate bosons
1224  for(int i=0; i < int(intermediates.size()); ++i){
1225 
1226  // Do nothing if the intermediate boson is absent
1227  if (intermediates[i] == 0) continue;
1228 
1229  // Loop through event
1230  for(int j=0; j < int(event.size()); ++j) {
1231  // If the particle has a requested intermediate id, check if
1232  // daughters are hard process particles
1233  if ( (event[j].id() == intermediates[i])
1234  ||(event[j].idAbs() == 24 && intermediates[i] == 2400) ) {
1235  // If this particle is a potential intermediate
1236  PosIntermediate[i] = j;
1237  intermediates[i] = 0;
1238  // If id's of daughters are good, store position
1239  int iPos1 = event[j].daughter1();
1240  int iPos2 = event[j].daughter2();
1241 
1242  // Loop through daughters to check if these contain some hard
1243  // outgoing particles
1244  for( int k=iPos1; k <= iPos2; ++k){
1245  int id = event[k].id();
1246 
1247  // Skip all particles that have already been identified
1248  bool skip = false;
1249  for(int m=0; m < int(iPosChecked.size()); ++m)
1250  if (k == iPosChecked[m]) skip = true;
1251  if (skip) continue;
1252 
1253  // Check if daughter is hard outgoing particle
1254  for(int l=0; l < int(outgoing2.size()); ++l)
1255  if ( outgoing2[l] != 99 ){
1256  // Found particle id
1257  if (id == outgoing2[l]
1258  // Found jet
1259  || (id > 0 && abs(id) < 10 && outgoing2[l] == 2212) ){
1260  // Store position
1261  PosOutgoing2[l] = k;
1262  // Remove the matched particle from the list
1263  outgoing2[l] = 99;
1264  iPosChecked.push_back(k);
1265  break;
1266  }
1267 
1268  }
1269 
1270  // Check if daughter is hard outgoing antiparticle
1271  for(int l=0; l < int(outgoing1.size()); ++l)
1272  if ( outgoing1[l] != 99 ){
1273  // Found particle id
1274  if (id == outgoing1[l]
1275  // Found jet
1276  || (id < 0 && abs(id) < 10 && outgoing1[l] == 2212) ){
1277  // Store position
1278  PosOutgoing1[l] = k;
1279  // Remove the matched particle from the list
1280  outgoing1[l] = 99;
1281  iPosChecked.push_back(k);
1282  break;
1283  }
1284 
1285  }
1286 
1287  } // End loop through daughters
1288  } // End if ids match
1289  } // End loop through event
1290  } // End loop though requested intermediates
1291 
1292  // If all outgoing particles were found, done
1293  bool done = true;
1294  for(int i=0; i < int(outgoing1.size()); ++i)
1295  if (outgoing1[i] != 99)
1296  done = false;
1297  for(int i=0; i < int(outgoing2.size()); ++i)
1298  if (outgoing2[i] != 99)
1299  done = false;
1300  // Return
1301  if (done) return;
1302 
1303  // Leptons not associated with resonance are allowed.
1304  // Try to find all unmatched hard process leptons.
1305  // Loop through event to find outgoing lepton
1306  for(int i=0; i < int(event.size()); ++i){
1307  // Skip non-final particles and final partons
1308  if ( !event[i].isFinal() || event[i].colType() != 0)
1309  continue;
1310  // Skip all particles that have already been identified
1311  bool skip = false;
1312  for(int k=0; k < int(iPosChecked.size()); ++k){
1313  if (i == iPosChecked[k])
1314  skip = true;
1315  }
1316  if (skip) continue;
1317 
1318  // Check if any hard outgoing leptons remain
1319  for(int j=0; j < int(outgoing2.size()); ++j){
1320  // Do nothing if this particle has already be found,
1321  // or if this particle is a jet or quark
1322  if ( outgoing2[j] == 99
1323  || outgoing2[j] == 2212
1324  || abs(outgoing2[j]) < 10)
1325  continue;
1326 
1327  // If the particle matches an outgoing lepton, save it
1328  if ( event[i].id() == outgoing2[j] ){
1329  PosOutgoing2[j] = i;
1330  outgoing2[j] = 99;
1331  iPosChecked.push_back(i);
1332  }
1333  }
1334 
1335  // Check if any hard outgoing antileptons remain
1336  for(int j=0; j < int(outgoing1.size()); ++j){
1337  // Do nothing if this particle has already be found,
1338  // or if this particle is a jet or quark
1339  if ( outgoing1[j] == 99
1340  || outgoing1[j] == 2212
1341  || abs(outgoing1[j]) < 10)
1342  continue;
1343 
1344  // If the particle matches an outgoing lepton, save it
1345  if (event[i].id() == outgoing1[j] ){
1346  PosOutgoing1[j] = i;
1347  outgoing1[j] = 99;
1348  iPosChecked.push_back(i);
1349  }
1350  }
1351  }
1352 
1353  multimap<int,int> out2copy;
1354  for(int i=0; i < int(event.size()); ++i)
1355  for(int j=0; j < int(outgoing2.size()); ++j)
1356  // Do nothing if this particle has already be found,
1357  // or if this particle is a jet.
1358  if ( outgoing2[j] != 99
1359  && outgoing2[j] != 2212
1360  && ( abs(outgoing2[j]) < 10
1361  || (abs(outgoing2[j]) > 1000000 && abs(outgoing2[j]) < 1000010)
1362  || (abs(outgoing2[j]) > 2000000 && abs(outgoing2[j]) < 2000010)
1363  || abs(outgoing2[j]) == 1000021 )
1364  && event[i].isFinal()
1365  && event[i].id() == outgoing2[j] ){
1366  out2copy.insert(make_pair(j, i));
1367  }
1368 
1369  multimap<int,int> out1copy;
1370  for(int i=0; i < int(event.size()); ++i)
1371  for(int j=0; j < int(outgoing1.size()); ++j)
1372  // Do nothing if this particle has already be found,
1373  // or if this particle is a jet.
1374  if ( outgoing1[j] != 99
1375  && outgoing1[j] != 2212
1376  && ( abs(outgoing1[j]) < 10
1377  || (abs(outgoing1[j]) > 1000000 && abs(outgoing1[j]) < 1000010)
1378  || (abs(outgoing1[j]) > 2000000 && abs(outgoing1[j]) < 2000010)
1379  || abs(outgoing2[j]) == 1000021 )
1380  && event[i].isFinal()
1381  && event[i].id() == outgoing1[j] ){
1382  out1copy.insert(make_pair(j, i));
1383  }
1384 
1385  if ( out1copy.size() > out2copy.size()){
1386 
1387  // In case the index of the multimap is filled twice, make sure not to
1388  // arbitrarily overwrite set values.
1389  vector<int> indexWasSet;
1390  for ( multimap<int, int>::iterator it = out2copy.begin();
1391  it != out2copy.end(); ++it ) {
1392  if ( allowCandidates(it->second, PosOutgoing1, PosOutgoing2, event) ){
1393 
1394  // Skip all particles that have already been identified
1395  bool skip = false;
1396  for(int k=0; k < int(iPosChecked.size()); ++k)
1397  if (it->second == iPosChecked[k]) skip = true;
1398  // Skip all indices that have already been identified
1399  for(int k=0; k < int(indexWasSet.size()); ++k)
1400  if (it->first == indexWasSet[k]) skip = true;
1401  if (skip) continue;
1402 
1403  // Save parton
1404  PosOutgoing2[it->first] = it->second;
1405  // remove entry form lists
1406  outgoing2[it->first] = 99;
1407  iPosChecked.push_back(it->second);
1408  indexWasSet.push_back(it->first);
1409  }
1410  }
1411 
1412  indexWasSet.resize(0);
1413  for ( multimap<int, int>::iterator it = out1copy.begin();
1414  it != out1copy.end(); ++it ) {
1415  if ( allowCandidates(it->second, PosOutgoing1, PosOutgoing2, event) ){
1416 
1417  // Skip all particles that have already been identified
1418  bool skip = false;
1419  for(int k=0; k < int(iPosChecked.size()); ++k)
1420  if (it->second == iPosChecked[k]) skip = true;
1421  // Skip all indices that have already been identified
1422  for(int k=0; k < int(indexWasSet.size()); ++k)
1423  if (it->first == indexWasSet[k]) skip = true;
1424  if (skip) continue;
1425 
1426  // Save parton
1427  PosOutgoing1[it->first] = it->second;
1428  // remove entry form lists
1429  outgoing1[it->first] = 99;
1430  iPosChecked.push_back(it->second);
1431  indexWasSet.push_back(it->first);
1432  }
1433  }
1434 
1435  } else {
1436 
1437  // In case the index of the multimap is filled twice, make sure not to
1438  // arbitraryly overwrite set values.
1439  vector<int> indexWasSet;
1440  for ( multimap<int, int>::iterator it = out1copy.begin();
1441  it != out1copy.end(); ++it ) {
1442  if ( allowCandidates(it->second, PosOutgoing1, PosOutgoing2, event) ){
1443 
1444  // Skip all particles that have already been identified
1445  bool skip = false;
1446  for(int k=0; k < int(iPosChecked.size()); ++k)
1447  if (it->second == iPosChecked[k]) skip = true;
1448  // Skip all indices that have already been identified
1449  for(int k=0; k < int(indexWasSet.size()); ++k)
1450  if (it->first == indexWasSet[k]) skip = true;
1451  if (skip) continue;
1452 
1453  // Save parton
1454  PosOutgoing1[it->first] = it->second;
1455  // remove entry form lists
1456  outgoing1[it->first] = 99;
1457  iPosChecked.push_back(it->second);
1458  indexWasSet.push_back(it->first);
1459  }
1460  }
1461 
1462  indexWasSet.resize(0);
1463  for ( multimap<int, int>::iterator it = out2copy.begin();
1464  it != out2copy.end(); ++it ) {
1465  if ( allowCandidates(it->second, PosOutgoing1, PosOutgoing2, event) ){
1466 
1467  // Skip all particles that have already been identified
1468  bool skip = false;
1469  for(int k=0; k < int(iPosChecked.size()); ++k)
1470  if (it->second == iPosChecked[k]) skip = true;
1471  // Skip all indices that have already been identified
1472  for(int k=0; k < int(indexWasSet.size()); ++k)
1473  if (it->first == indexWasSet[k]) skip = true;
1474  if (skip) continue;
1475 
1476  // Save parton
1477  PosOutgoing2[it->first] = it->second;
1478  // remove entry form lists
1479  outgoing2[it->first] = 99;
1480  iPosChecked.push_back(it->second);
1481  indexWasSet.push_back(it->first);
1482  }
1483  }
1484  }
1485 
1486  // It sometimes happens that MadEvent does not put a
1487  // heavy coloured resonance into the LHE file, even if requested.
1488  // This means that the decay products of this resonance need to be
1489  // found separately.
1490  // Loop through event to find hard process (anti)quarks
1491  for(int i=0; i < int(event.size()); ++i){
1492 
1493  // Skip non-final particles and final partons
1494  if ( !event[i].isFinal() || event[i].colType() == 0)
1495  continue;
1496 
1497  // Skip all particles that have already been identified
1498  bool skip = false;
1499  for(int k=0; k < int(iPosChecked.size()); ++k){
1500  if (i == iPosChecked[k])
1501  skip = true;
1502  }
1503  if (skip) continue;
1504 
1505  // Check if any hard outgoing quarks remain
1506  for(int j=0; j < int(outgoing2.size()); ++j){
1507  // Do nothing if this particle has already be found,
1508  // or if this particle is a jet, lepton container or lepton
1509 
1510  if ( outgoing2[j] == 99
1511  || outgoing2[j] == 2212
1512  || (abs(outgoing2[j]) > 10 && abs(outgoing2[j]) < 20)
1513  || outgoing2[j] == 1100
1514  || outgoing2[j] == 1200
1515  || outgoing2[j] == 2400 )
1516  continue;
1517 
1518  // If the particle matches an outgoing quark, save it
1519  if (event[i].id() == outgoing2[j]){
1520  // Save parton
1521  PosOutgoing2[j] = i;
1522  // remove entry form lists
1523  outgoing2[j] = 99;
1524  iPosChecked.push_back(i);
1525  break;
1526  }
1527  }
1528 
1529  // Check if any hard outgoing antiquarks remain
1530  for(int j=0; j < int(outgoing1.size()); ++j){
1531  // Do nothing if this particle has already be found,
1532  // or if this particle is a jet, lepton container or lepton
1533  if ( outgoing1[j] == 99
1534  || outgoing1[j] == 2212
1535  || (abs(outgoing1[j]) > 10 && abs(outgoing1[j]) < 20)
1536  || outgoing1[j] == 1100
1537  || outgoing1[j] == 1200
1538  || outgoing1[j] == 2400 )
1539  continue;
1540  // If the particle matches an outgoing antiquark, save it
1541  if (event[i].id() == outgoing1[j]){
1542  // Save parton
1543  PosOutgoing1[j] = i;
1544  // Remove parton from list
1545  outgoing1[j] = 99;
1546  iPosChecked.push_back(i);
1547  break;
1548  }
1549  }
1550  }
1551 
1552  // Done
1553 }
1554 
1555 //--------------------------------------------------------------------------
1556 
1557 // Function to check if the particle event[iPos] matches any of
1558 // the stored outgoing particles of the hard subprocess
1559 
1560 bool HardProcess::matchesAnyOutgoing(int iPos, const Event& event){
1561 
1562  // Match quantum numbers of any first outgoing candidate
1563  bool matchQN1 = false;
1564  // Match quantum numbers of any second outgoing candidate
1565  bool matchQN2 = false;
1566  // Match parton in the hard process,
1567  // or parton from decay of electroweak boson in hard process,
1568  // or parton from decay of electroweak boson from decay of top
1569  bool matchHP = false;
1570 
1571  // Check outgoing candidates
1572  for(int i=0; i < int(PosOutgoing1.size()); ++i)
1573  // Compare particle properties
1574  if ( event[iPos].id() == state[PosOutgoing1[i]].id()
1575  && event[iPos].colType() == state[PosOutgoing1[i]].colType()
1576  && event[iPos].chargeType() == state[PosOutgoing1[i]].chargeType()
1577  && ( ( event[iPos].col() > 0
1578  && event[iPos].col() == state[PosOutgoing1[i]].col())
1579  || ( event[iPos].acol() > 0
1580  && event[iPos].acol() == state[PosOutgoing1[i]].acol()))
1581  && event[iPos].charge() == state[PosOutgoing1[i]].charge() )
1582  matchQN1 = true;
1583 
1584  // Check outgoing candidates
1585  for(int i=0; i < int(PosOutgoing2.size()); ++i)
1586  // Compare particle properties
1587  if ( event[iPos].id() == state[PosOutgoing2[i]].id()
1588  && event[iPos].colType() == state[PosOutgoing2[i]].colType()
1589  && event[iPos].chargeType() == state[PosOutgoing2[i]].chargeType()
1590  && ( ( event[iPos].col() > 0
1591  && event[iPos].col() == state[PosOutgoing2[i]].col())
1592  || ( event[iPos].acol() > 0
1593  && event[iPos].acol() == state[PosOutgoing2[i]].acol()))
1594  && event[iPos].charge() == state[PosOutgoing2[i]].charge() )
1595  matchQN2 = true;
1596 
1597  // Check if maps to hard process:
1598  // Check that particle is in hard process
1599  if ( event[iPos].mother1()*event[iPos].mother2() == 12
1600  // Or particle has taken recoil from first splitting
1601  || ( event[iPos].status() == 44
1602  && event[event[iPos].mother1()].mother1()
1603  *event[event[iPos].mother1()].mother2() == 12 )
1604  || ( event[iPos].status() == 48
1605  && event[event[iPos].mother1()].mother1()
1606  *event[event[iPos].mother1()].mother2() == 12 )
1607  // Or particle has on-shell resonace as mother
1608  || ( event[iPos].status() == 23
1609  && event[event[iPos].mother1()].mother1()
1610  *event[event[iPos].mother1()].mother2() == 12 )
1611  // Or particle has on-shell resonace as mother,
1612  // which again has and on-shell resonance as mother
1613  || ( event[iPos].status() == 23
1614  && event[event[iPos].mother1()].status() == -22
1615  && event[event[event[iPos].mother1()].mother1()].status() == -22
1616  && event[event[event[iPos].mother1()].mother1()].mother1()
1617  *event[event[event[iPos].mother1()].mother1()].mother2() == 12 ) )
1618  matchHP = true;
1619 
1620  // Done
1621  return ( matchHP && (matchQN1 || matchQN2) );
1622 
1623 }
1624 
1625 
1626 //--------------------------------------------------------------------------
1627 
1628 // Function to check if instead of the particle event[iCandidate], another
1629 // particle could serve as part of the hard process. Assumes that iCandidate
1630 // is already stored as part of the hard process.
1631 
1632 bool HardProcess::findOtherCandidates(int iPos, const Event& event,
1633  bool doReplace){
1634 
1635  // Return value
1636  bool foundCopy = false;
1637 
1638  // Save stored candidates' properties.
1639  int id = event[iPos].id();
1640  int col = event[iPos].col();
1641  int acl = event[iPos].acol();
1642 
1643  // If the particle's mother is an identified intermediate resonance,
1644  // then do not attempt any replacement.
1645  int iMoth1 = event[iPos].mother1();
1646  int iMoth2 = event[iPos].mother2();
1647  if ( iMoth1 > 0 && iMoth2 == 0 ) {
1648  bool hasIdentifiedMother = false;
1649  for(int i=0; i < int(PosIntermediate.size()); ++i)
1650  // Compare particle properties
1651  if ( event[iMoth1].id() == state[PosIntermediate[i]].id()
1652  && event[iMoth1].colType() == state[PosIntermediate[i]].colType()
1653  && event[iMoth1].chargeType() == state[PosIntermediate[i]].chargeType()
1654  && event[iMoth1].col() == state[PosIntermediate[i]].col()
1655  && event[iMoth1].acol() == state[PosIntermediate[i]].acol()
1656  && event[iMoth1].charge() == state[PosIntermediate[i]].charge() )
1657  hasIdentifiedMother = true;
1658  if(hasIdentifiedMother && event[iMoth1].id() != id) return false;
1659  }
1660 
1661  // Find candidate amongst the already stored ME process candidates.
1662  vector<int> candidates1;
1663  vector<int> candidates2;
1664  // Check outgoing candidates
1665  for(int i=0; i < int(PosOutgoing1.size()); ++i)
1666  // Compare particle properties
1667  if ( id == state[PosOutgoing1[i]].id()
1668  && col == state[PosOutgoing1[i]].col()
1669  && acl == state[PosOutgoing1[i]].acol() )
1670  candidates1.push_back(i);
1671  // Check outgoing candidates
1672  for(int i=0; i < int(PosOutgoing2.size()); ++i)
1673  // Compare particle properties
1674  if ( id == state[PosOutgoing2[i]].id()
1675  && col == state[PosOutgoing2[i]].col()
1676  && acl == state[PosOutgoing2[i]].acol() )
1677  candidates2.push_back(i);
1678 
1679  // If more / less than one stored candidate for iPos has been found, exit.
1680  if ( candidates1.size() + candidates2.size() != 1 ) return false;
1681 
1682  // Now check for other allowed candidates.
1683  map<int,int> further1;
1684  for(int i=0; i < int(state.size()); ++i)
1685  for(int j=0; j < int(PosOutgoing1.size()); ++j)
1686  // Do nothing if this particle has already be found,
1687  // or if this particle is a jet, lepton container or lepton
1688  if ( state[i].isFinal()
1689  && i != PosOutgoing1[j]
1690  && state[PosOutgoing1[j]].id() == id
1691  && state[i].id() == id ){
1692  // Declare vector of already existing candiates.
1693  vector<int> newPosOutgoing1;
1694  for(int k=0; k < int(PosOutgoing1.size()); ++k)
1695  if ( k != j ) newPosOutgoing1.push_back( PosOutgoing1[k] );
1696  // If allowed, remember replacment parton.
1697  if ( allowCandidates(i, newPosOutgoing1, PosOutgoing2, state) )
1698  further1.insert(make_pair(j, i));
1699  }
1700 
1701  // Now check for other allowed candidates.
1702  map<int,int> further2;
1703  for(int i=0; i < int(state.size()); ++i)
1704  for(int j=0; j < int(PosOutgoing2.size()); ++j)
1705  // Do nothing if this particle has already be found,
1706  // or if this particle is a jet, lepton container or lepton
1707  if ( state[i].isFinal()
1708  && i != PosOutgoing2[j]
1709  && state[PosOutgoing2[j]].id() == id
1710  && state[i].id() == id ){
1711  // Declare vector of already existing candidates.
1712  vector<int> newPosOutgoing2;
1713  for(int k=0; k < int(PosOutgoing2.size()); ++k)
1714  if ( k != j ) newPosOutgoing2.push_back( PosOutgoing2[k] );
1715  // If allowed, remember replacment parton.
1716  if ( allowCandidates(i, PosOutgoing1, newPosOutgoing2, state) )
1717  further2.insert(make_pair(j, i));
1718  }
1719 
1720  // Remove all hard process particles that would be counted twice.
1721  map<int,int>::iterator it2 = further2.begin();
1722  while(it2 != further2.end()) {
1723  bool remove = false;
1724  for(int j=0; j < int(PosOutgoing2.size()); ++j)
1725  if (it2->second == PosOutgoing2[j] ) remove = true;
1726  if ( remove ) further2.erase(it2++);
1727  else ++it2;
1728  }
1729  map<int,int>::iterator it1 = further1.begin();
1730  while(it1 != further1.end()) {
1731  bool remove = false;
1732  for(int j=0; j < int(PosOutgoing1.size()); ++j)
1733  if (it1->second == PosOutgoing1[j] ) remove = true;
1734  if ( remove ) further1.erase(it1++);
1735  else ++it1;
1736  }
1737 
1738  // Decide of a replacment candidate has been found.
1739  foundCopy = (doReplace)
1740  ? exchangeCandidates(candidates1, candidates2, further1, further2)
1741  : (further1.size() + further2.size() > 0);
1742 
1743  // Done
1744  return foundCopy;
1745 
1746 }
1747 
1748 //--------------------------------------------------------------------------
1749 
1750 // Function to exchange hard process candidates.
1751 
1752 bool HardProcess::exchangeCandidates( vector<int> candidates1,
1753  vector<int> candidates2, map<int,int> further1, map<int,int> further2) {
1754 
1755  int nOld1 = candidates1.size();
1756  int nOld2 = candidates2.size();
1757  int nNew1 = further1.size();
1758  int nNew2 = further2.size();
1759  bool exchanged = false;
1760  // Replace, if one-to-one correspondence exists.
1761  if ( nOld1 == 1 && nOld2 == 0 && nNew1 == 1 && nNew2 == 0){
1762  PosOutgoing1[further1.begin()->first] = further1.begin()->second;
1763  exchanged = true;
1764  } else if ( nOld1 == 0 && nOld2 == 1 && nNew1 == 0 && nNew2 == 1){
1765  PosOutgoing2[further2.begin()->first] = further2.begin()->second;
1766  exchanged = true;
1767  // Else simply swap with the first candidate.
1768  } else if ( nNew1 > 1 && nNew2 == 0 ) {
1769  PosOutgoing1[further1.begin()->first] = further1.begin()->second;
1770  exchanged = true;
1771  } else if ( nNew1 == 0 && nNew2 > 0 ) {
1772  PosOutgoing2[further2.begin()->first] = further2.begin()->second;
1773  exchanged = true;
1774  }
1775 
1776  // Done
1777  return exchanged;
1778 
1779 }
1780 
1781 //--------------------------------------------------------------------------
1782 
1783 // Function to get the number of coloured final state partons in the
1784 // hard process
1785 
1786 int HardProcess::nQuarksOut(){
1787  int nFin =0;
1788  for(int i =0; i< int(hardOutgoing1.size()); ++i){
1789  if (hardOutgoing1[i] == 2212 || abs(hardOutgoing1[i]) < 10) nFin++;
1790  }
1791  for(int i =0; i< int(hardOutgoing2.size()); ++i){
1792  if (hardOutgoing2[i] == 2212 || abs(hardOutgoing2[i]) < 10) nFin++;
1793  }
1794  // For very loose hard process definition, check number of hard process
1795  // b-quarks explicitly.
1796  for(int i =0; i< int(hardOutgoing1.size()); ++i)
1797  if (hardOutgoing1[i] == 5000)
1798  for(int j =0; j< int(PosOutgoing1.size()); ++j)
1799  if (state[PosOutgoing1[j]].idAbs() == 5)
1800  nFin++;
1801  for(int i =0; i< int(hardOutgoing2.size()); ++i)
1802  if (hardOutgoing2[i] == 5000)
1803  for(int j =0; j< int(PosOutgoing2.size()); ++j)
1804  if (state[PosOutgoing2[j]].idAbs() == 5)
1805  nFin++;
1806  return nFin;
1807 }
1808 
1809 //--------------------------------------------------------------------------
1810 
1811 // Function to get the number of uncoloured final state particles in the
1812 // hard process
1813 
1814 int HardProcess::nLeptonOut(){
1815  int nFin =0;
1816  for(int i =0; i< int(hardOutgoing1.size()); ++i){
1817  if (abs(hardOutgoing1[i]) > 10 && abs(hardOutgoing1[i]) < 20) nFin++;
1818  // Bookkeep MSSM neutralinos as leptons
1819  if (abs(hardOutgoing1[i]) == 1000022) nFin++;
1820  // Bookkeep sleptons as leptons
1821  if ( abs(hardOutgoing1[i]) == 1000011 || abs(hardOutgoing1[i]) == 2000011
1822  || abs(hardOutgoing1[i]) == 1000013 || abs(hardOutgoing1[i]) == 2000013
1823  || abs(hardOutgoing1[i]) == 1000015 || abs(hardOutgoing1[i]) == 2000015)
1824  nFin++;
1825  }
1826  for(int i =0; i< int(hardOutgoing2.size()); ++i){
1827  if (abs(hardOutgoing2[i]) > 10 && abs(hardOutgoing2[i]) < 20) nFin++;
1828  // Bookkeep MSSM neutralinos as leptons
1829  if (abs(hardOutgoing2[i]) == 1000022) nFin++;
1830  // Bookkeep sleptons as leptons
1831  if ( abs(hardOutgoing2[i]) == 1000011 || abs(hardOutgoing2[i]) == 2000011
1832  || abs(hardOutgoing2[i]) == 1000013 || abs(hardOutgoing2[i]) == 2000013
1833  || abs(hardOutgoing2[i]) == 1000015 || abs(hardOutgoing2[i]) == 2000015)
1834  nFin++;
1835  }
1836  // For very loose hard process definition, check number of hard process
1837  // lepton explicitly.
1838  // Check lepton / neutrino containers as leptons
1839  for(int i =0; i< int(hardOutgoing1.size()); ++i)
1840  if (hardOutgoing1[i] == 1100)
1841  for(int j =0; j< int(PosOutgoing1.size()); ++j)
1842  if ( abs(state[PosOutgoing1[j]].id()) == 11
1843  || abs(state[PosOutgoing1[j]].id()) == 13
1844  || abs(state[PosOutgoing1[j]].id()) == 15 )
1845  nFin++;
1846  for(int i =0; i< int(hardOutgoing2.size()); ++i)
1847  if (hardOutgoing2[i] == 1200)
1848  for(int j =0; j< int(PosOutgoing2.size()); ++j)
1849  if ( abs(state[PosOutgoing2[j]].id()) == 12
1850  || abs(state[PosOutgoing2[j]].id()) == 14
1851  || abs(state[PosOutgoing2[j]].id()) == 16 )
1852  nFin++;
1853  return nFin;
1854 }
1855 
1856 //--------------------------------------------------------------------------
1857 
1858 // Function to get the number of uncoloured final state particles in the
1859 // hard process
1860 
1861 int HardProcess::nBosonsOut(){
1862  int nFin =0;
1863  for(int i =0; i< int(hardOutgoing1.size()); ++i){
1864  if (abs(hardOutgoing1[i]) > 20 && abs(hardOutgoing1[i]) <= 25) nFin++;
1865  }
1866  for(int i =0; i< int(hardOutgoing2.size()); ++i){
1867  if (abs(hardOutgoing2[i]) > 20 && abs(hardOutgoing2[i]) <= 25) nFin++;
1868  if ( hardOutgoing2[i] == 2400) nFin++;
1869  }
1870  return nFin;
1871 }
1872 
1873 //--------------------------------------------------------------------------
1874 
1875 // Function to get the number of coloured initial state partons in the
1876 // hard process
1877 
1878 int HardProcess::nQuarksIn(){
1879  int nIn =0;
1880  if (hardIncoming1 == 2212 || abs(hardIncoming1) < 10) nIn++;
1881  if (hardIncoming2 == 2212 || abs(hardIncoming2) < 10) nIn++;
1882  return nIn;
1883 }
1884 
1885 //--------------------------------------------------------------------------
1886 
1887 // Function to get the number of uncoloured initial state particles in the
1888 // hard process
1889 
1890 int HardProcess::nLeptonIn(){
1891  int nIn =0;
1892  if (abs(hardIncoming1) > 10 && abs(hardIncoming1) < 20) nIn++;
1893  if (abs(hardIncoming2) > 10 && abs(hardIncoming2) < 20) nIn++;
1894  return nIn;
1895 }
1896 
1897 //--------------------------------------------------------------------------
1898 
1899 // Function to report if a resonace decay was found in the
1900 // 2->2 hard sub-process in the current state
1901 
1902 int HardProcess::hasResInCurrent(){
1903  for(int i =0; i< int(PosIntermediate.size()); ++i)
1904  if (PosIntermediate[i] == 0) return 0;
1905  // Do not count final state bosons as resonaces
1906  for(int i =0; i< int(PosIntermediate.size()); ++i){
1907  for(int j =0; j< int(PosOutgoing1.size()); ++j){
1908  if ( PosIntermediate[i] == PosOutgoing1[j] )
1909  return 0;
1910  }
1911  for(int j =0; j< int(PosOutgoing2.size()); ++j){
1912  if ( PosIntermediate[i] == PosOutgoing2[j] )
1913  return 0;
1914  }
1915  }
1916  return 1;
1917 }
1918 
1919 //--------------------------------------------------------------------------
1920 
1921 // Function to report the number of resonace decays in the 2->2 sub-process
1922 // of the current state
1923 
1924 int HardProcess::nResInCurrent(){
1925  int nRes = 0;
1926  for(int i =0; i< int(PosIntermediate.size()); ++i){
1927  if (PosIntermediate[i] != 0) {
1928  bool matchesFinalBoson = false;
1929  for(int j =0; j< int(PosOutgoing1.size()); ++j){
1930  if ( PosIntermediate[i] == PosOutgoing1[j] )
1931  matchesFinalBoson = true;
1932  }
1933  for(int j =0; j< int(PosOutgoing2.size()); ++j){
1934  if ( PosIntermediate[i] == PosOutgoing2[j] )
1935  matchesFinalBoson = true;
1936  }
1937  if (!matchesFinalBoson) nRes++;
1938  }
1939  }
1940  return nRes;
1941 }
1942 
1943 //--------------------------------------------------------------------------
1944 
1945 // Function to report if a resonace decay was found in the
1946 // 2->2 hard core process
1947 
1948 bool HardProcess::hasResInProc(){
1949 
1950  for(int i =0; i< int(hardIntermediate.size()); ++i)
1951  if (hardIntermediate[i] == 0) return false;
1952  // Do not count final state bosons as resonaces
1953  for(int i =0; i< int(hardIntermediate.size()); ++i){
1954  for(int j =0; j< int(hardOutgoing1.size()); ++j){
1955  if ( hardIntermediate[i] == hardOutgoing1[j] )
1956  return false;
1957  }
1958  for(int j =0; j< int(hardOutgoing2.size()); ++j){
1959  if ( hardIntermediate[i] == hardOutgoing2[j] )
1960  return false;
1961  }
1962  }
1963  return true;
1964 }
1965 
1966 //--------------------------------------------------------------------------
1967 
1968 // Function to print the hard process (for debug)
1969 
1970 void HardProcess::list() const {
1971  cout << " Hard Process: ";
1972  cout << " \t " << hardIncoming1 << " + " << hardIncoming2;
1973  cout << " \t -----> \t ";
1974  for(int i =0; i < int(hardIntermediate.size());++i)
1975  cout << hardIntermediate[i] << " ";
1976  cout << " \t -----> \t ";
1977  for(int i =0; i < int(hardOutgoing1.size());++i)
1978  cout << hardOutgoing1[i] << " ";
1979  for(int i =0; i < int(hardOutgoing2.size());++i)
1980  cout << hardOutgoing2[i] << " ";
1981  cout << endl;
1982 }
1983 
1984 //--------------------------------------------------------------------------
1985 
1986 // Function to list the hard process candiates in the matrix element state
1987 // (for debug)
1988 
1989 void HardProcess::listCandidates() const {
1990  cout << " Hard Process candidates: ";
1991  cout << " \t " << hardIncoming1 << " + " << hardIncoming2;
1992  cout << " \t -----> \t ";
1993  for(int i =0; i < int(PosIntermediate.size());++i)
1994  cout << PosIntermediate[i] << " ";
1995  cout << " \t -----> \t ";
1996  for(int i =0; i < int(PosOutgoing1.size());++i)
1997  cout << PosOutgoing1[i] << " ";
1998  for(int i =0; i < int(PosOutgoing2.size());++i)
1999  cout << PosOutgoing2[i] << " ";
2000  cout << endl;
2001 }
2002 
2003 //--------------------------------------------------------------------------
2004 
2005 // Function to clear hard process information
2006 
2007 void HardProcess::clear() {
2008 
2009  // Clear flavour of the first incoming particle
2010  hardIncoming1 = hardIncoming2 = 0;
2011  // Clear outgoing particles
2012  hardOutgoing1.resize(0);
2013  hardOutgoing2.resize(0);
2014  // Clear intermediate bosons in the hard 2->2
2015  hardIntermediate.resize(0);
2016 
2017  // Clear reference event
2018  state.clear();
2019 
2020  // Clear potential positions of outgoing particles in reference event
2021  PosOutgoing1.resize(0);
2022  PosOutgoing2.resize(0);
2023  // Clear potential positions of intermediate bosons in reference event
2024  PosIntermediate.resize(0);
2025 
2026  // Clear merging scale read from LHE file
2027  tms = 0.;
2028 
2029 }
2030 
2031 //==========================================================================
2032 
2033 // The MergingHooks class.
2034 
2035 //--------------------------------------------------------------------------
2036 
2037 // Destructor
2038 MergingHooks::~MergingHooks() { if (useOwnHardProcess) delete hardProcess; }
2039 
2040 //--------------------------------------------------------------------------
2041 
2042 // Initialise MergingHooks class
2043 
2044 void MergingHooks::init(){
2045 
2046  // Save pointers
2047  showers = 0;
2048 
2049  // Initialise AlphaS objects for reweighting
2050  double alphaSvalueFSR = settingsPtr->parm("TimeShower:alphaSvalue");
2051  int alphaSorderFSR = settingsPtr->mode("TimeShower:alphaSorder");
2052  int alphaSnfmax = settingsPtr->mode("StandardModel:alphaSnfmax");
2053  int alphaSuseCMWFSR= settingsPtr->flag("TimeShower:alphaSuseCMW");
2054  AlphaS_FSRSave.init(alphaSvalueFSR, alphaSorderFSR, alphaSnfmax,
2055  alphaSuseCMWFSR);
2056  double alphaSvalueISR = settingsPtr->parm("SpaceShower:alphaSvalue");
2057  int alphaSorderISR = settingsPtr->mode("SpaceShower:alphaSorder");
2058  int alphaSuseCMWISR= settingsPtr->flag("SpaceShower:alphaSuseCMW");
2059  AlphaS_ISRSave.init(alphaSvalueISR, alphaSorderISR, alphaSnfmax,
2060  alphaSuseCMWISR);
2061 
2062  // Initialise AlphaEM objects for reweighting
2063  int alphaEMFSRorder = settingsPtr->mode("TimeShower:alphaEMorder");
2064  AlphaEM_FSRSave.init(alphaEMFSRorder, settingsPtr);
2065  int alphaEMISRorder = settingsPtr->mode("SpaceShower:alphaEMorder");
2066  AlphaEM_ISRSave.init(alphaEMISRorder, settingsPtr);
2067 
2068  // Initialise merging switches
2069  doUserMergingSave = settingsPtr->flag("Merging:doUserMerging");
2070  // Initialise automated MadGraph kT merging
2071  doMGMergingSave = settingsPtr->flag("Merging:doMGMerging");
2072  // Initialise kT merging
2073  doKTMergingSave = settingsPtr->flag("Merging:doKTMerging");
2074  // Initialise evolution-pT merging
2075  doPTLundMergingSave = settingsPtr->flag("Merging:doPTLundMerging");
2076  // Initialise \Delta_R_{ij}, pT_i Q_{ij} merging
2077  doCutBasedMergingSave = settingsPtr->flag("Merging:doCutBasedMerging");
2078  // Initialise exact definition of kT
2079  ktTypeSave = settingsPtr->mode("Merging:ktType");
2080 
2081  // Initialise NL3 switches.
2082  doNL3TreeSave = settingsPtr->flag("Merging:doNL3Tree");
2083  doNL3LoopSave = settingsPtr->flag("Merging:doNL3Loop");
2084  doNL3SubtSave = settingsPtr->flag("Merging:doNL3Subt");
2085  bool doNL3 = doNL3TreeSave || doNL3LoopSave || doNL3SubtSave;
2086 
2087  // Initialise UNLOPS switches.
2088  doUNLOPSTreeSave = settingsPtr->flag("Merging:doUNLOPSTree");
2089  doUNLOPSLoopSave = settingsPtr->flag("Merging:doUNLOPSLoop");
2090  doUNLOPSSubtSave = settingsPtr->flag("Merging:doUNLOPSSubt");
2091  doUNLOPSSubtNLOSave = settingsPtr->flag("Merging:doUNLOPSSubtNLO");
2092  bool doUNLOPS = doUNLOPSTreeSave || doUNLOPSLoopSave
2093  || doUNLOPSSubtSave || doUNLOPSSubtNLOSave;
2094 
2095  // Initialise UMEPS switches
2096  doUMEPSTreeSave = settingsPtr->flag("Merging:doUMEPSTree");
2097  doUMEPSSubtSave = settingsPtr->flag("Merging:doUMEPSSubt");
2098  nReclusterSave = settingsPtr->mode("Merging:nRecluster");
2099  nQuarksMergeSave = settingsPtr->mode("Merging:nQuarksMerge");
2100  nRequestedSave = settingsPtr->mode("Merging:nRequested");
2101  bool doUMEPS = doUMEPSTreeSave || doUMEPSSubtSave;
2102 
2103  // Flag to only do phase space cut.
2104  doEstimateXSection = settingsPtr->flag("Merging:doXSectionEstimate");
2105 
2106  // Flag to check if merging weight should directly be included in the cross
2107  // section.
2108  includeWGTinXSECSave = settingsPtr->flag("Merging:includeWeightInXsection");
2109 
2110  // Flag to check if CKKW-L event veto should be applied.
2111  applyVeto = settingsPtr->flag("Merging:applyVeto");
2112 
2113  // Get core process from user input
2114  processSave = settingsPtr->word("Merging:Process");
2115 
2116  if (!hardProcess) {
2117  hardProcess = new HardProcess();
2118  useOwnHardProcess = true;
2119  }
2120 
2121  // Clear hard process
2122  hardProcess->clear();
2123 
2124  // Initialise input event.
2125  inputEvent.init("(hard process)", particleDataPtr);
2126  doRemoveDecayProducts = settingsPtr->flag("Merging:mayRemoveDecayProducts");
2127 
2128  // Initialise the hard process
2129  if ( doMGMergingSave )
2130  hardProcess->initOnLHEF(lheInputFile, particleDataPtr);
2131  else
2132  hardProcess->initOnProcess(processSave, particleDataPtr);
2133 
2134  // Remove whitespace from process string
2135  while(processSave.find(" ", 0) != string::npos)
2136  processSave.erase(processSave.begin()+processSave.find(" ",0));
2137 
2138  // Parameters for reconstruction of evolution scales
2139  includeMassiveSave = settingsPtr->flag("Merging:includeMassive");
2140  enforceStrongOrderingSave =
2141  settingsPtr->flag("Merging:enforceStrongOrdering");
2142  scaleSeparationFactorSave =
2143  settingsPtr->parm("Merging:scaleSeparationFactor");
2144  orderInRapiditySave = settingsPtr->flag("Merging:orderInRapidity");
2145 
2146  // Parameters for choosing history probabilistically
2147  nonJoinedNormSave = settingsPtr->parm("Merging:nonJoinedNorm");
2148  fsrInRecNormSave = settingsPtr->parm("Merging:fsrInRecNorm");
2149  pickByFullPSave = settingsPtr->flag("Merging:pickByFullP");
2150  pickByPoPT2Save = settingsPtr->flag("Merging:pickByPoPT2");
2151  includeRedundantSave = settingsPtr->flag("Merging:includeRedundant");
2152 
2153  // Parameters for scale choices
2154  unorderedScalePrescipSave =
2155  settingsPtr->mode("Merging:unorderedScalePrescrip");
2156  unorderedASscalePrescipSave =
2157  settingsPtr->mode("Merging:unorderedASscalePrescrip");
2158  unorderedPDFscalePrescipSave =
2159  settingsPtr->mode("Merging:unorderedPDFscalePrescrip");
2160  incompleteScalePrescipSave =
2161  settingsPtr->mode("Merging:incompleteScalePrescrip");
2162 
2163  // Parameter for allowing swapping of one colour index while reclustering
2164  allowColourShufflingSave =
2165  settingsPtr->flag("Merging:allowColourShuffling");
2166 
2167  // Parameters to allow setting hard process scales to default (dynamical)
2168  // Pythia values.
2169  resetHardQRenSave = settingsPtr->flag("Merging:usePythiaQRenHard");
2170  resetHardQFacSave = settingsPtr->flag("Merging:usePythiaQFacHard");
2171 
2172  // Parameters for choosing history by sum(|pT|)
2173  pickBySumPTSave = settingsPtr->flag("Merging:pickBySumPT");
2174  herwigAcollFSRSave = settingsPtr->parm("Merging:aCollFSR");
2175  herwigAcollISRSave = settingsPtr->parm("Merging:aCollISR");
2176 
2177  // Information on the shower cut-off scale
2178  pT0ISRSave = settingsPtr->parm("SpaceShower:pT0Ref");
2179  pTcutSave = settingsPtr->parm("SpaceShower:pTmin");
2180  pTcutSave = max(pTcutSave,pT0ISRSave);
2181 
2182  // Initialise CKKWL weight
2183  weightCKKWLSave = 1.;
2184  weightFIRSTSave = 0.;
2185  nMinMPISave = 100;
2186  muMISave = -1.;
2187 
2188  // Initialise merging scale
2189  tmsValueSave = 0.;
2190  tmsListSave.resize(0);
2191 
2192  kFactor0jSave = settingsPtr->parm("Merging:kFactor0j");
2193  kFactor1jSave = settingsPtr->parm("Merging:kFactor1j");
2194  kFactor2jSave = settingsPtr->parm("Merging:kFactor2j");
2195 
2196  muFSave = settingsPtr->parm("Merging:muFac");
2197  muRSave = settingsPtr->parm("Merging:muRen");
2198  muFinMESave = settingsPtr->parm("Merging:muFacInME");
2199  muRinMESave = settingsPtr->parm("Merging:muRenInME");
2200 
2201  doWeakClusteringSave = settingsPtr->flag("Merging:allowWeakClustering");
2202  doSQCDClusteringSave = settingsPtr->flag("Merging:allowSQCDClustering");
2203  DparameterSave = settingsPtr->parm("Merging:Dparameter");
2204 
2205  // Save merging scale on maximal number of jets
2206  if ( doKTMergingSave || doUserMergingSave || doPTLundMergingSave
2207  || doUMEPS ) {
2208  // Read merging scale (defined in kT) from input parameter.
2209  tmsValueSave = settingsPtr->parm("Merging:TMS");
2210  nJetMaxSave = settingsPtr->mode("Merging:nJetMax");
2211  nJetMaxNLOSave = -1;
2212  } else if (doMGMergingSave) {
2213  // Read merging scale (defined in kT) from LHE file.
2214  tmsValueSave = hardProcess->tms;
2215  nJetMaxSave = settingsPtr->mode("Merging:nJetMax");
2216  nJetMaxNLOSave = -1;
2217  } else if (doCutBasedMergingSave) {
2218 
2219  // Save list of cuts defining the merging scale.
2220  nJetMaxSave = settingsPtr->mode("Merging:nJetMax");
2221  nJetMaxNLOSave = -1;
2222  // Write tms cut values to list of cut values,
2223  // ordered by DeltaR_{ij}, pT_{i}, Q_{ij}.
2224  tmsListSave.resize(0);
2225  double drms = settingsPtr->parm("Merging:dRijMS");
2226  double ptms = settingsPtr->parm("Merging:pTiMS");
2227  double qms = settingsPtr->parm("Merging:QijMS");
2228  tmsListSave.push_back(drms);
2229  tmsListSave.push_back(ptms);
2230  tmsListSave.push_back(qms);
2231 
2232  }
2233 
2234  // Read additional settingsPtr->for NLO merging methods.
2235  if ( doNL3 || doUNLOPS || doEstimateXSection ) {
2236  tmsValueSave = settingsPtr->parm("Merging:TMS");
2237  nJetMaxSave = settingsPtr->mode("Merging:nJetMax");
2238  nJetMaxNLOSave = settingsPtr->mode("Merging:nJetMaxNLO");
2239  }
2240 
2241  tmsValueNow = tmsValueSave;
2242 
2243  // Internal Pythia cross section should not include NLO merging weights.
2244  if ( doNL3 || doUNLOPS ) includeWGTinXSECSave = false;
2245 
2246  hasJetMaxLocal = false;
2247  nJetMaxLocal = nJetMaxSave;
2248  nJetMaxNLOLocal = nJetMaxNLOSave;
2249 
2250  // Check if external shower plugin should be used.
2251  useShowerPluginSave = settingsPtr->flag("Merging:useShowerPlugin");
2252 
2253  bool writeBanner = doKTMergingSave || doMGMergingSave
2254  || doUserMergingSave
2255  || doNL3 || doUNLOPS || doUMEPS
2256  || doPTLundMergingSave || doCutBasedMergingSave;
2257 
2258  if (!writeBanner) return;
2259 
2260  // Write banner.
2261  cout << "\n *------------------ MEPS Merging Initialization ---------------"
2262  << "---*";
2263  cout << "\n | "
2264  << " |\n";
2265  if ( doKTMergingSave || doMGMergingSave || doUserMergingSave
2266  || doPTLundMergingSave || doCutBasedMergingSave )
2267  cout << " | CKKW-L merge "
2268  << " |\n"
2269  << " |"<< setw(34) << processSave << " with up to"
2270  << setw(3) << nJetMaxSave << " additional jets |\n";
2271  else if ( doNL3 )
2272  cout << " | NL3 merge "
2273  << " |\n"
2274  << " |" << setw(31) << processSave << " with jets up to"
2275  << setw(3) << nJetMaxNLOSave << " correct to NLO |\n"
2276  << " | and up to" << setw(3) << nJetMaxSave
2277  << " additional jets included by CKKW-L merging at LO |\n";
2278  else if ( doUNLOPS )
2279  cout << " | UNLOPS merge "
2280  << " |\n"
2281  << " |" << setw(31) << processSave << " with jets up to"
2282  << setw(3)<< nJetMaxNLOSave << " correct to NLO |\n"
2283  << " | and up to" << setw(3) << nJetMaxSave
2284  << " additional jets included by UMEPS merging at LO |\n";
2285  else if ( doUMEPS )
2286  cout << " | UMEPS merge "
2287  << " |\n"
2288  << " |" << setw(34) << processSave << " with up to"
2289  << setw(3) << nJetMaxSave << " additional jets |\n";
2290 
2291  if ( doKTMergingSave )
2292  cout << " | Merging scale is defined in kT, with value ktMS = "
2293  << tmsValueSave << " GeV";
2294  else if ( doMGMergingSave )
2295  cout << " | Perform automanted MG/ME merging \n"
2296  << " | Merging scale is defined in kT, with value ktMS = "
2297  << setw(6) << fixed << setprecision(1) << tmsValueSave << " GeV |";
2298  else if ( doUserMergingSave )
2299  cout << " | Merging scale is defined by the user, with value tMS = "
2300  << setw(6) << fixed << setprecision(1) << tmsValueSave << " |";
2301  else if ( doPTLundMergingSave )
2302  cout << " | Merging scale is defined by Lund pT, with value tMS = "
2303  << setw(6) << fixed << setprecision(1) << tmsValueSave << " GeV |";
2304  else if ( doCutBasedMergingSave )
2305  cout << " | Merging scale is defined by combination of Delta R_{ij}, pT_i "
2306  << " |\n"
2307  << " | and Q_{ij} cut, with values "
2308  << " |\n"
2309  << " | Delta R_{ij,min} = "
2310  << setw(7) << scientific << setprecision(2) << tmsListSave[0]
2311  << " |\n"
2312  << " | pT_{i,min} = "
2313  << setw(6) << fixed << setprecision(1) << tmsListSave[1]
2314  << " GeV |\n"
2315  << " | Q_{ij,min} = "
2316  << setw(6) << fixed << setprecision(1) << tmsListSave[2]
2317  << " GeV |";
2318  else if ( doNL3TreeSave )
2319  cout << " | Generate tree-level O(alpha_s)-subtracted events "
2320  << " |\n"
2321  << " | Merging scale is defined by Lund pT, with value tMS = "
2322  << setw(6) << fixed << setprecision(1) << tmsValueSave << " GeV |";
2323  else if ( doNL3LoopSave )
2324  cout << " | Generate virtual correction unit-weight events "
2325  << " |\n"
2326  << " | Merging scale is defined by Lund pT, with value tMS = "
2327  << setw(6) << fixed << setprecision(1) << tmsValueSave << " GeV |";
2328  else if ( doNL3SubtSave )
2329  cout << " | Generate reclustered tree-level events "
2330  << " |\n"
2331  << " | Merging scale is defined by Lund pT, with value tMS = "
2332  << setw(6) << fixed << setprecision(1) << tmsValueSave << " GeV |";
2333  else if ( doUNLOPSTreeSave )
2334  cout << " | Generate tree-level O(alpha_s)-subtracted events "
2335  << " |\n"
2336  << " | Merging scale is defined by Lund pT, with value tMS = "
2337  << setw(6) << fixed << setprecision(1) << tmsValueSave << " GeV |";
2338  else if ( doUNLOPSLoopSave )
2339  cout << " | Generate virtual correction unit-weight events "
2340  << " |\n"
2341  << " | Merging scale is defined by Lund pT, with value tMS = "
2342  << setw(6) << fixed << setprecision(1) << tmsValueSave << " GeV |";
2343  else if ( doUNLOPSSubtSave )
2344  cout << " | Generate reclustered tree-level events "
2345  << " |\n"
2346  << " | Merging scale is defined by Lund pT, with value tMS = "
2347  << setw(6) << fixed << setprecision(1) << tmsValueSave << " GeV |";
2348  else if ( doUNLOPSSubtNLOSave )
2349  cout << " | Generate reclustered loop-level events "
2350  << " |\n"
2351  << " | Merging scale is defined by Lund pT, with value tMS = "
2352  << setw(6) << fixed << setprecision(1) << tmsValueSave << " GeV |";
2353  else if ( doUMEPSTreeSave )
2354  cout << " | Generate tree-level events "
2355  << " |\n"
2356  << " | Merging scale is defined by Lund pT, with value tMS = "
2357  << setw(6) << fixed << setprecision(1) << tmsValueSave << " GeV |";
2358  else if ( doUMEPSSubtSave )
2359  cout << " | Generate reclustered tree-level events "
2360  << " |\n"
2361  << " | Merging scale is defined by Lund pT, with value tMS = "
2362  << setw(6) << fixed << setprecision(1) << tmsValueSave << " GeV |";
2363 
2364  cout << "\n | "
2365  << " |";
2366  cout << "\n *-------------- END MEPS Merging Initialization ---------------"
2367  << "---*\n\n";
2368 
2369 }
2370 
2371 //--------------------------------------------------------------------------
2372 
2373 // Function to check if emission should be rejected.
2374 
2375 bool MergingHooks::doVetoEmission( const Event& event) {
2376 
2377  // Do nothing in trial showers, or after first step.
2378  if ( doIgnoreEmissionsSave ) return false;
2379 
2380  // Do nothing in CKKW-L
2381  if ( doUserMerging() || doMGMerging() || doKTMerging()
2382  || doPTLundMerging() || doCutBasedMerging() )
2383  return false;
2384 
2385  // For NLO merging, count and veto emissions above the merging scale
2386  bool veto = false;
2387  // Get number of clustering steps
2388  int nSteps = getNumberOfClusteringSteps(event);
2389  // Get merging scale in current event
2390  double tnow = tmsNow( event);
2391 
2392  // Get maximal number of additional jets
2393  int nJetMax = nMaxJets();
2394  // Always remove emissions above the merging scale for
2395  // samples containing reclusterings!
2396  if ( nRecluster() > 0 ) nSteps = max(1, min(nJetMax-2, 1));
2397  // Check veto condition
2398  if ( nSteps - 1 < nJetMax && nSteps >= 1 && tnow > tms() ) veto = true;
2399 
2400  // Do not veto if state already includes MPI.
2401  if ( infoPtr->nMPI() > 1 ) veto = false;
2402 
2403  // When performing NL3 merging of tree-level events, reset the
2404  // CKKWL weight.
2405  if ( veto && doNL3Tree() ) setWeightCKKWL(0.);
2406 
2407  // If the emission is allowed, do not check any further emissions
2408  if ( !veto ) doIgnoreEmissionsSave = true;
2409 
2410  // Done
2411  return veto;
2412 
2413 }
2414 
2415 //--------------------------------------------------------------------------
2416 
2417 // Function to check if emission should be rejected.
2418 
2419 bool MergingHooks::doVetoStep( const Event& process, const Event& event,
2420  bool doResonance ) {
2421 
2422  // Do nothing in trial showers, or after first step.
2423  if ( doIgnoreStepSave && !doResonance ) return false;
2424 
2425  // Do nothing in UMEPS or UNLOPS
2426  if ( doUMEPSTree() || doUMEPSSubt() || doUMEPSMerging() || doUNLOPSTree()
2427  || doUNLOPSLoop() || doUNLOPSSubt() || doUNLOPSSubtNLO()
2428  || doUNLOPSMerging() )
2429  return false;
2430 
2431  // Get number of clustering steps. If necessary, remove resonance
2432  // decay products first.
2433  int nSteps = 0;
2434  if ( getProcessString().find("inc") != string::npos )
2435  nSteps = getNumberOfClusteringSteps( bareEvent( process, false) );
2436  else nSteps = (doResonance) ? getNumberOfClusteringSteps(process)
2437  : getNumberOfClusteringSteps( bareEvent( process, false) );
2438 
2439  int nStepsAfter = getNumberOfClusteringSteps(event);
2440 
2441  // Get maximal number of additional jets.
2442  int nJetMax = nMaxJets();
2443  // Get merging scale in current event.
2444  double tnow = tmsNow( event );
2445 
2446  // Do not print zero-weight events.
2447  // For non-resonant showers, simply check veto. If event should indeed be
2448  // vetoed, save the current pT and weights in case the veto needs to be
2449  // revoked.
2450  if ( !doResonance ) {
2451 
2452  // Store pT to check if veto needs to be revoked later.
2453  pTsave = infoPtr->pTnow();
2454  if ( nRecluster() == 1) nSteps--;
2455 
2456  // Store veto inputs to perform veto at a later stage.
2457  if (!applyVeto) {
2458  setEventVetoInfo(nSteps, tnow);
2459  return false;
2460  }
2461 
2462  // Check merging veto condition.
2463  bool veto = false;
2464  if ( nStepsAfter > nSteps && nSteps > nMaxJetsNLO() && nSteps < nJetMax
2465  && tnow > tms() ) {
2466  // Set weight to zero if event should be vetoed.
2467  weightCKKWL1Save = 0.;
2468  // Save weight before veto, in case veto needs to be revoked.
2469  weightCKKWL2Save = getWeightCKKWL();
2470  // Reset stored weights.
2471  if ( !includeWGTinXSEC() ) setWeightCKKWL(0.);
2472  if ( includeWGTinXSEC() ) infoPtr->updateWeight(0.);
2473  veto = true;
2474  }
2475 
2476  // Done
2477  return veto;
2478 
2479  // For resonant showers, check if any previous veto should be revoked.
2480  // This means we treat showers off resonance decay products identical to
2481  // MPI: If a hard resonance emission has been produced, the event should
2482  // have been kept. Following this reasoning, it might be necessary to revoke
2483  // any previous veto.
2484  } else {
2485 
2486  // Initialise switch to revoke vetoing.
2487  bool revokeVeto = false;
2488 
2489  // Nothing to check if pTsave was not stored, i.e. no emission to
2490  // possibly veto was recorded.
2491  // Only allow revoking the veto for diboson processes, with resonant
2492  // electroweak bosons
2493  bool check = (nHardInLeptons() == 0)&& (nHardOutLeptons() == 2)
2494  && (nHardOutPartons() == 2);
2495 
2496  // For current purpose only!!!
2497  check = false;
2498 
2499  // For hadronic resonance decays at hadron colliders, do not veto
2500  // events with a hard emission of the resonance decay products,
2501  // since such states are not included in the matrix element
2502  if ( pTsave > 0. && check ) {
2503 
2504  // Check how many resonance decay systems are allowed
2505  int nResNow = nResInCurrent();
2506 
2507  // Find systems really containing only emission off a resonance
2508  // decay
2509  vector<int>goodSys;
2510  // Resonance decay systems are considered last, thus at the end of
2511  // the list
2512  int sysSize = partonSystemsPtr->sizeSys();
2513  for ( int i=0; i < nResNow; ++i ) {
2514  if ( partonSystemsPtr->sizeOut(sysSize - 1 - i) == 3 )
2515  goodSys.push_back(sysSize - 1 - i);
2516  }
2517 
2518  // Check the members of the resonance decay systems
2519  for ( int i=0; i < int(goodSys.size()); ++i ) {
2520 
2521  // Save the (three) members of the resonance decay system
2522  int iMem1 = partonSystemsPtr->getOut(goodSys[i],0);
2523  int iMem2 = partonSystemsPtr->getOut(goodSys[i],1);
2524  int iMem3 = partonSystemsPtr->getOut(goodSys[i],2);
2525 
2526  // Now find emitted gluon or gamma
2527  int iEmtGlue = ((event[iMem1].id() == 21) ? iMem1
2528  : ((event[iMem2].id() == 21) ? iMem2
2529  : ((event[iMem3].id() == 21) ? iMem3: 0)));
2530  int iEmtGamm = ((event[iMem1].id() == 22) ? iMem1
2531  : ((event[iMem2].id() == 22) ? iMem2
2532  : ((event[iMem3].id() == 22) ? iMem3: 0)));
2533  // Per system, only one emission
2534  int iEmt = (iEmtGlue != 0) ? iEmtGlue : iEmtGamm;
2535 
2536  int iRad = 0;
2537  int iRec = 0;
2538  if ( iEmt == iMem1 ) {
2539  iRad = (event[iMem2].mother1() != event[iMem2].mother2())
2540  ? iMem2 : iMem3;
2541  iRec = (event[iMem3].mother1() == event[iMem3].mother2())
2542  ? iMem3 : iMem2;
2543  } else if ( iEmt == iMem2 ) {
2544  iRad = (event[iMem1].mother1() != event[iMem1].mother2())
2545  ? iMem1 : iMem3;
2546  iRec = (event[iMem3].mother1() == event[iMem3].mother2())
2547  ? iMem3 : iMem1;
2548  } else {
2549  iRad = (event[iMem1].mother1() != event[iMem1].mother2())
2550  ? iMem1 : iMem2;
2551  iRec = (event[iMem2].mother1() == event[iMem2].mother2())
2552  ? iMem2 : iMem1;
2553  }
2554 
2555  double pTres = rhoPythia(event, iRad, iEmt, iRec, 1);
2556 
2557  // Revoke previous veto of last emission if a splitting of the
2558  // resonance produced a harder parton, i.e. we are inside the
2559  // PS region
2560  if ( pTres > pTsave ) {
2561  revokeVeto = true;
2562  // Do nothing (i.e. allow other first emission veto) for soft
2563  // splitting
2564  } else {
2565  revokeVeto = false;
2566  }
2567  // Done with one system
2568  }
2569  // Done with all systems
2570  }
2571 
2572  // Check veto condition
2573  bool veto = false;
2574  if ( revokeVeto && check ) {
2575  setWeightCKKWL(weightCKKWL2Save);
2576  } else if ( check ) {
2577  setWeightCKKWL(weightCKKWL1Save);
2578  if ( weightCKKWL1Save == 0. ) veto = true;
2579  }
2580 
2581  // Check veto condition.
2582  if ( !check && nSteps > nMaxJetsNLO() && nSteps < nJetMax && tnow > tms()){
2583  // Set stored weights to zero.
2584  if ( !includeWGTinXSEC() ) setWeightCKKWL(0.);
2585  if ( includeWGTinXSEC() ) infoPtr->updateWeight(0.);
2586  // Now allow veto.
2587  veto = true;
2588  }
2589 
2590  // If the emission is allowed, do not check any further emissions
2591  if ( !veto || !doIgnoreStepSave ) doIgnoreStepSave = true;
2592 
2593  // Done
2594  return veto;
2595 
2596  }
2597 
2598  // Done
2599  return false;
2600 
2601 }
2602 
2603 //--------------------------------------------------------------------------
2604 
2605 // Return event stripped from decay products.
2606 
2607 Event MergingHooks::bareEvent(const Event& inputEventIn,
2608  bool storeInputEvent ) {
2609 
2610  // Find and detach decay products.
2611  Event newProcess = Event();
2612  newProcess.init("(hard process-modified)", particleDataPtr);
2613 
2614  // If desired, store input event.
2615  if ( storeInputEvent ) {
2616  resonances.resize(0);
2617  inputEvent.clear();
2618  for (int i = 0; i < inputEventIn.size(); ++i)
2619  inputEvent.append( inputEventIn[i] );
2620  for (int i = 0; i < inputEventIn.sizeJunction(); ++i)
2621  inputEvent.appendJunction( inputEventIn.getJunction(i) );
2622  inputEvent.saveSize();
2623  inputEvent.saveJunctionSize();
2624  }
2625 
2626  // Now remove decay products.
2627  if ( doRemoveDecayProducts ) {
2628 
2629  // Add the beam and initial partons to the event record.
2630  for (int i = 0; i < inputEventIn.size(); ++ i) {
2631  if ( inputEventIn[i].mother1() > 4
2632  || inputEventIn[i].statusAbs() == 22
2633  || inputEventIn[i].statusAbs() == 23)
2634  break;
2635  newProcess.append(inputEventIn[i]);
2636  }
2637 
2638  // Add the intermediate particles to the event record.
2639  for (int i = 0; i < inputEventIn.size(); ++ i) {
2640  if (inputEventIn[i].mother1() > 4) break;
2641  if ( inputEventIn[i].status() == -22) {
2642  int j = newProcess.append(inputEventIn[i]);
2643  newProcess[j].statusPos();
2644  if ( storeInputEvent ) resonances.push_back( make_pair(j, i) );
2645  newProcess[j].daughters(0, 0);
2646  }
2647  }
2648 
2649  // Add remaining outgoing particles to the event record.
2650  for (int i = 0; i < inputEventIn.size(); ++ i) {
2651  if (inputEventIn[i].mother1() > 4) break;
2652  if ( inputEventIn[i].statusAbs() != 11
2653  && inputEventIn[i].statusAbs() != 12
2654  && inputEventIn[i].statusAbs() != 21
2655  && inputEventIn[i].statusAbs() != 22)
2656  newProcess.append(inputEventIn[i]);
2657  }
2658 
2659  // Update event colour tag to maximum in whole process.
2660  int maxColTag = 0;
2661  for (int i = 0; i < inputEventIn.size(); ++ i) {
2662  if ( inputEventIn[i].col() > maxColTag )
2663  maxColTag = inputEventIn[i].col();
2664  if ( inputEventIn[i].acol() > maxColTag )
2665  maxColTag = inputEventIn[i].acol();
2666  }
2667  newProcess.initColTag(maxColTag);
2668 
2669  // Copy junctions from process to newProcess.
2670  for (int i = 0; i < inputEventIn.sizeJunction(); ++i)
2671  newProcess.appendJunction( inputEventIn.getJunction(i));
2672 
2673  newProcess.saveSize();
2674  newProcess.saveJunctionSize();
2675 
2676  } else {
2677  newProcess = inputEventIn;
2678  }
2679 
2680  // Remember scale
2681  newProcess.scale( inputEventIn.scale() );
2682 
2683  // Done
2684  return newProcess;
2685 
2686 }
2687 
2688 //--------------------------------------------------------------------------
2689 
2690 // Write event with decay products attached to argument. Only possible if an
2691 // input event with decay producs had been stored before.
2692 
2693 bool MergingHooks::reattachResonanceDecays(Event& process ) {
2694 
2695  // Now reattach the decay products.
2696  if ( doRemoveDecayProducts && inputEvent.size() > 0 ) {
2697 
2698  int sizeBef = process.size();
2699  // Vector of resonances for which the decay products were already attached.
2700  vector<int> iAftChecked;
2701  // Reset daughters and status of intermediate particles.
2702  for ( int i = 0; i < int(resonances.size()); ++i ) {
2703  for (int j = 0; j < sizeBef; ++j ) {
2704  if ( j != resonances[i].first ) continue;
2705 
2706  int iOldDaughter1 = inputEvent[resonances[i].second].daughter1();
2707  int iOldDaughter2 = inputEvent[resonances[i].second].daughter2();
2708 
2709  // Get momenta in case of reclustering.
2710  int iHardMother = resonances[i].second;
2711  Particle& hardMother = inputEvent[iHardMother];
2712  // Find current mother copy (after clustering).
2713  int iAftMother = 0;
2714  for ( int k = 0; k < process.size(); ++k )
2715  if ( process[k].id() == inputEvent[resonances[i].second].id() ) {
2716  // Only attempt if decays of this resonance were not attached.
2717  bool checked = false;
2718  for ( int l = 0; l < int(iAftChecked.size()); ++l )
2719  if ( k == iAftChecked[l] )
2720  checked = true;
2721  if ( !checked ) {
2722  iAftChecked.push_back(k);
2723  iAftMother = k;
2724  break;
2725  }
2726  }
2727 
2728  Particle& aftMother = process[iAftMother];
2729 
2730  // Resonance can have been moved by clustering,
2731  // so prepare to update colour and momentum information for system.
2732  int colBef = hardMother.col();
2733  int acolBef = hardMother.acol();
2734  int colAft = aftMother.col();
2735  int acolAft = aftMother.acol();
2736  RotBstMatrix M;
2737  M.bst( hardMother.p(), aftMother.p());
2738 
2739  // Attach resonance decay products.
2740  int iNewDaughter1 = 0;
2741  int iNewDaughter2 = 0;
2742  for ( int k = iOldDaughter1; k <= iOldDaughter2; ++k ) {
2743  if ( k == iOldDaughter1 )
2744  iNewDaughter1 = process.append(inputEvent[k] );
2745  else
2746  iNewDaughter2 = process.append(inputEvent[k] );
2747  process.back().statusPos();
2748  Particle& now = process.back();
2749  // Update colour and momentum information.
2750  if (now.col() != 0 && now.col() == colBef ) now.col(colAft);
2751  if (now.acol() != 0 && now.acol() == acolBef) now.acol(acolAft);
2752  now.rotbst( M);
2753  // Update vertex information.
2754  if (now.hasVertex()) now.vProd( aftMother.vDec() );
2755  // Update mothers.
2756  now.mothers(iAftMother,0);
2757  }
2758 
2759  process[iAftMother].daughters( iNewDaughter1, iNewDaughter2 );
2760  process[iAftMother].statusNeg();
2761 
2762  // Loop through event and attach remaining decays
2763  int iDec = 0;
2764  do {
2765  if ( process[iDec].isFinal() && process[iDec].canDecay()
2766  && process[iDec].mayDecay() && process[iDec].isResonance() ) {
2767 
2768  int iD1 = process[iDec].daughter1();
2769  int iD2 = process[iDec].daughter2();
2770 
2771  // Done if no daughters exist.
2772  if ( iD1 == 0 || iD2 == 0 ) continue;
2773 
2774  // Attach daughters.
2775  int iNewDaughter12 = 0;
2776  int iNewDaughter22 = 0;
2777  for ( int k = iD1; k <= iD2; ++k ) {
2778  if ( k == iD1 )
2779  iNewDaughter12 = process.append(inputEvent[k] );
2780  else
2781  iNewDaughter22 = process.append(inputEvent[k] );
2782  process.back().statusPos();
2783  Particle& now = process.back();
2784  // Update colour and momentum information.
2785  if (now.col() != 0 && now.col() == colBef ) now.col(colAft);
2786  if (now.acol()!= 0 && now.acol()== acolBef) now.acol(acolAft);
2787  now.rotbst( M);
2788  // Update vertex information.
2789  if (now.hasVertex()) now.vProd( process[iDec].vDec() );
2790  // Update mothers.
2791  now.mothers(iDec,0);
2792  }
2793 
2794  // Modify mother status and daughters.
2795  process[iDec].status(-22);
2796  process[iDec].daughters(iNewDaughter12, iNewDaughter22);
2797 
2798  // End of loop over all entries.
2799  }
2800  } while (++iDec < process.size());
2801  } // End loop over process entries.
2802  } // End loop over resonances.
2803 
2804  // Update event colour tag to maximum in whole process.
2805  int maxColTag = 0;
2806  for (int i = 0; i < process.size(); ++ i) {
2807  if (process[i].col() > maxColTag) maxColTag = process[i].col();
2808  if (process[i].acol() > maxColTag) maxColTag = process[i].acol();
2809  }
2810  process.initColTag(maxColTag);
2811 
2812  }
2813 
2814  // Done.
2815  return (doRemoveDecayProducts) ? inputEvent.size() > 0 : true;
2816 
2817 }
2818 
2819 //--------------------------------------------------------------------------
2820 
2821 bool MergingHooks::isInHard( int iPos, const Event& event){
2822 
2823  // MPI not part of hard process
2824  if ( event[iPos].statusAbs() > 30 && event[iPos].statusAbs() < 40 )
2825  return false;
2826  // Beam remnants and hadronisation not part of hard process
2827  if ( event[iPos].statusAbs() > 60 )
2828  return false;
2829 
2830  // Still MPI: Check that the particle is not due to radiation off MPIs.
2831  // First get all intermediate MPI partons in the state.
2832  vector<int> mpiParticlePos;
2833  mpiParticlePos.clear();
2834  for ( int i=0; i < event.size(); ++i )
2835  if ( event[i].statusAbs() > 30
2836  && event[i].statusAbs() < 40 )
2837  mpiParticlePos.push_back(i);
2838  // Disregard any parton iPos that has MPI ancestors.
2839  for ( int i=0; i < int(mpiParticlePos.size()); ++i)
2840  if ( event[iPos].isAncestor( mpiParticlePos[i]) )
2841  return false;
2842 
2843  // Disallow other systems.
2844  // Get sub-system of particles for iPos
2845  int iSys = partonSystemsPtr->getSystemOf(iPos, !event[iPos].isFinal() );
2846  if ( iSys > 0 ) {
2847  // Check all partons belonging to the same system as iPos. If any is
2848  // produced in MPI or has MPI ancestors, the whole system is not the
2849  // hard subprocess, i.e. iPos is not in the hard subprocess.
2850  int sysSize = partonSystemsPtr->sizeAll(iSys);
2851  for ( int i = 0; i < sysSize; ++i ) {
2852  int iPosNow = partonSystemsPtr->getAll( iSys, i );
2853  // MPI not part of hard process
2854  if ( event[iPosNow].statusAbs() > 30
2855  && event[iPosNow].statusAbs() < 40 )
2856  return false;
2857  // Disregard any parton iPos that has MPI ancestors.
2858  for ( int j=0; j < int(mpiParticlePos.size()); ++j)
2859  if ( event[iPosNow].isAncestor( mpiParticlePos[j]) )
2860  return false;
2861  // Beam remnants and hadronisation not part of hard process
2862  if ( event[iPosNow].statusAbs() > 60 )
2863  return false;
2864  }
2865  }
2866 
2867  // Check if any ancestor contains the hard incoming partons as daughters.
2868  // Begin loop to trace upwards from the daughter.
2869  bool containsInitialParton = false;
2870  int iUp = iPos;
2871  for ( ; ; ) {
2872  // If out of range then failed to find match.
2873  if (iUp <= 0 || iUp > event.size()) break;
2874  // If positive match then done.
2875  if ( iUp == 3 || iUp == 4 ) {
2876  containsInitialParton = true;
2877  break;
2878  }
2879  if ( event[iUp].mother1() == 1
2880  && (event[iUp].daughter1() == 3 || event[iUp].daughter2() == 3) ) {
2881  containsInitialParton = true;
2882  break;
2883  }
2884  if ( event[iUp].mother1() == 2
2885  && (event[iUp].daughter1() == 4 || event[iUp].daughter2() == 4) ) {
2886  containsInitialParton = true;
2887  break;
2888  }
2889  // If unique mother then keep on moving up the chain.
2890  iUp = event[iUp].mother1();
2891  }
2892 
2893  if ( !containsInitialParton ) return false;
2894 
2895  // Done
2896  return true;
2897 
2898 }
2899 
2900 //--------------------------------------------------------------------------
2901 
2902 // Function to return the number of clustering steps for the current event
2903 
2904 int MergingHooks::getNumberOfClusteringSteps(const Event& event,
2905  bool resetJetMax ){
2906 
2907  // Count the number of final state partons
2908  int nFinalPartons = 0;
2909  for ( int i=0; i < event.size(); ++i)
2910  if ( event[i].isFinal()
2911  && isInHard( i, event)
2912  && (event[i].isQuark() || event[i].isGluon()) )
2913  nFinalPartons++;
2914 
2915  // Count the number of final state leptons
2916  int nFinalLeptons = 0;
2917  for( int i=0; i < event.size(); ++i)
2918  if ( event[i].isFinal() && isInHard( i, event) && event[i].isLepton())
2919  nFinalLeptons++;
2920 
2921  // Add neutralinos to number of leptons
2922  for( int i=0; i < event.size(); ++i)
2923  if ( event[i].isFinal() && isInHard( i, event)
2924  && event[i].idAbs() == 1000022)
2925  nFinalLeptons++;
2926 
2927  // Add sleptons to number of leptons
2928  for( int i=0; i < event.size(); ++i)
2929  if ( event[i].isFinal() && isInHard( i, event)
2930  && (event[i].idAbs() == 1000011
2931  || event[i].idAbs() == 2000011
2932  || event[i].idAbs() == 1000013
2933  || event[i].idAbs() == 2000013
2934  || event[i].idAbs() == 1000015
2935  || event[i].idAbs() == 2000015) )
2936  nFinalLeptons++;
2937 
2938  // Count the number of final state electroweak bosons
2939  int nFinalBosons = 0;
2940  for( int i=0; i < event.size(); ++i)
2941  if ( event[i].isFinal() && isInHard( i, event)
2942  && ( event[i].idAbs() == 22
2943  || event[i].idAbs() == 23
2944  || event[i].idAbs() == 24
2945  || event[i].idAbs() == 25 ) )
2946  nFinalBosons++;
2947 
2948  // Save sum of all final state particles
2949  int nFinal = nFinalPartons + nFinalLeptons
2950  + 2*(nFinalBosons - nHardOutBosons() );
2951 
2952  // Return the difference to the core process outgoing particles
2953  int nsteps = nFinal - nHardOutPartons() - nHardOutLeptons();
2954 
2955  // For inclusive handling, the number of reclustering steps
2956  // can be different within a single sample.
2957  if ( getProcessString().find("inc") != string::npos ) {
2958 
2959  // Final particle counters
2960  int njInc = 0, naInc = 0, nzInc = 0, nwInc =0;
2961  for (int i=0; i < event.size(); ++i){
2962  if ( event[i].isFinal() && event[i].colType() != 0 ) njInc++;
2963  if ( getProcessString().find("Ainc") != string::npos
2964  && event[i].isFinal() && event[i].idAbs() == 22 ) naInc++;
2965  if ( getProcessString().find("Zinc") != string::npos
2966  && event[i].isFinal() && event[i].idAbs() == 23 ) nzInc++;
2967  if ( getProcessString().find("Winc") != string::npos
2968  && event[i].isFinal() && event[i].idAbs() == 24 ) nwInc++;
2969  }
2970 
2971  // Set steps for QCD or QCD+QED events: Need at least two
2972  // massless particles at lowest multiplicity.
2973  if (nzInc == 0 && nwInc == 0 && njInc+naInc > 1) {
2974  nsteps = naInc + njInc - 2;
2975  if (resetJetMax) {
2976  hasJetMaxLocal = true;
2977  nJetMaxLocal = nJetMaxSave - 2;
2978  nRequestedSave = nsteps;
2979  }
2980  }
2981 
2982  // Set steps for events containing heavy bosons. Need at least one
2983  // massive particle at lowest multiplicity.
2984  if ( nzInc > 0 || nwInc > 0 ) {
2985  nsteps = njInc + naInc + nzInc + nwInc - 1;
2986  if (resetJetMax) {
2987  hasJetMaxLocal = true;
2988  nJetMaxLocal = nJetMaxSave - 1;
2989  nRequestedSave = nsteps;
2990  }
2991  }
2992 
2993  } // dynamical handling of steps
2994 
2995  // Return the difference to the core process outgoing particles
2996  return nsteps;
2997 
2998 }
2999 
3000 //--------------------------------------------------------------------------
3001 
3002 // Function to check if event contains an emission not present in the hard
3003 // process.
3004 
3005 bool MergingHooks::isFirstEmission(const Event& event ) {
3006 
3007  // If the beam remnant treatment or hadronisation has already started, do
3008  // no veto.
3009  for ( int i=0; i < event.size(); ++i)
3010  if ( event[i].statusAbs() > 60 ) return false;
3011 
3012  // Count particle types
3013  int nFinalQuarks = 0;
3014  int nFinalGluons = 0;
3015  int nFinalLeptons = 0;
3016  int nFinalBosons = 0;
3017  int nFinalPhotons = 0;
3018  int nFinal = 0;
3019  for( int i=0; i < event.size(); ++i) {
3020  if (event[i].isFinal() && isInHard(i, event) ){
3021  if ( event[i].spinType() == 2 && event[i].colType() == 0)
3022  nFinalLeptons++;
3023  if ( event[i].id() == 23
3024  || event[i].idAbs() == 24
3025  || event[i].id() == 25)
3026  nFinalBosons++;
3027  if ( event[i].id() == 22)
3028  nFinalPhotons++;
3029  if ( event[i].isQuark())
3030  nFinalQuarks++;
3031  if ( event[i].isGluon())
3032  nFinalGluons++;
3033  if ( !event[i].isDiquark() )
3034  nFinal++;
3035  }
3036  }
3037 
3038  // Return highest value if the event does not contain any final state
3039  // coloured particles.
3040  if (nFinalQuarks + nFinalGluons == 0) return false;
3041 
3042  // Use MergingHooks functions to get information on the hard process.
3043  int nLeptons = nHardOutLeptons();
3044 
3045  // The state is already in the PS region if the number of leptons had been
3046  // increased by QED splittings.
3047  if (nFinalLeptons > nLeptons) return false;
3048 
3049  // If the mumber of photons if larger than in the hard process, QED
3050  // radiation has pushed the state into the PS region.
3051  int nPhotons = 0;
3052  for(int i =0; i< int(hardProcess->hardOutgoing1.size()); ++i)
3053  if (hardProcess->hardOutgoing1[i] == 22)
3054  nPhotons++;
3055  for(int i =0; i< int(hardProcess->hardOutgoing2.size()); ++i)
3056  if (hardProcess->hardOutgoing2[i] == 22)
3057  nPhotons++;
3058  if (nFinalPhotons > nPhotons) return false;
3059 
3060  // Done
3061  return true;
3062 }
3063 
3064 //--------------------------------------------------------------------------
3065 
3066 // Function to set the correct starting scales of the shower.
3067 // Note: 2 -> 2 QCD systems can be produced by MPI. Hence, there is an
3068 // overlap between MPI and "hard" 2 -> 2 QCD systems which needs to be
3069 // removed by no-MPI probabilities. This means that for any "hard" 2 -> 2 QCD
3070 // system, multiparton interactions should start at the maximal scale
3071 // of multiple interactions. The same argument holds for any "hard" process
3072 // that overlaps with MPI.
3073 
3074 bool MergingHooks::setShowerStartingScales( bool isTrial,
3075  bool doMergeFirstEmm, double& pTscaleIn, const Event& event,
3076  double& pTmaxFSRIn, bool& limitPTmaxFSRIn,
3077  double& pTmaxISRIn, bool& limitPTmaxISRIn,
3078  double& pTmaxMPIIn, bool& limitPTmaxMPIIn ) {
3079 
3080  // Local copies of power/wimpy shower booleans and scales.
3081  bool limitPTmaxFSR = limitPTmaxFSRIn;
3082  bool limitPTmaxISR = limitPTmaxISRIn;
3083  bool limitPTmaxMPI = limitPTmaxMPIIn;
3084  double pTmaxFSR = pTmaxFSRIn;
3085  double pTmaxISR = pTmaxISRIn;
3086  double pTmaxMPI = pTmaxMPIIn;
3087  double pTscale = pTscaleIn;
3088 
3089  // Merging of EW+QCD showers with matrix elements: Ensure that
3090  // 1. any event with more than one final state particle will be showered
3091  // from the reconstructed transverse momentum of the last emission,
3092  // even if the factorisation scale is low.
3093  // 2. the shower starting scale for events with no emission is given by
3094  // the (user-defined) choice.
3095  bool isInclusive = ( getProcessString().find("inc") != string::npos );
3096 
3097  // Check if the process only contains two outgoing partons. If so, then
3098  // this process could also have been produced by MPI. Thus, the MPI starting
3099  // scale would need to be set accordingly to correctly attach a
3100  // "no-MPI-probability" to multi-jet events. ("Hard" MPI are included
3101  // by not restricting MPI when showering the lowest-multiplicity sample.)
3102  double pT2to2 = 0;
3103  int nFinalPartons = 0, nInitialPartons = 0, nFinalOther = 0;
3104  for ( int i = 0; i < event.size(); ++i ) {
3105  if ( (event[i].mother1() == 1 || event[i].mother1() == 2 )
3106  && (event[i].idAbs() < 6 || event[i].id() == 21) )
3107  nInitialPartons++;
3108  if (event[i].isFinal() && (event[i].idAbs() < 6 || event[i].id() == 21)) {
3109  nFinalPartons++;
3110  pT2to2 = event[i].pT();
3111  } else if ( event[i].isFinal() ) nFinalOther++;
3112  }
3113  bool is2to2QCD = ( nFinalPartons == 2 && nInitialPartons == 2
3114  && nFinalOther == 0 );
3115  bool hasMPIoverlap = is2to2QCD;
3116  bool is2to1 = ( nFinalPartons == 0 );
3117 
3118  double scale = event.scale();
3119 
3120  // SET THE STARTING SCALES FOR TRIAL SHOWERS.
3121  if ( isTrial ) {
3122 
3123  // Reset shower and MPI scales.
3124  pTmaxISR = pTmaxFSR = pTmaxMPI = scale;
3125 
3126  // Reset to minimal scale for wimpy showers. Keep scales for EW+QCD
3127  // merging.
3128  if ( limitPTmaxISR && !isInclusive ) pTmaxISR = min(scale,muF());
3129  if ( limitPTmaxFSR && !isInclusive ) pTmaxFSR = min(scale,muF());
3130  if ( limitPTmaxMPI && !isInclusive ) pTmaxMPI = min(scale,muF());
3131 
3132  // For EW+QCD merging, apply wimpy shower only to 2->1 processes.
3133  if ( limitPTmaxISR && isInclusive && is2to1 ) pTmaxISR = min(scale,muF());
3134  if ( limitPTmaxFSR && isInclusive && is2to1 ) pTmaxFSR = min(scale,muF());
3135  if ( limitPTmaxMPI && isInclusive && is2to1 ) pTmaxMPI = min(scale,muF());
3136 
3137  // For pure QCD set the PS starting scales to the pT of the dijet system.
3138  if (is2to2QCD) {
3139  pTmaxFSR = pT2to2;
3140  pTmaxISR = pT2to2;
3141  }
3142 
3143  // If necessary, set the MPI starting scale to the collider energy.
3144  if ( hasMPIoverlap ) pTmaxMPI = infoPtr->eCM();
3145 
3146  // Reset phase space limitation flags
3147  if ( pTscale < infoPtr->eCM() ) {
3148  limitPTmaxISR = limitPTmaxFSR = limitPTmaxMPI = true;
3149  // If necessary, set the MPI starting scale to the collider energy.
3150  if ( hasMPIoverlap ) limitPTmaxMPI = false;
3151  }
3152 
3153  }
3154 
3155  // SET THE STARTING SCALES FOR REGULAR SHOWERS.
3156  if ( doMergeFirstEmm ) {
3157 
3158  // Remember if this is a "regular" shower off a reclustered event.
3159  bool doRecluster = doUMEPSSubt() || doNL3Subt() || doUNLOPSSubt()
3160  || doUNLOPSSubtNLO();
3161 
3162  // Reset shower and MPI scales.
3163  pTmaxISR = pTmaxFSR = pTmaxMPI = scale;
3164 
3165  // Reset to minimal scale for wimpy showers. Keep scales for EW+QCD
3166  // merging.
3167  if ( limitPTmaxISR && !isInclusive ) pTmaxISR = min(scale,muF());
3168  if ( limitPTmaxFSR && !isInclusive ) pTmaxFSR = min(scale,muF());
3169  if ( limitPTmaxMPI && !isInclusive ) pTmaxMPI = min(scale,muF());
3170 
3171  // For EW+QCD merging, apply wimpy shower only to 2->1 processes.
3172  if ( limitPTmaxISR && isInclusive && is2to1 ) pTmaxISR = min(scale,muF());
3173  if ( limitPTmaxFSR && isInclusive && is2to1 ) pTmaxFSR = min(scale,muF());
3174  if ( limitPTmaxMPI && isInclusive && is2to1 ) pTmaxMPI = min(scale,muF());
3175 
3176  // For pure QCD set the PS starting scales to the pT of the dijet system.
3177  if (is2to2QCD) {
3178  pTmaxFSR = pT2to2;
3179  pTmaxISR = pT2to2;
3180  }
3181 
3182  // If necessary, set the MPI starting scale to the collider energy.
3183  if ( hasMPIoverlap && !doRecluster ) {
3184  pTmaxMPI = infoPtr->eCM();
3185  limitPTmaxMPI = false;
3186  }
3187 
3188  // For reclustered events, no-MPI-probability between "pTmaxMPI" and
3189  // "scale" already included in the event weight.
3190  if ( doRecluster ) {
3191  pTmaxMPI = muMI();
3192  limitPTmaxMPI = true;
3193  }
3194  }
3195 
3196  // Reset power/wimpy shower switches iand scales if necessary.
3197  limitPTmaxFSRIn = limitPTmaxFSR;
3198  limitPTmaxISRIn = limitPTmaxISR;
3199  limitPTmaxMPIIn = limitPTmaxMPI;
3200  pTmaxFSRIn = pTmaxFSR;
3201  pTmaxISRIn = pTmaxISR;
3202  pTmaxMPIIn = pTmaxMPI;
3203  pTscaleIn = pTscale;
3204 
3205  // Done
3206  return true;
3207 
3208 }
3209 
3210 //--------------------------------------------------------------------------
3211 
3212 // Function to return the value of the merging scale function in the current
3213 // event.
3214 
3215 double MergingHooks::tmsNow( const Event& event ) {
3216 
3217  // Get merging scale in current event.
3218  double tnow = 0.;
3219  // Use KT/Durham merging scale definition.
3220  if ( doKTMerging() || doMGMerging() )
3221  tnow = kTms(event);
3222  // Use Lund PT merging scale definition.
3223  else if ( doPTLundMerging() )
3224  tnow = rhoms(event, false);
3225  // Use DeltaR_{ij}, pT_i, Q_{ij} combination merging scale definition.
3226  else if ( doCutBasedMerging() )
3227  tnow = cutbasedms(event);
3228  // Use NLO merging (Lund PT) merging scale definition.
3229  else if ( doNL3Merging() )
3230  tnow = rhoms(event, false);
3231  // Use NLO merging (Lund PT) merging scale definition.
3232  else if ( doUNLOPSMerging() )
3233  tnow = rhoms(event, false);
3234  // Use UMEPS (Lund PT) merging scale definition.
3235  else if ( doUMEPSMerging() )
3236  tnow = rhoms(event, false);
3237  // Use user-defined merging scale.
3238  else
3239  tnow = tmsDefinition(event);
3240  // Return merging scale value. Done
3241  return tnow;
3242 }
3243 
3244 //--------------------------------------------------------------------------
3245 
3246 // Function to check if the properties of the input particle should be
3247 // checked against the cut-based merging scale defintion.
3248 
3249 bool MergingHooks::checkAgainstCut( const Particle& particle){
3250 
3251  // Do not check uncoloured particles.
3252  if (particle.colType() == 0) return false;
3253  // By default, use u-, d-, c-, s- and b-quarks.
3254  if ( particle.idAbs() != 21 && particle.idAbs() > nQuarksMergeSave )
3255  return false;
3256  // Done
3257  return true;
3258 
3259 }
3260 
3261 //--------------------------------------------------------------------------
3262 
3263 // Function to return the minimal kT in the event. If doKTMerging = true, this
3264 // function will be used as a merging scale definition.
3265 
3266 double MergingHooks::kTms(const Event& event) {
3267 
3268  // Only check first emission.
3269  if (!isFirstEmission(event)) return 0.;
3270 
3271  // Find all electroweak decayed bosons in the state.
3272  vector<int> ewResonancePos;
3273  ewResonancePos.clear();
3274  for (int i=0; i < event.size(); ++i)
3275  if ( abs(event[i].status()) == 22
3276  && ( event[i].idAbs() == 22
3277  || event[i].idAbs() == 23
3278  || event[i].idAbs() == 24
3279  || event[i].idAbs() == 25
3280  || event[i].idAbs() == 6 ) )
3281  ewResonancePos.push_back(i);
3282 
3283  // Declare final parton vectors
3284  vector <int> FinalPartPos;
3285  FinalPartPos.clear();
3286  // Search inEvent record for final state partons.
3287  // Exclude decay products of ew resonance.
3288  for (int i=0; i < event.size(); ++i){
3289  if ( event[i].isFinal()
3290  && isInHard( i, event )
3291  && event[i].colType() != 0
3292  && checkAgainstCut(event[i]) ){
3293  bool isDecayProduct = false;
3294  for(int j=0; j < int(ewResonancePos.size()); ++j)
3295  if ( event[i].isAncestor( ewResonancePos[j]) )
3296  isDecayProduct = true;
3297  // Except for e+e- -> jets, do not check radiation in resonance decays.
3298  if ( !isDecayProduct
3299  || getProcessString().compare("e+e->jj") == 0
3300  || getProcessString().compare("e+e->(z>jj)") == 0 )
3301  FinalPartPos.push_back(i);
3302  }
3303  }
3304 
3305  // Find minimal Durham kT in event, using own function: Check
3306  // definition of separation
3307  int type = (event[3].colType() == 0
3308  && event[4].colType() == 0) ? -1 : ktTypeSave;
3309  // Find minimal kT
3310  double ktmin = event[0].e();
3311  for(int i=0; i < int(FinalPartPos.size()); ++i){
3312  double kt12 = ktmin;
3313  // Compute separation to the beam axis for hadronic collisions
3314  if (type == 1 || type == 2) {
3315  double temp = event[FinalPartPos[i]].pT();
3316  kt12 = min(kt12, temp);
3317  }
3318  // Compute separation to other final state jets
3319  for(int j=i+1; j < int(FinalPartPos.size()); ++j) {
3320  double temp = kTdurham( event[FinalPartPos[i]], event[FinalPartPos[j]],
3321  type, DparameterSave);
3322  kt12 = min(kt12, temp);
3323  }
3324  // Keep the minimal Durham separation
3325  ktmin = min(ktmin,kt12);
3326  }
3327 
3328  // Return minimal Durham kT
3329  return ktmin;
3330 
3331 }
3332 
3333 //--------------------------------------------------------------------------
3334 
3335 // Function to compute durham y separation from Particle input.
3336 
3337 double MergingHooks::kTdurham(const Particle& RadAfterBranch,
3338  const Particle& EmtAfterBranch, int Type, double D ){
3339 
3340  // Declare return variable
3341  double ktdur;
3342  // Save 4-momenta of final state particles
3343  Vec4 jet1 = RadAfterBranch.p();
3344  Vec4 jet2 = EmtAfterBranch.p();
3345 
3346  if ( Type == -1) {
3347  // Get angle between jets for e+e- collisions, make sure that
3348  // -1 <= cos(theta) <= 1
3349  double costh;
3350  if (jet1.pAbs()*jet2.pAbs() <=0.) costh = 1.;
3351  else {
3352  costh = costheta(jet1,jet2);
3353  }
3354  // Calculate kt durham separation between jets for e+e- collisions
3355  ktdur = 2.0*min( pow(jet1.e(),2) , (pow(jet2.e(),2)) )*(1.0 - costh);
3356  } else if ( Type == 1 ){
3357  // Get delta_y for hadronic collisions:
3358  // Get mT of first jet
3359  double mT1sq = jet1.m2Calc() + jet1.pT2();
3360  double mT1 = 0.;
3361  if (mT1sq < 0) mT1 = - sqrt(-mT1sq);
3362  else mT1 = sqrt(mT1sq);
3363  // Get mT of second jet
3364  double mT2sq = jet2.m2Calc() + jet2.pT2();
3365  double mT2 = 0.;
3366  if (mT2sq < 0) mT2 = - sqrt(-mT2sq);
3367  else mT2 = sqrt(mT2sq);
3368  // Get rapidity of first jet
3369  double y1 = log( ( jet1.e() + abs(jet1.pz()) ) / mT1 );
3370  if (jet1.pz() < 0) y1 *= -1.;
3371  // Get rapidity of second jet
3372  double y2 = log( ( jet2.e() + abs(jet2.pz()) ) / mT2 );
3373  if (jet2.pz() < 0) y2 *= -1.;
3374  // Get delta_phi for hadronic collisions
3375  double pt1 = sqrt( pow(jet1.px(),2) + pow(jet1.py(),2) );
3376  double pt2 = sqrt( pow(jet2.px(),2) + pow(jet2.py(),2) );
3377  double cosdPhi = ( jet1.px()*jet2.px() + jet1.py()*jet2.py() ) / (pt1*pt2);
3378  double dPhi = acos( cosdPhi );
3379  // Calculate kT durham like fastjet,
3380  // but with rapidity instead of pseudo-rapidity
3381  ktdur = min( pow(pt1,2),pow(pt2,2) )
3382  * ( pow(y1-y2,2) + pow(dPhi,2) ) / pow(D,2);
3383  } else if ( Type == 2 ){
3384 
3385  // Get mT of first jet
3386  double mT1sq = jet1.m2Calc() + jet1.pT2();
3387  double mT1 = 0.;
3388  if (mT1sq < 0) mT1 = - sqrt(-mT1sq);
3389  else mT1 = sqrt(mT1sq);
3390  // Get mT of second jet
3391  double mT2sq = jet2.m2Calc() + jet2.pT2();
3392  double mT2 = 0.;
3393  if (mT2sq < 0) mT2 = - sqrt(-mT2sq);
3394  else mT2 = sqrt(mT2sq);
3395  // Get pseudo-rapidity of first jet
3396  double eta1 = log( ( sqrt(jet1.px()*jet1.px() + jet1.py()*jet1.py()
3397  + jet1.pz()*jet1.pz()) + abs(jet1.pz()) ) / mT1);
3398  if (jet1.pz() < 0) eta1 *= -1.;
3399  // Get pseudo-rapidity of second jet
3400  double eta2 = log( ( sqrt(jet2.px()*jet2.px() + jet2.py()*jet2.py()
3401  + jet2.pz()*jet2.pz()) + abs(jet2.pz()) ) / mT2);
3402  if (jet2.pz() < 0) eta2 *= -1.;
3403 
3404  // Get delta_phi and cos(Delta_phi) for hadronic collisions
3405  double pt1 = sqrt( pow(jet1.px(),2) + pow(jet1.py(),2) );
3406  double pt2 = sqrt( pow(jet2.px(),2) + pow(jet2.py(),2) );
3407  double cosdPhi = ( jet1.px()*jet2.px() + jet1.py()*jet2.py() ) / (pt1*pt2);
3408  double dPhi = acos( cosdPhi );
3409  // Calculate kT durham like fastjet
3410  ktdur = min( pow(pt1,2),pow(pt2,2) )
3411  * ( pow(eta1-eta2,2) + pow(dPhi,2) ) / pow(D,2);
3412  } else if ( Type == 3 ){
3413  // Get cosh(Delta_eta) for hadronic collisions
3414  double eta1 = 0.5*log( (jet1.e() + jet1.pz()) / (jet1.e() - jet1.pz()) );
3415  double eta2 = 0.5*log( (jet2.e() + jet2.pz()) / (jet2.e() - jet2.pz()) );
3416  double coshdEta = cosh( eta1 - eta2 );
3417  // Get delta_phi and cos(Delta_phi) for hadronic collisions
3418  double pt1 = sqrt( pow(jet1.px(),2) + pow(jet1.py(),2) );
3419  double pt2 = sqrt( pow(jet2.px(),2) + pow(jet2.py(),2) );
3420  double cosdPhi = ( jet1.px()*jet2.px() + jet1.py()*jet2.py() ) / (pt1*pt2);
3421  // Calculate kT durham separation "SHERPA-like"
3422  ktdur = 2.0*min( pow(pt1,2),pow(pt2,2) )
3423  * ( coshdEta - cosdPhi ) / pow(D,2);
3424  } else {
3425  ktdur = 0.0;
3426  }
3427  // Return kT
3428  return sqrt(ktdur);
3429 }
3430 
3431 //--------------------------------------------------------------------------
3432 
3433 // Find the minimal Lund pT between coloured partons in the input
3434 // event. If doPTLundMerging = true, this function will be used as a merging
3435 // scale definition.
3436 
3437 double MergingHooks::rhoms( const Event& event, bool withColour){
3438 
3439  // Only check first emission.
3440  if (!isFirstEmission(event)) return 0.;
3441 
3442  if ( useShowerPlugin() ) {
3443  double ptret=event[0].e();
3444  for(int i=0; i < event.size(); ++i) {
3445  for(int j=0; j < event.size(); ++j) {
3446  if (i==j) continue;
3447  double temp = rhoPythia( event, i, j, 0, 0 );
3448  if (temp > 0.) ptret = min(ptret, temp);
3449  }
3450  }
3451  return ptret;
3452  }
3453 
3454  // Find all electroweak decayed bosons in the state.
3455  vector<int> ewResonancePos;
3456  ewResonancePos.clear();
3457  for (int i=0; i < event.size(); ++i)
3458  if ( abs(event[i].status()) == 22
3459  && ( event[i].idAbs() == 22
3460  || event[i].idAbs() == 23
3461  || event[i].idAbs() == 24
3462  || event[i].idAbs() == 25
3463  || event[i].idAbs() == 6 ) )
3464  ewResonancePos.push_back(i);
3465 
3466  // Declare final parton vectors
3467  vector <int> FinalPartPos;
3468  FinalPartPos.clear();
3469  // Search inEvent record for final state partons.
3470  // Exclude decay products of ew resonance.
3471  for (int i=0; i < event.size(); ++i){
3472 
3473  if ( event[i].isFinal()
3474  && isInHard( i, event )
3475  && event[i].colType() != 0
3476  && checkAgainstCut(event[i]) ){
3477  bool isDecayProduct = false;
3478  for(int j=0; j < int(ewResonancePos.size()); ++j)
3479  if ( event[i].isAncestor( ewResonancePos[j]) )
3480  isDecayProduct = true;
3481  // Except for e+e- -> jets, do not check radiation in resonance decays.
3482  if ( !isDecayProduct
3483  || getProcessString().compare("e+e->jj") == 0
3484  || getProcessString().compare("e+e->(z>jj)") == 0 )
3485  FinalPartPos.push_back(i);
3486  }
3487 
3488  // Include photons into the tms definition for "weak+QCD merging".
3489  if ( getProcessString().find("Ainc") != string::npos
3490  && event[i].isFinal() && event[i].idAbs() == 22 )
3491  FinalPartPos.push_back(i);
3492  // Include Z-bosons into the tms definition for "weak+QCD merging".
3493  if ( getProcessString().find("Zinc") != string::npos
3494  && event[i].isFinal() && event[i].idAbs() == 23 )
3495  FinalPartPos.push_back(i);
3496  // Include W-bosons into the tms definition for "weak+QCD merging".
3497  if ( getProcessString().find("Winc") != string::npos
3498  && event[i].isFinal() && event[i].idAbs() == 24 )
3499  FinalPartPos.push_back(i);
3500  }
3501 
3502  // Get index of first incoming
3503  int in1 = 0;
3504  for (int i=0; i < event.size(); ++i)
3505  if (abs(event[i].status()) == 41 ){
3506  in1 = i;
3507  break;
3508  }
3509 
3510  // Get index of second incoming
3511  int in2 = 0;
3512  for (int i=0; i < event.size(); ++i)
3513  if (abs(event[i].status()) == 42 ){
3514  in2 = i;
3515  break;
3516  }
3517 
3518  // If no incoming of the cascade are found, try incoming
3519  if (in1 == 0 || in2 == 0){
3520  // Find current incoming partons
3521  for(int i=3; i < int(event.size()); ++i){
3522  if ( !isInHard( i, event ) ) continue;
3523  if (event[i].mother1() == 1) in1 = i;
3524  if (event[i].mother1() == 2) in2 = i;
3525  }
3526  }
3527 
3528  int nInitialPartons = 0, nFinalOther = 0;
3529  for ( int i = 0; i < event.size(); ++i ) {
3530  if ( (event[i].mother1() == 1 || event[i].mother1() == 2 )
3531  && (event[i].idAbs() < 6 || event[i].id() == 21) )
3532  nInitialPartons++;
3533  if (event[i].isFinal() && event[i].idAbs() >= 6 && event[i].id() != 21)
3534  nFinalOther++;
3535  }
3536  bool is2to2QCD = ( int(FinalPartPos.size()) == 2 && nInitialPartons == 2
3537  && nFinalOther == 0 );
3538 
3539  // For pure QCD set the cut to the pT of the dijet system.
3540  if (is2to2QCD) {
3541  double pt12 = min(event[FinalPartPos[0]].pT(),
3542  event[FinalPartPos[1]].pT());
3543  return pt12;
3544  }
3545 
3546  // Find minimal pythia pt in event
3547  double ptmin = event[0].e();
3548  for(int i=0; i < int(FinalPartPos.size()); ++i){
3549 
3550  double pt12 = ptmin;
3551  // Compute pythia ISR separation i-jet and first incoming
3552  if (event[in1].colType() != 0) {
3553  double temp = rhoPythia( event, in1, FinalPartPos[i], in2, -1 );
3554  pt12 = min(pt12, temp);
3555  }
3556 
3557  // Compute pythia ISR separation i-jet and second incoming
3558  if ( event[in2].colType() != 0) {
3559  double temp = rhoPythia( event, in2, FinalPartPos[i], in1, -1 );
3560  pt12 = min(pt12, temp);
3561  }
3562 
3563  if (withColour) {
3564  // Compute pythia FSR separation between two jets,
3565  // with knowledge of colour connections
3566  for(int j=0; j < int(FinalPartPos.size()); ++j) {
3567 
3568  // Find recoiler in event
3569  if ( i!=j ){
3570  bool isHard = false;
3571  int radAcl = event[FinalPartPos[i]].acol();
3572  int radCol = event[FinalPartPos[i]].col();
3573  int emtAcl = event[FinalPartPos[j]].acol();
3574  int emtCol = event[FinalPartPos[j]].col();
3575  int iRec = -1;
3576  // Check in final state
3577  if (iRec <= 0 && radAcl > 0 && radAcl != emtCol)
3578  iRec = findColour(radAcl, FinalPartPos[i], FinalPartPos[j],
3579  event,1, isHard);
3580  if (iRec <= 0 && radCol > 0 && radCol != emtAcl)
3581  iRec = findColour(radCol, FinalPartPos[i], FinalPartPos[j],
3582  event,1, isHard);
3583  if (iRec <= 0 && emtAcl > 0 && emtAcl != radCol)
3584  iRec = findColour(emtAcl, FinalPartPos[i], FinalPartPos[j],
3585  event,1, isHard);
3586  if (iRec <= 0 && emtCol > 0 && emtCol != radAcl)
3587  iRec = findColour(emtCol, FinalPartPos[i], FinalPartPos[j],
3588  event,1, isHard);
3589 
3590  // Check in initial state
3591  if (iRec <= 0 && radAcl > 0 && radAcl != emtCol)
3592  iRec = findColour(radAcl, FinalPartPos[i], FinalPartPos[j],
3593  event,2, isHard);
3594  if (iRec <= 0 && radCol > 0 && radCol != emtAcl)
3595  iRec = findColour(radCol, FinalPartPos[i], FinalPartPos[j],
3596  event,2, isHard);
3597  if (iRec <= 0 && emtAcl > 0 && emtAcl != radCol)
3598  iRec = findColour(emtAcl, FinalPartPos[i], FinalPartPos[j],
3599  event,2, isHard);
3600  if (iRec <= 0 && emtCol > 0 && emtCol != radAcl)
3601  iRec = findColour(emtCol, FinalPartPos[i], FinalPartPos[j],
3602  event,2, isHard);
3603 
3604  if (iRec > 0) {
3605  double temp = rhoPythia( event, FinalPartPos[i], FinalPartPos[j],
3606  iRec, 1 );
3607  pt12 = min(pt12, temp);
3608  }
3609  }
3610  }
3611 
3612  } else {
3613  // Compute pythia FSR separation between two jets,
3614  // without any knowledge of colour connections
3615  for(int j=0; j < int(FinalPartPos.size()); ++j) {
3616  for(int k=0; k < int(FinalPartPos.size()); ++k) {
3617  // Allow any parton as recoiler
3618  if ( (i != j) && (i != k) && (j != k) ){
3619 
3620  double temp = 0.;
3621  // Only check splittings allowed by flavour, e.g.
3622  // only q -> qg and g -> qqbar
3623  temp = rhoPythia( event, FinalPartPos[i], FinalPartPos[j],
3624  FinalPartPos[k], 1 );
3625  pt12 = min(pt12, temp);
3626  temp = rhoPythia( event, FinalPartPos[j], FinalPartPos[i],
3627  FinalPartPos[k], 1 );
3628  pt12 = min(pt12, temp);
3629  }
3630  }
3631  }
3632 
3633  // Compute pythia FSR separation between two jets, with initial recoiler
3634  // without any knowledge of colour connections
3635  if ( event[in1].colType() != 0 && event[in2].colType() != 0) {
3636  for(int j=0; j < int(FinalPartPos.size()); ++j) {
3637  // Allow both initial partons as recoiler
3638  if ( i != j ){
3639  double temp = pt12;
3640 
3641  // Check with first initial as recoiler
3642  if (event[in1].colType() != 0)
3643  temp = rhoPythia( event, FinalPartPos[i],FinalPartPos[j],in1, 1);
3644  pt12 = min(pt12, temp);
3645  // Check with second initial as recoiler
3646  if (event[in2].colType() != 0)
3647  temp = rhoPythia( event, FinalPartPos[i],FinalPartPos[j],in2, 1);
3648  pt12 = min(pt12, temp);
3649  }
3650  }
3651  }
3652 
3653  }
3654  // Reset minimal y separation
3655  ptmin = min(ptmin,pt12);
3656  }
3657 
3658  return ptmin;
3659 
3660 }
3661 
3662 //--------------------------------------------------------------------------
3663 
3664 // Function to compute "pythia pT separation" from Particle input, as a helper
3665 // for rhoms(...).
3666 
3667 double MergingHooks::rhoPythia(const Event& event, int rad, int emt, int rec,
3668  int ShowerType){
3669 
3670  Particle RadAfterBranch = event[rad];
3671  Particle EmtAfterBranch = event[emt];
3672  Particle RecAfterBranch = event[rec];
3673 
3674  // Use external shower for merging.
3675  // Ask showers for evolution variable.
3676  if ( useShowerPlugin() ) {
3677  map<string,double> stateVars;
3678  double ptret = event[0].m();
3679  bool isFSR = showers->timesPtr->allowedSplitting(event, rad, emt);
3680  bool isISR = showers->spacePtr->allowedSplitting(event, rad, emt);
3681  if (isFSR) {
3682  vector<string> names
3683  = showers->timesPtr->getSplittingName(event, rad, emt, 0);
3684  for (int iName=0; iName < int(names.size()); ++iName) {
3685  vector<int> recsNow
3686  = showers->timesPtr->getRecoilers(event, rad, emt, names[iName]);
3687  for ( int i = 0; i < int(recsNow.size()); ++i ) {
3688  stateVars = showers->timesPtr->getStateVariables(event, rad, emt,
3689  recsNow[i], names[iName]);
3690  double pttemp = ptret;
3691  if (stateVars.size() > 0 && stateVars.find("t") != stateVars.end())
3692  pttemp = sqrt(stateVars["t"]);
3693  ptret = min(ptret,pttemp);
3694  }
3695  }
3696  }
3697 
3698  if (isISR) {
3699  vector<string> names
3700  = showers->spacePtr->getSplittingName(event, rad, emt, 0);
3701  for (int iName=0; iName < int(names.size()); ++iName) {
3702  vector<int> recsNow
3703  = showers->timesPtr->getRecoilers(event, rad, emt, names[iName]);
3704  for ( int i = 0; i < int(recsNow.size()); ++i ) {
3705  stateVars = showers->spacePtr->getStateVariables(event, rad, emt,
3706  recsNow[i], names[iName]);
3707  double pttemp = ptret;
3708  if (stateVars.size() > 0 && stateVars.find("t") != stateVars.end())
3709  pttemp = sqrt(stateVars["t"]);
3710  ptret = min(ptret,pttemp);
3711  }
3712  }
3713  }
3714 
3715  return ptret;
3716  }
3717 
3718  // Note: If massive particles are involved, this definition slightly differs
3719  // from History:pTLund(), as we need to ensure consistency with
3720  // aMC@NLO_MadGraph5 (!). In the latter, no masses are available at the
3721  // point where the merging scale value is calculated, and thus masses are set
3722  // by hand there, and consequently here.
3723 
3724  bool allowed = true;
3725 
3726  // Save type: 1 = FSR pT definition, else ISR definition
3727  int Type = ShowerType;
3728 
3729  // Set masses (as used in MG5).
3730  double m0u = 0.0, m0d = 0.0, m0c = 1.5, m0s = 0.0, m0t = 172.5,
3731  m0b = 4.7, m0w = 80.4, m0z = 91.188, m0x = 1000.0;
3732  if (false) cout << m0u*m0d*m0c*m0s*m0t*m0b*m0w*m0z*m0x;
3733 
3734  // Calculate virtuality of splitting
3735  int sign = (Type==1) ? 1 : -1;
3736  Vec4 Q(RadAfterBranch.p() + sign*EmtAfterBranch.p());
3737  double Qsq = sign * Q.m2Calc();
3738 
3739  // Splitting not possible for negative virtuality.
3740  if ( Qsq < 0.0 ) allowed = false;
3741 
3742  // Construct 2->3 variables for FSR
3743  Vec4 radAft(RadAfterBranch.p());
3744  Vec4 recAft(RecAfterBranch.p());
3745  Vec4 emtAft(EmtAfterBranch.p());
3746 
3747  // Try to reconstruct flavour of radiator before emission.
3748  int idRadBef = 0;
3749  int flavEmt = EmtAfterBranch.id();
3750  int flavRad = RadAfterBranch.id();
3751  // gluon radiation: idBef = idAft
3752  if (abs(flavEmt) == 21 || abs(flavEmt) == 22 ) idRadBef=flavRad;
3753  // final state gluon splitting: idBef = 21
3754  if (Type == 1 && flavEmt == -flavRad) idRadBef=21;
3755  // final state quark -> gluon conversion
3756  if (Type == 1 && abs(flavEmt) < 10 && flavRad == 21) idRadBef=flavEmt;
3757  // initial state gluon splitting: idBef = -idEmt
3758  if (Type == -1 && abs(flavEmt) < 10 && flavRad == 21) idRadBef=-flavEmt;
3759  // initial state gluon -> quark conversion
3760  if (Type == -1 && abs(flavEmt) < 10 && flavRad == flavEmt) idRadBef=21;
3761  // W-boson radiation
3762  if (flavEmt == 24) idRadBef = RadAfterBranch.id()+1;
3763  if (flavEmt == -24) idRadBef = RadAfterBranch.id()-1;
3764 
3765  // Store masses both after and prior to emission.
3766  double m2RadAft = radAft.m2Calc();
3767  double m2EmtAft = emtAft.m2Calc();
3768  double m2RadBef = 0.;
3769  if ( RadAfterBranch.idAbs() != 21 && RadAfterBranch.idAbs() != 22
3770  && EmtAfterBranch.idAbs() != 24
3771  && RadAfterBranch.idAbs() != EmtAfterBranch.idAbs() )
3772  m2RadBef = m2RadAft;
3773  else if (EmtAfterBranch.idAbs() == 24) {
3774  if (idRadBef != 0) {
3775  if( abs(idRadBef) == 4 ) m2RadBef = pow(m0c,2);
3776  if( abs(idRadBef) == 5 ) m2RadBef = pow(m0b,2);
3777  if( abs(idRadBef) == 6 ) m2RadBef = pow(m0t,2);
3778  if( abs(idRadBef) == 9000001 ) m2RadBef = pow(m0x,2);
3779  }
3780  } else if (!RadAfterBranch.isFinal()) {
3781  if (RadAfterBranch.idAbs() == 21 && EmtAfterBranch.idAbs() != 21)
3782  m2RadBef = m2EmtAft;
3783  }
3784 
3785  double m2Final = (radAft + recAft + emtAft).m2Calc();
3786  // Final state splitting not possible for negative "dipole mass".
3787  if (m2Final < 0.0) allowed = false;
3788 
3789  // Rescaling of recoiler for FSR with initial state recoiler.
3790  if ( !RecAfterBranch.isFinal() && RadAfterBranch.isFinal() ){
3791  double mar2 = m2Final - 2. * Qsq + 2. * m2RadBef;
3792  double rescale = (1. - (Qsq - m2RadBef)/(mar2 - m2RadBef))
3793  /(1. + (Qsq - m2RadBef)/(mar2 - m2RadBef));
3794  // Final-initial splitting not possible for negative rescaling.
3795  if (rescale < 0.0) allowed = false;
3796  recAft *= rescale;
3797  }
3798 
3799  Vec4 sum = radAft + recAft + emtAft;
3800  double m2Dip = sum.m2Calc();
3801  double x1 = 2. * (sum * radAft) / m2Dip;
3802  double x2 = 2. * (sum * recAft) / m2Dip;
3803 
3804  // Final state splitting not possible for ill-defined 3-body-variables.
3805  if ( RadAfterBranch.isFinal()
3806  && ( x1 < 0.0 || x1 > 1.0 || x2 < 0.0 || x2 > 1.0)) allowed = false;
3807 
3808  // Construct momenta of dipole before/after splitting for ISR
3809  Vec4 qBR(RadAfterBranch.p() - EmtAfterBranch.p() + RecAfterBranch.p());
3810  Vec4 qAR(RadAfterBranch.p() + RecAfterBranch.p());
3811 
3812  // Prepare for more complicated z definition for massive splittings.
3813  double lambda13 = sqrt( pow2(Qsq - m2RadAft - m2EmtAft )
3814  - 4. * m2RadAft*m2EmtAft );
3815  double k1 = ( Qsq - lambda13 + (m2EmtAft - m2RadAft ) ) / ( 2. * Qsq );
3816  double k3 = ( Qsq - lambda13 - (m2EmtAft - m2RadAft ) ) / ( 2. * Qsq );
3817 
3818  // Calculate z of splitting, different for FSR and ISR
3819  double z = (Type==1) ? 1./ ( 1- k1 -k3) * ( x1 / (2.-x2) - k3)
3820  : (qBR.m2Calc())/( qAR.m2Calc());
3821 
3822  // Splitting not possible for ill-defined energy sharing.
3823  if ( z < 0.0 || z > 1.0) allowed = false;
3824 
3825  // Separation of splitting, different for FSR and ISR
3826  double pTpyth = (Type==1) ? z*(1.-z) : (1.-z);
3827 
3828  // pT^2 = separation*virtuality
3829  if (Type == 1) pTpyth *= (Qsq - m2RadBef);
3830  else pTpyth *= Qsq;
3831 
3832  // Check for threshold in ISR, only relevant for c and b.
3833  // Use pT2 = (1 - z) * (Qsq + m^2).
3834  if ( Type != 1) {
3835  if ( ( RadAfterBranch.idAbs() == 4 || EmtAfterBranch.idAbs() == 4)
3836  && RadAfterBranch.idAbs() != EmtAfterBranch.idAbs() ) {
3837  if (pTpyth < 2 * pow(m0c,2)) pTpyth = (Qsq + pow(m0c,2)) * (1. - z);
3838  } else if ( (RadAfterBranch.idAbs() == 5 || EmtAfterBranch.idAbs() == 5)
3839  && RadAfterBranch.idAbs() != EmtAfterBranch.idAbs() ) {
3840  if (pTpyth < 2 * pow(m0b,2))
3841  pTpyth = (Qsq + pow(m0b,2) ) * (1. - z);
3842  }
3843  }
3844 
3845  // Kinematically impossible splittings should not be included in the
3846  // pT definition!
3847  if (!allowed) pTpyth = 1e15;
3848 
3849  if ( pTpyth < 0. ) pTpyth = 0.;
3850 
3851  // Return pT
3852  return sqrt(pTpyth);
3853 }
3854 
3855 //--------------------------------------------------------------------------
3856 
3857 // Function to find a colour (anticolour) index in the input event.
3858 // Helper for rhoms
3859 // IN int col : Colour tag to be investigated
3860 // int iExclude1 : Identifier of first particle to be excluded
3861 // from search
3862 // int iExclude2 : Identifier of second particle to be excluded
3863 // from search
3864 // Event event : event to be searched for colour tag
3865 // int type : Tag to define if col should be counted as
3866 // colour (type = 1) [->find anti-colour index
3867 // contracted with col]
3868 // anticolour (type = 2) [->find colour index
3869 // contracted with col]
3870 // OUT int : Position of particle in event record
3871 // contraced with col [0 if col is free tag]
3872 
3873 int MergingHooks::findColour(int col, int iExclude1, int iExclude2,
3874  const Event& event, int type, bool isHardIn){
3875 
3876  bool isHard = isHardIn;
3877  int index = 0;
3878 
3879  if (isHard){
3880  // Search event record for matching colour & anticolour
3881  for(int n = 0; n < event.size(); ++n) {
3882  if ( n != iExclude1 && n != iExclude2
3883  && event[n].colType() != 0
3884  &&( event[n].status() > 0 // Check outgoing
3885  || event[n].status() == -21) ) { // Check incoming
3886  if ( event[n].acol() == col ) {
3887  index = -n;
3888  break;
3889  }
3890  if ( event[n].col() == col ){
3891  index = n;
3892  break;
3893  }
3894  }
3895  }
3896  } else {
3897 
3898  // Search event record for matching colour & anticolour
3899  for(int n = 0; n < event.size(); ++n) {
3900  if ( n != iExclude1 && n != iExclude2
3901  && event[n].colType() != 0
3902  &&( event[n].status() == 43 // Check outgoing from ISR
3903  || event[n].status() == 51 // Check outgoing from FSR
3904  || event[n].status() == 52 // Check outgoing from FSR
3905  || event[n].status() == -41 // first initial
3906  || event[n].status() == -42) ) { // second initial
3907  if ( event[n].acol() == col ) {
3908  index = -n;
3909  break;
3910  }
3911  if ( event[n].col() == col ){
3912  index = n;
3913  break;
3914  }
3915  }
3916  }
3917  }
3918  // if no matching colour / anticolour has been found, return false
3919  if ( type == 1 && index < 0) return abs(index);
3920  if ( type == 2 && index > 0) return abs(index);
3921 
3922  return 0;
3923 }
3924 
3925 //--------------------------------------------------------------------------
3926 
3927 // Find the if the event passes the Delta R_{ij}, pT_{i} and Q_{ij} cuts on
3928 // the matrix element, as needed for cut-based merging scale definition.
3929 
3930 double MergingHooks::cutbasedms( const Event& event ){
3931 
3932  // Only check first emission.
3933  if (!isFirstEmission(event)) return -1.;
3934 
3935  // Save allowed final state particles
3936  vector<int> partons;
3937  for( int i=0; i < event.size(); ++i) {
3938  if ( event[i].isFinal()
3939  && isInHard( i, event )
3940  && checkAgainstCut(event[i]) )
3941  partons.push_back(i);
3942  }
3943 
3944  // Declare overall veto
3945  bool doVeto = false;
3946  // Declare vetoes
3947  bool vetoPT = false;
3948  bool vetoRjj = false;
3949  bool vetoMjj = false;
3950  // Declare cuts used in matrix element
3951  double pTjmin = pTiMS();
3952  double mjjmin = QijMS();
3953  double rjjmin = dRijMS();
3954 
3955  // Declare minimum values
3956  double minPT = event[0].e();
3957  double minRJJ = 10.;
3958  double minMJJ = event[0].e();
3959 
3960  // Check matrix element cuts
3961  for( int i=0; i < int(partons.size()); ++i){
3962  // Save pT value
3963  minPT = min(minPT,event[partons[i]].pT());
3964 
3965  // Check two-parton cuts
3966  for( int j=0; j < int(partons.size()); ++j){
3967  if (i!=j){
3968 
3969  // Save delta R value
3970  minRJJ = min(minRJJ, deltaRij( event[partons[i]].p(),
3971  event[partons[j]].p()) );
3972  // Save delta R value
3973  minMJJ = min(minMJJ, ( event[partons[i]].p()
3974  +event[partons[j]].p() ).mCalc() );
3975 
3976  }
3977  }
3978  // Done with cut evaluation
3979  }
3980 
3981  // Check if all partons are in the matrix element region
3982  if (minPT > pTjmin) vetoPT = true;
3983  if (minRJJ > rjjmin) vetoRjj = true;
3984  if (minMJJ > mjjmin) vetoMjj = true;
3985 
3986  // In the matrix element calculation, we have rejected the events if any of
3987  // the cuts had not been fulfilled,
3988  // i.e. we are in the matrix element domain if all cuts are fulfilled.
3989  // We veto any emission in the ME region.
3990  // Disregard the two-parton cuts if only one parton in the final state
3991  if (int(partons.size() == 1))
3992  doVeto = vetoPT;
3993  else
3994  // Veto if the combination of cuts would be in the ME region
3995  doVeto = vetoPT && vetoRjj && vetoMjj;
3996 
3997  // If event is above merging scale, veto
3998  if (doVeto) return 1.;
3999 
4000  // Else, do nothing
4001  return -1.;
4002 
4003 }
4004 
4005 //--------------------------------------------------------------------------
4006 
4007 // Function to compute Delta R separation from 4-vector input.
4008 
4009 double MergingHooks::deltaRij(Vec4 jet1, Vec4 jet2){
4010 
4011  // Declare return variable
4012  double deltaR = 0.;
4013  // Get delta_eta and cosh(Delta_eta) for hadronic collisions
4014  double eta1 = 0.5*log( (jet1.e() + jet1.pz()) / (jet1.e() - jet1.pz()) );
4015  double eta2 = 0.5*log( (jet2.e() + jet2.pz()) / (jet2.e() - jet2.pz()) );
4016  // Get delta_phi and cos(Delta_phi) for hadronic collisions
4017  double pt1 = sqrt( pow(jet1.px(),2) + pow(jet1.py(),2) );
4018  double pt2 = sqrt( pow(jet2.px(),2) + pow(jet2.py(),2) );
4019  double cosdPhi = ( jet1.px()*jet2.px() + jet1.py()*jet2.py() ) / (pt1*pt2);
4020  double dPhi = acos( cosdPhi );
4021  // Calculate kT durham like fastjet
4022  deltaR = sqrt(pow(eta1-eta2,2) + pow(dPhi,2));
4023  // Return kT
4024  return deltaR;
4025 }
4026 
4027 //==========================================================================
4028 
4029 } // end namespace Pythia8
Definition: AgUStep.h:26