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) 2020 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(outgoing1[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  unordered_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  unordered_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  unordered_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  unordered_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, unordered_map<int,int> further1,
1754  unordered_map<int,int> further2) {
1755 
1756  int nOld1 = candidates1.size();
1757  int nOld2 = candidates2.size();
1758  int nNew1 = further1.size();
1759  int nNew2 = further2.size();
1760  bool exchanged = false;
1761  // Replace, if one-to-one correspondence exists.
1762  if ( nOld1 == 1 && nOld2 == 0 && nNew1 == 1 && nNew2 == 0){
1763  PosOutgoing1[further1.begin()->first] = further1.begin()->second;
1764  exchanged = true;
1765  } else if ( nOld1 == 0 && nOld2 == 1 && nNew1 == 0 && nNew2 == 1){
1766  PosOutgoing2[further2.begin()->first] = further2.begin()->second;
1767  exchanged = true;
1768  // Else simply swap with the first candidate.
1769  } else if ( nNew1 > 1 && nNew2 == 0 ) {
1770  PosOutgoing1[further1.begin()->first] = further1.begin()->second;
1771  exchanged = true;
1772  } else if ( nNew1 == 0 && nNew2 > 0 ) {
1773  PosOutgoing2[further2.begin()->first] = further2.begin()->second;
1774  exchanged = true;
1775  }
1776 
1777  // Done
1778  return exchanged;
1779 
1780 }
1781 
1782 //--------------------------------------------------------------------------
1783 
1784 // Function to get the number of coloured final state partons in the
1785 // hard process
1786 
1787 int HardProcess::nQuarksOut(){
1788  int nFin =0;
1789  for(int i =0; i< int(hardOutgoing1.size()); ++i){
1790  if (hardOutgoing1[i] == 2212 || abs(hardOutgoing1[i]) < 10) nFin++;
1791  }
1792  for(int i =0; i< int(hardOutgoing2.size()); ++i){
1793  if (hardOutgoing2[i] == 2212 || abs(hardOutgoing2[i]) < 10) nFin++;
1794  }
1795  // For very loose hard process definition, check number of hard process
1796  // b-quarks explicitly.
1797  for(int i =0; i< int(hardOutgoing1.size()); ++i)
1798  if (hardOutgoing1[i] == 5000)
1799  for(int j =0; j< int(PosOutgoing1.size()); ++j)
1800  if (state[PosOutgoing1[j]].idAbs() == 5)
1801  nFin++;
1802  for(int i =0; i< int(hardOutgoing2.size()); ++i)
1803  if (hardOutgoing2[i] == 5000)
1804  for(int j =0; j< int(PosOutgoing2.size()); ++j)
1805  if (state[PosOutgoing2[j]].idAbs() == 5)
1806  nFin++;
1807  return nFin;
1808 }
1809 
1810 //--------------------------------------------------------------------------
1811 
1812 // Function to get the number of uncoloured final state particles in the
1813 // hard process
1814 
1815 int HardProcess::nLeptonOut(){
1816  int nFin =0;
1817  for(int i =0; i< int(hardOutgoing1.size()); ++i){
1818  if (abs(hardOutgoing1[i]) > 10 && abs(hardOutgoing1[i]) < 20) nFin++;
1819  // Bookkeep MSSM neutralinos as leptons
1820  if (abs(hardOutgoing1[i]) == 1000022) nFin++;
1821  // Bookkeep sleptons as leptons
1822  if ( abs(hardOutgoing1[i]) == 1000011 || abs(hardOutgoing1[i]) == 2000011
1823  || abs(hardOutgoing1[i]) == 1000013 || abs(hardOutgoing1[i]) == 2000013
1824  || abs(hardOutgoing1[i]) == 1000015 || abs(hardOutgoing1[i]) == 2000015)
1825  nFin++;
1826  }
1827  for(int i =0; i< int(hardOutgoing2.size()); ++i){
1828  if (abs(hardOutgoing2[i]) > 10 && abs(hardOutgoing2[i]) < 20) nFin++;
1829  // Bookkeep MSSM neutralinos as leptons
1830  if (abs(hardOutgoing2[i]) == 1000022) nFin++;
1831  // Bookkeep sleptons as leptons
1832  if ( abs(hardOutgoing2[i]) == 1000011 || abs(hardOutgoing2[i]) == 2000011
1833  || abs(hardOutgoing2[i]) == 1000013 || abs(hardOutgoing2[i]) == 2000013
1834  || abs(hardOutgoing2[i]) == 1000015 || abs(hardOutgoing2[i]) == 2000015)
1835  nFin++;
1836  }
1837  // For very loose hard process definition, check number of hard process
1838  // lepton explicitly.
1839  // Check lepton / neutrino containers as leptons
1840  for(int i =0; i< int(hardOutgoing1.size()); ++i)
1841  if (hardOutgoing1[i] == 1100)
1842  for(int j =0; j< int(PosOutgoing1.size()); ++j)
1843  if ( abs(state[PosOutgoing1[j]].id()) == 11
1844  || abs(state[PosOutgoing1[j]].id()) == 13
1845  || abs(state[PosOutgoing1[j]].id()) == 15 )
1846  nFin++;
1847  for(int i =0; i< int(hardOutgoing2.size()); ++i)
1848  if (hardOutgoing2[i] == 1200)
1849  for(int j =0; j< int(PosOutgoing2.size()); ++j)
1850  if ( abs(state[PosOutgoing2[j]].id()) == 12
1851  || abs(state[PosOutgoing2[j]].id()) == 14
1852  || abs(state[PosOutgoing2[j]].id()) == 16 )
1853  nFin++;
1854  return nFin;
1855 }
1856 
1857 //--------------------------------------------------------------------------
1858 
1859 // Function to get the number of uncoloured final state particles in the
1860 // hard process
1861 
1862 int HardProcess::nBosonsOut(){
1863  int nFin =0;
1864  for(int i =0; i< int(hardOutgoing1.size()); ++i){
1865  if (abs(hardOutgoing1[i]) > 20 && abs(hardOutgoing1[i]) <= 25) nFin++;
1866  }
1867  for(int i =0; i< int(hardOutgoing2.size()); ++i){
1868  if (abs(hardOutgoing2[i]) > 20 && abs(hardOutgoing2[i]) <= 25) nFin++;
1869  if ( hardOutgoing2[i] == 2400) nFin++;
1870  }
1871  return nFin;
1872 }
1873 
1874 //--------------------------------------------------------------------------
1875 
1876 // Function to get the number of coloured initial state partons in the
1877 // hard process
1878 
1879 int HardProcess::nQuarksIn(){
1880  int nIn =0;
1881  if (hardIncoming1 == 2212 || abs(hardIncoming1) < 10) nIn++;
1882  if (hardIncoming2 == 2212 || abs(hardIncoming2) < 10) nIn++;
1883  return nIn;
1884 }
1885 
1886 //--------------------------------------------------------------------------
1887 
1888 // Function to get the number of uncoloured initial state particles in the
1889 // hard process
1890 
1891 int HardProcess::nLeptonIn(){
1892  int nIn =0;
1893  if (abs(hardIncoming1) > 10 && abs(hardIncoming1) < 20) nIn++;
1894  if (abs(hardIncoming2) > 10 && abs(hardIncoming2) < 20) nIn++;
1895  return nIn;
1896 }
1897 
1898 //--------------------------------------------------------------------------
1899 
1900 // Function to report if a resonace decay was found in the
1901 // 2->2 hard sub-process in the current state
1902 
1903 int HardProcess::hasResInCurrent(){
1904  for(int i =0; i< int(PosIntermediate.size()); ++i)
1905  if (PosIntermediate[i] == 0) return 0;
1906  // Do not count final state bosons as resonaces
1907  for(int i =0; i< int(PosIntermediate.size()); ++i){
1908  for(int j =0; j< int(PosOutgoing1.size()); ++j){
1909  if ( PosIntermediate[i] == PosOutgoing1[j] )
1910  return 0;
1911  }
1912  for(int j =0; j< int(PosOutgoing2.size()); ++j){
1913  if ( PosIntermediate[i] == PosOutgoing2[j] )
1914  return 0;
1915  }
1916  }
1917  return 1;
1918 }
1919 
1920 //--------------------------------------------------------------------------
1921 
1922 // Function to report the number of resonace decays in the 2->2 sub-process
1923 // of the current state
1924 
1925 int HardProcess::nResInCurrent(){
1926  int nRes = 0;
1927  for(int i =0; i< int(PosIntermediate.size()); ++i){
1928  if (PosIntermediate[i] != 0) {
1929  bool matchesFinalBoson = false;
1930  for(int j =0; j< int(PosOutgoing1.size()); ++j){
1931  if ( PosIntermediate[i] == PosOutgoing1[j] )
1932  matchesFinalBoson = true;
1933  }
1934  for(int j =0; j< int(PosOutgoing2.size()); ++j){
1935  if ( PosIntermediate[i] == PosOutgoing2[j] )
1936  matchesFinalBoson = true;
1937  }
1938  if (!matchesFinalBoson) nRes++;
1939  }
1940  }
1941  return nRes;
1942 }
1943 
1944 //--------------------------------------------------------------------------
1945 
1946 // Function to report if a resonace decay was found in the
1947 // 2->2 hard core process
1948 
1949 bool HardProcess::hasResInProc(){
1950 
1951  for(int i =0; i< int(hardIntermediate.size()); ++i)
1952  if (hardIntermediate[i] == 0) return false;
1953  // Do not count final state bosons as resonaces
1954  for(int i =0; i< int(hardIntermediate.size()); ++i){
1955  for(int j =0; j< int(hardOutgoing1.size()); ++j){
1956  if ( hardIntermediate[i] == hardOutgoing1[j] )
1957  return false;
1958  }
1959  for(int j =0; j< int(hardOutgoing2.size()); ++j){
1960  if ( hardIntermediate[i] == hardOutgoing2[j] )
1961  return false;
1962  }
1963  }
1964  return true;
1965 }
1966 
1967 //--------------------------------------------------------------------------
1968 
1969 // Function to print the hard process (for debug)
1970 
1971 void HardProcess::list() const {
1972  cout << " Hard Process: ";
1973  cout << " \t " << hardIncoming1 << " + " << hardIncoming2;
1974  cout << " \t -----> \t ";
1975  for(int i =0; i < int(hardIntermediate.size());++i)
1976  cout << hardIntermediate[i] << " ";
1977  cout << " \t -----> \t ";
1978  for(int i =0; i < int(hardOutgoing1.size());++i)
1979  cout << hardOutgoing1[i] << " ";
1980  for(int i =0; i < int(hardOutgoing2.size());++i)
1981  cout << hardOutgoing2[i] << " ";
1982  cout << endl;
1983 }
1984 
1985 //--------------------------------------------------------------------------
1986 
1987 // Function to list the hard process candiates in the matrix element state
1988 // (for debug)
1989 
1990 void HardProcess::listCandidates() const {
1991  cout << " Hard Process candidates: ";
1992  cout << " \t " << hardIncoming1 << " + " << hardIncoming2;
1993  cout << " \t -----> \t ";
1994  for(int i =0; i < int(PosIntermediate.size());++i)
1995  cout << PosIntermediate[i] << " ";
1996  cout << " \t -----> \t ";
1997  for(int i =0; i < int(PosOutgoing1.size());++i)
1998  cout << PosOutgoing1[i] << " ";
1999  for(int i =0; i < int(PosOutgoing2.size());++i)
2000  cout << PosOutgoing2[i] << " ";
2001  cout << endl;
2002 }
2003 
2004 //--------------------------------------------------------------------------
2005 
2006 // Function to clear hard process information
2007 
2008 void HardProcess::clear() {
2009 
2010  // Clear flavour of the first incoming particle
2011  hardIncoming1 = hardIncoming2 = 0;
2012  // Clear outgoing particles
2013  hardOutgoing1.resize(0);
2014  hardOutgoing2.resize(0);
2015  // Clear intermediate bosons in the hard 2->2
2016  hardIntermediate.resize(0);
2017 
2018  // Clear reference event
2019  state.clear();
2020 
2021  // Clear potential positions of outgoing particles in reference event
2022  PosOutgoing1.resize(0);
2023  PosOutgoing2.resize(0);
2024  // Clear potential positions of intermediate bosons in reference event
2025  PosIntermediate.resize(0);
2026 
2027  // Clear merging scale read from LHE file
2028  tms = 0.;
2029 
2030 }
2031 
2032 //==========================================================================
2033 
2034 // The MergingHooks class.
2035 
2036 //--------------------------------------------------------------------------
2037 
2038 // Destructor
2039 MergingHooks::~MergingHooks() { if (useOwnHardProcess) delete hardProcess; }
2040 
2041 //--------------------------------------------------------------------------
2042 
2043 // Initialise MergingHooks class
2044 
2045 void MergingHooks::init(){
2046 
2047  // Save pointers
2048  showers = 0;
2049 
2050  // Initialise AlphaS objects for reweighting
2051  double alphaSvalueFSR = parm("TimeShower:alphaSvalue");
2052  int alphaSorderFSR = mode("TimeShower:alphaSorder");
2053  int alphaSnfmax = mode("StandardModel:alphaSnfmax");
2054  int alphaSuseCMWFSR= flag("TimeShower:alphaSuseCMW");
2055  AlphaS_FSRSave.init(alphaSvalueFSR, alphaSorderFSR, alphaSnfmax,
2056  alphaSuseCMWFSR);
2057  double alphaSvalueISR = parm("SpaceShower:alphaSvalue");
2058  int alphaSorderISR = mode("SpaceShower:alphaSorder");
2059  int alphaSuseCMWISR= flag("SpaceShower:alphaSuseCMW");
2060  AlphaS_ISRSave.init(alphaSvalueISR, alphaSorderISR, alphaSnfmax,
2061  alphaSuseCMWISR);
2062 
2063  // Initialise AlphaEM objects for reweighting
2064  int alphaEMFSRorder = mode("TimeShower:alphaEMorder");
2065  AlphaEM_FSRSave.init(alphaEMFSRorder, settingsPtr);
2066  int alphaEMISRorder = mode("SpaceShower:alphaEMorder");
2067  AlphaEM_ISRSave.init(alphaEMISRorder, settingsPtr);
2068 
2069  // Initialise merging switches
2070  doUserMergingSave = flag("Merging:doUserMerging");
2071  // Initialise automated MadGraph kT merging
2072  doMGMergingSave = flag("Merging:doMGMerging");
2073  // Initialise kT merging
2074  doKTMergingSave = flag("Merging:doKTMerging");
2075  // Initialise evolution-pT merging
2076  doPTLundMergingSave = flag("Merging:doPTLundMerging");
2077  // Initialise \Delta_R_{ij}, pT_i Q_{ij} merging
2078  doCutBasedMergingSave = flag("Merging:doCutBasedMerging");
2079  // Initialise exact definition of kT
2080  ktTypeSave = mode("Merging:ktType");
2081 
2082  // Initialise NL3 switches.
2083  doNL3TreeSave = flag("Merging:doNL3Tree");
2084  doNL3LoopSave = flag("Merging:doNL3Loop");
2085  doNL3SubtSave = flag("Merging:doNL3Subt");
2086  bool doNL3 = doNL3TreeSave || doNL3LoopSave || doNL3SubtSave;
2087 
2088  // Initialise UNLOPS switches.
2089  doUNLOPSTreeSave = flag("Merging:doUNLOPSTree");
2090  doUNLOPSLoopSave = flag("Merging:doUNLOPSLoop");
2091  doUNLOPSSubtSave = flag("Merging:doUNLOPSSubt");
2092  doUNLOPSSubtNLOSave = flag("Merging:doUNLOPSSubtNLO");
2093  bool doUNLOPS = doUNLOPSTreeSave || doUNLOPSLoopSave
2094  || doUNLOPSSubtSave || doUNLOPSSubtNLOSave;
2095 
2096  // Initialise UMEPS switches
2097  doUMEPSTreeSave = flag("Merging:doUMEPSTree");
2098  doUMEPSSubtSave = flag("Merging:doUMEPSSubt");
2099  nReclusterSave = mode("Merging:nRecluster");
2100  nQuarksMergeSave = mode("Merging:nQuarksMerge");
2101  nRequestedSave = mode("Merging:nRequested");
2102  bool doUMEPS = doUMEPSTreeSave || doUMEPSSubtSave;
2103 
2104  // Flag to only do phase space cut.
2105  doEstimateXSection = flag("Merging:doXSectionEstimate");
2106 
2107  // Flag to check if merging weight should directly be included in the cross
2108  // section.
2109  includeWGTinXSECSave = flag("Merging:includeWeightInXsection");
2110 
2111  // Flag to check if CKKW-L event veto should be applied.
2112  applyVeto = flag("Merging:applyVeto");
2113 
2114  // Get core process from user input
2115  processSave = word("Merging:Process");
2116  processNow = processSave;
2117  bool doGuess = (processNow.find("guess") != string::npos);
2118 
2119  // If the process string is "guess", temporarily set it to something safe
2120  // for initialization.
2121  if (processNow.find("guess") != string::npos) processNow = "pp>e+e-";
2122 
2123  if (!hardProcess) {
2124  hardProcess = new HardProcess();
2125  useOwnHardProcess = true;
2126  }
2127 
2128  // Clear hard process
2129  hardProcess->clear();
2130 
2131  // Initialise input event.
2132  inputEvent.init("(hard process)", particleDataPtr);
2133  doRemoveDecayProducts = doGuess || flag("Merging:mayRemoveDecayProducts");
2134  settingsPtr->flag("Merging:mayRemoveDecayProducts",doRemoveDecayProducts);
2135 
2136  // Initialise the hard process
2137  if ( doMGMergingSave )
2138  hardProcess->initOnLHEF(lheInputFile, particleDataPtr);
2139  else
2140  hardProcess->initOnProcess(processNow, particleDataPtr);
2141 
2142  // Remove whitespace from process string
2143  while(processSave.find(" ", 0) != string::npos)
2144  processSave.erase(processSave.begin()+processSave.find(" ",0));
2145 
2146  // Parameters for reconstruction of evolution scales
2147  includeMassiveSave = flag("Merging:includeMassive");
2148  enforceStrongOrderingSave = flag("Merging:enforceStrongOrdering");
2149  scaleSeparationFactorSave = parm("Merging:scaleSeparationFactor");
2150  orderInRapiditySave = flag("Merging:orderInRapidity");
2151 
2152  // Parameters for choosing history probabilistically
2153  nonJoinedNormSave = parm("Merging:nonJoinedNorm");
2154  fsrInRecNormSave = parm("Merging:fsrInRecNorm");
2155  pickByFullPSave = flag("Merging:pickByFullP");
2156  pickByPoPT2Save = flag("Merging:pickByPoPT2");
2157  includeRedundantSave = flag("Merging:includeRedundant");
2158 
2159  // Parameters for scale choices
2160  unorderedScalePrescipSave = mode("Merging:unorderedScalePrescrip");
2161  unorderedASscalePrescipSave = mode("Merging:unorderedASscalePrescrip");
2162  unorderedPDFscalePrescipSave = mode("Merging:unorderedPDFscalePrescrip");
2163  incompleteScalePrescipSave = mode("Merging:incompleteScalePrescrip");
2164 
2165  // Parameter for allowing swapping of one colour index while reclustering
2166  allowColourShufflingSave = flag("Merging:allowColourShuffling");
2167 
2168  // Parameters to allow setting hard process scales to default (dynamical)
2169  // Pythia values.
2170  resetHardQRenSave = flag("Merging:usePythiaQRenHard");
2171  resetHardQFacSave = flag("Merging:usePythiaQFacHard");
2172 
2173  // Parameters for choosing history by sum(|pT|)
2174  pickBySumPTSave = flag("Merging:pickBySumPT");
2175  herwigAcollFSRSave = parm("Merging:aCollFSR");
2176  herwigAcollISRSave = parm("Merging:aCollISR");
2177 
2178  // Information on the shower cut-off scale
2179  pT0ISRSave = parm("SpaceShower:pT0Ref");
2180  pTcutSave = parm("SpaceShower:pTmin");
2181  pTcutSave = max(pTcutSave,pT0ISRSave);
2182 
2183  // Information on renormalization scale variations
2184  muRVarFactors = infoPtr->weightContainerPtr->weightsMerging.
2185  getMuRVarFactors();
2186  doVariations = muRVarFactors.size() ? true : false;
2187  nWgts = 1+muRVarFactors.size();
2188 
2189  // Initialise CKKWL weight
2190  weightCKKWLSave = vector<double>( nWgts, 1. );
2191  weightFIRSTSave = vector<double>( nWgts, 0. );
2192  nMinMPISave = 100;
2193  muMISave = -1.;
2194 
2195  // Initialize merging weights in weight container
2196  vector<string> weightNames = {"MUR1.0_MUF1.0"};
2197  for (double fact: muRVarFactors) {
2198  weightNames.push_back("MUR"+std::to_string(fact)+"_MUF1.0");
2199  }
2200  infoPtr->weightContainerPtr->weightsMerging.bookVectors(
2201  weightCKKWLSave,weightFIRSTSave,weightNames);
2202 
2203  // Initialise merging scale
2204  tmsValueSave = 0.;
2205  tmsListSave.resize(0);
2206 
2207  kFactor0jSave = parm("Merging:kFactor0j");
2208  kFactor1jSave = parm("Merging:kFactor1j");
2209  kFactor2jSave = parm("Merging:kFactor2j");
2210 
2211  muFSave = parm("Merging:muFac");
2212  muRSave = parm("Merging:muRen");
2213  muFinMESave = parm("Merging:muFacInME");
2214  muRinMESave = parm("Merging:muRenInME");
2215 
2216  doWeakClusteringSave = flag("Merging:allowWeakClustering");
2217  doSQCDClusteringSave = flag("Merging:allowSQCDClustering");
2218  DparameterSave = parm("Merging:Dparameter");
2219 
2220  // Save merging scale on maximal number of jets
2221  if ( doKTMergingSave || doUserMergingSave || doPTLundMergingSave
2222  || doUMEPS ) {
2223  // Read merging scale (defined in kT) from input parameter.
2224  tmsValueSave = parm("Merging:TMS");
2225  nJetMaxSave = mode("Merging:nJetMax");
2226  nJetMaxNLOSave = -1;
2227  } else if (doMGMergingSave) {
2228  // Read merging scale (defined in kT) from LHE file.
2229  tmsValueSave = hardProcess->tms;
2230  nJetMaxSave = mode("Merging:nJetMax");
2231  nJetMaxNLOSave = -1;
2232  } else if (doCutBasedMergingSave) {
2233 
2234  // Save list of cuts defining the merging scale.
2235  nJetMaxSave = mode("Merging:nJetMax");
2236  nJetMaxNLOSave = -1;
2237  // Write tms cut values to list of cut values,
2238  // ordered by DeltaR_{ij}, pT_{i}, Q_{ij}.
2239  tmsListSave.resize(0);
2240  double drms = parm("Merging:dRijMS");
2241  double ptms = parm("Merging:pTiMS");
2242  double qms = parm("Merging:QijMS");
2243  tmsListSave.push_back(drms);
2244  tmsListSave.push_back(ptms);
2245  tmsListSave.push_back(qms);
2246 
2247  }
2248 
2249  // Read additional settings for NLO merging methods.
2250  if ( doNL3 || doUNLOPS || doEstimateXSection ) {
2251  tmsValueSave = parm("Merging:TMS");
2252  nJetMaxSave = mode("Merging:nJetMax");
2253  nJetMaxNLOSave = mode("Merging:nJetMaxNLO");
2254  }
2255 
2256  tmsValueNow = tmsValueSave;
2257 
2258  // Internal Pythia cross section should not include NLO merging weights.
2259  if ( doNL3 || doUNLOPS ) includeWGTinXSECSave = false;
2260 
2261  hasJetMaxLocal = false;
2262  nJetMaxLocal = nJetMaxSave;
2263  nJetMaxNLOLocal = nJetMaxNLOSave;
2264 
2265  // Check if external shower plugin should be used.
2266  useShowerPluginSave = flag("Merging:useShowerPlugin");
2267 
2268  bool writeBanner = doKTMergingSave || doMGMergingSave
2269  || doUserMergingSave
2270  || doNL3 || doUNLOPS || doUMEPS
2271  || doPTLundMergingSave || doCutBasedMergingSave;
2272 
2273  if (!writeBanner) return;
2274 
2275  // Write banner.
2276  cout << "\n *------------------ MEPS Merging Initialization ---------------"
2277  << "---*";
2278  cout << "\n | "
2279  << " |\n";
2280  if ( doKTMergingSave || doMGMergingSave || doUserMergingSave
2281  || doPTLundMergingSave || doCutBasedMergingSave )
2282  cout << " | CKKW-L merge "
2283  << " |\n"
2284  << " |"<< setw(34) << processSave << " with up to"
2285  << setw(3) << nJetMaxSave << " additional jets |\n";
2286  else if ( doNL3 )
2287  cout << " | NL3 merge "
2288  << " |\n"
2289  << " |" << setw(31) << processSave << " with jets up to"
2290  << setw(3) << nJetMaxNLOSave << " correct to NLO |\n"
2291  << " | and up to" << setw(3) << nJetMaxSave
2292  << " additional jets included by CKKW-L merging at LO |\n";
2293  else if ( doUNLOPS )
2294  cout << " | UNLOPS merge "
2295  << " |\n"
2296  << " |" << setw(31) << processSave << " with jets up to"
2297  << setw(3)<< nJetMaxNLOSave << " correct to NLO |\n"
2298  << " | and up to" << setw(3) << nJetMaxSave
2299  << " additional jets included by UMEPS merging at LO |\n";
2300  else if ( doUMEPS )
2301  cout << " | UMEPS merge "
2302  << " |\n"
2303  << " |" << setw(34) << processSave << " with up to"
2304  << setw(3) << nJetMaxSave << " additional jets |\n";
2305 
2306  if ( doKTMergingSave )
2307  cout << " | Merging scale is defined in kT, with value ktMS = "
2308  << tmsValueSave << " GeV";
2309  else if ( doMGMergingSave )
2310  cout << " | Perform automanted MG/ME merging \n"
2311  << " | Merging scale is defined in kT, with value ktMS = "
2312  << setw(6) << fixed << setprecision(1) << tmsValueSave << " GeV |";
2313  else if ( doUserMergingSave )
2314  cout << " | Merging scale is defined by the user, with value tMS = "
2315  << setw(6) << fixed << setprecision(1) << tmsValueSave << " |";
2316  else if ( doPTLundMergingSave )
2317  cout << " | Merging scale is defined by Lund pT, with value tMS = "
2318  << setw(6) << fixed << setprecision(1) << tmsValueSave << " GeV |";
2319  else if ( doCutBasedMergingSave )
2320  cout << " | Merging scale is defined by combination of Delta R_{ij}, pT_i "
2321  << " |\n"
2322  << " | and Q_{ij} cut, with values "
2323  << " |\n"
2324  << " | Delta R_{ij,min} = "
2325  << setw(7) << scientific << setprecision(2) << tmsListSave[0]
2326  << " |\n"
2327  << " | pT_{i,min} = "
2328  << setw(6) << fixed << setprecision(1) << tmsListSave[1]
2329  << " GeV |\n"
2330  << " | Q_{ij,min} = "
2331  << setw(6) << fixed << setprecision(1) << tmsListSave[2]
2332  << " GeV |";
2333  else if ( doNL3TreeSave )
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 ( doNL3LoopSave )
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 ( doNL3SubtSave )
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 ( doUNLOPSTreeSave )
2349  cout << " | Generate tree-level O(alpha_s)-subtracted 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 ( doUNLOPSLoopSave )
2354  cout << " | Generate virtual correction unit-weight 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 ( doUNLOPSSubtSave )
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  else if ( doUNLOPSSubtNLOSave )
2364  cout << " | Generate reclustered loop-level events "
2365  << " |\n"
2366  << " | Merging scale is defined by Lund pT, with value tMS = "
2367  << setw(6) << fixed << setprecision(1) << tmsValueSave << " GeV |";
2368  else if ( doUMEPSTreeSave )
2369  cout << " | Generate tree-level events "
2370  << " |\n"
2371  << " | Merging scale is defined by Lund pT, with value tMS = "
2372  << setw(6) << fixed << setprecision(1) << tmsValueSave << " GeV |";
2373  else if ( doUMEPSSubtSave )
2374  cout << " | Generate reclustered tree-level events "
2375  << " |\n"
2376  << " | Merging scale is defined by Lund pT, with value tMS = "
2377  << setw(6) << fixed << setprecision(1) << tmsValueSave << " GeV |";
2378 
2379  cout << "\n | "
2380  << " |";
2381  cout << "\n *-------------- END MEPS Merging Initialization ---------------"
2382  << "---*\n\n";
2383 
2384 }
2385 
2386 //--------------------------------------------------------------------------
2387 
2388 // Function to check if emission should be rejected.
2389 
2390 bool MergingHooks::doVetoEmission( const Event& event) {
2391 
2392  // Do nothing in trial showers, or after first step.
2393  if ( doIgnoreEmissionsSave ) return false;
2394 
2395  // Do nothing in CKKW-L
2396  if ( doUserMerging() || doMGMerging() || doKTMerging()
2397  || doPTLundMerging() || doCutBasedMerging() )
2398  return false;
2399 
2400  // For NLO merging, count and veto emissions above the merging scale
2401  bool veto = false;
2402  // Get number of clustering steps
2403  int nSteps = getNumberOfClusteringSteps(event);
2404  // Get merging scale in current event
2405  double tnow = tmsNow( event);
2406 
2407  // Get maximal number of additional jets
2408  int nJetMax = nMaxJets();
2409  // Always remove emissions above the merging scale for
2410  // samples containing reclusterings!
2411  if ( nRecluster() > 0 ) nSteps = 1;
2412  // Check veto condition
2413  if ( nSteps - 1 < nJetMax && nSteps >= 1 && tnow > tms() ) veto = true;
2414 
2415  // Do not veto if state already includes MPI.
2416  if ( infoPtr->nMPI() > 1 ) veto = false;
2417 
2418  // When performing NL3 merging of tree-level events, reset the
2419  // CKKWL weight.
2420  if ( veto && doNL3Tree() ) setWeightCKKWL(vector<double>(nWgts, 0.));
2421 
2422  // If the emission is allowed, do not check any further emissions
2423  if ( !veto ) doIgnoreEmissionsSave = true;
2424 
2425  // Done
2426  return veto;
2427 
2428 }
2429 
2430 //--------------------------------------------------------------------------
2431 
2432 // Function to check if emission should be rejected.
2433 
2434 bool MergingHooks::doVetoStep( const Event& process, const Event& event,
2435  bool doResonance ) {
2436 
2437  // Do nothing in trial showers, or after first step.
2438  if ( doIgnoreStepSave && !doResonance ) return false;
2439 
2440  // Do nothing in UMEPS or UNLOPS
2441  if ( doUMEPSTree() || doUMEPSSubt() || doUMEPSMerging() || doUNLOPSTree()
2442  || doUNLOPSLoop() || doUNLOPSSubt() || doUNLOPSSubtNLO()
2443  || doUNLOPSMerging() )
2444  return false;
2445 
2446  // Get number of clustering steps. If necessary, remove resonance
2447  // decay products first.
2448  int nSteps = 0;
2449  if ( getProcessString().find("inc") != string::npos )
2450  nSteps = getNumberOfClusteringSteps( bareEvent( process, false) );
2451  else nSteps = (doResonance) ? getNumberOfClusteringSteps(process)
2452  : getNumberOfClusteringSteps( bareEvent( process, false) );
2453  int nStepsAfter = getNumberOfClusteringSteps(event);
2454  // Get maximal number of additional jets.
2455  int nJetMax = nMaxJets();
2456 
2457  // Get merging scale in current event.
2458  double tnow = tmsNow( event );
2459 
2460  // Do not print zero-weight events.
2461  // For non-resonant showers, simply check veto. If event should indeed be
2462  // vetoed, save the current pT and weights in case the veto needs to be
2463  // revoked.
2464  if ( !doResonance ) {
2465 
2466  // Store pT to check if veto needs to be revoked later.
2467  pTsave = infoPtr->pTnow();
2468  if ( nRecluster() == 1) nSteps--;
2469 
2470  // Store veto inputs to perform veto at a later stage.
2471  if (!applyVeto) {
2472  setEventVetoInfo(nSteps, tnow);
2473  if ( nStepsAfter > nSteps && nSteps > nMaxJetsNLO() && nSteps < nJetMax
2474  && tnow > tms() ) {
2475  // Set weight to zero if event should be vetoed.
2476  weightCKKWL1Save = vector<double>(nWgts, 0.);
2477  // Save weight before veto, in case veto needs to be revoked.
2478  weightCKKWL2Save = getWeightCKKWL();
2479  // Reset stored weights.
2480  if ( !includeWGTinXSEC() ) setWeightCKKWL(vector<double>( nWgts, 0. ));
2481  if ( includeWGTinXSEC() ) infoPtr->weightContainerPtr->
2482  setWeightNominal(0.);
2483  }
2484  return false;
2485  }
2486 
2487  // Check merging veto condition.
2488  bool veto = false;
2489 
2490  if ( nStepsAfter > nSteps && nSteps > nMaxJetsNLO() && nSteps < nJetMax
2491  && tnow > tms()) {
2492  // Set weight to zero if event should be vetoed.
2493  weightCKKWL1Save = vector<double>( nWgts, 0. );
2494  // Save weight before veto, in case veto needs to be revoked.
2495  weightCKKWL2Save = getWeightCKKWL();
2496  // Reset stored weights.
2497  if ( !includeWGTinXSEC() ) setWeightCKKWL(vector<double>( nWgts, 0. ));
2498  if ( includeWGTinXSEC() ) infoPtr->weightContainerPtr->
2499  setWeightNominal(0.);
2500  veto = true;
2501  }
2502 
2503  // Done
2504  return veto;
2505 
2506  // For resonant showers, check if any previous veto should be revoked.
2507  // This means we treat showers off resonance decay products identical to
2508  // MPI: If a hard resonance emission has been produced, the event should
2509  // have been kept. Following this reasoning, it might be necessary to revoke
2510  // any previous veto.
2511  } else {
2512 
2513  // Initialise switch to revoke vetoing.
2514  bool revokeVeto = false;
2515 
2516  // Nothing to check if pTsave was not stored, i.e. no emission to
2517  // possibly veto was recorded.
2518  // Only allow revoking the veto for diboson processes, with resonant
2519  // electroweak bosons
2520  bool check = (nHardInLeptons() == 0)&& (nHardOutLeptons() == 2)
2521  && (nHardOutPartons() == 2);
2522 
2523  // For current purpose only!!!
2524  check = false;
2525 
2526  // For hadronic resonance decays at hadron colliders, do not veto
2527  // events with a hard emission of the resonance decay products,
2528  // since such states are not included in the matrix element
2529  if ( pTsave > 0. && check ) {
2530 
2531  // Check how many resonance decay systems are allowed
2532  int nResNow = nResInCurrent();
2533 
2534  // Find systems really containing only emission off a resonance
2535  // decay
2536  vector<int>goodSys;
2537  // Resonance decay systems are considered last, thus at the end of
2538  // the list
2539  int sysSize = partonSystemsPtr->sizeSys();
2540  for ( int i=0; i < nResNow; ++i ) {
2541  if ( partonSystemsPtr->sizeOut(sysSize - 1 - i) == 3 )
2542  goodSys.push_back(sysSize - 1 - i);
2543  }
2544 
2545  // Check the members of the resonance decay systems
2546  for ( int i=0; i < int(goodSys.size()); ++i ) {
2547 
2548  // Save the (three) members of the resonance decay system
2549  int iMem1 = partonSystemsPtr->getOut(goodSys[i],0);
2550  int iMem2 = partonSystemsPtr->getOut(goodSys[i],1);
2551  int iMem3 = partonSystemsPtr->getOut(goodSys[i],2);
2552 
2553  // Now find emitted gluon or gamma
2554  int iEmtGlue = ((event[iMem1].id() == 21) ? iMem1
2555  : ((event[iMem2].id() == 21) ? iMem2
2556  : ((event[iMem3].id() == 21) ? iMem3: 0)));
2557  int iEmtGamm = ((event[iMem1].id() == 22) ? iMem1
2558  : ((event[iMem2].id() == 22) ? iMem2
2559  : ((event[iMem3].id() == 22) ? iMem3: 0)));
2560  // Per system, only one emission
2561  int iEmt = (iEmtGlue != 0) ? iEmtGlue : iEmtGamm;
2562 
2563  int iRad = 0;
2564  int iRec = 0;
2565  if ( iEmt == iMem1 ) {
2566  iRad = (event[iMem2].mother1() != event[iMem2].mother2())
2567  ? iMem2 : iMem3;
2568  iRec = (event[iMem3].mother1() == event[iMem3].mother2())
2569  ? iMem3 : iMem2;
2570  } else if ( iEmt == iMem2 ) {
2571  iRad = (event[iMem1].mother1() != event[iMem1].mother2())
2572  ? iMem1 : iMem3;
2573  iRec = (event[iMem3].mother1() == event[iMem3].mother2())
2574  ? iMem3 : iMem1;
2575  } else {
2576  iRad = (event[iMem1].mother1() != event[iMem1].mother2())
2577  ? iMem1 : iMem2;
2578  iRec = (event[iMem2].mother1() == event[iMem2].mother2())
2579  ? iMem2 : iMem1;
2580  }
2581 
2582  double pTres = rhoPythia(event, iRad, iEmt, iRec, 1);
2583 
2584  // Revoke previous veto of last emission if a splitting of the
2585  // resonance produced a harder parton, i.e. we are inside the
2586  // PS region
2587  if ( pTres > pTsave ) {
2588  revokeVeto = true;
2589  // Do nothing (i.e. allow other first emission veto) for soft
2590  // splitting
2591  } else {
2592  revokeVeto = false;
2593  }
2594  // Done with one system
2595  }
2596  // Done with all systems
2597  }
2598 
2599  // Check veto condition
2600  bool veto = false;
2601  if ( revokeVeto && check ) {
2602  setWeightCKKWL(weightCKKWL2Save);
2603  } else if ( check ) {
2604  setWeightCKKWL(weightCKKWL1Save);
2605  if ( weightCKKWL1Save[0] == 0. ) veto = true;
2606  }
2607 
2608  // Check veto condition.
2609  if ( !check && nSteps > nMaxJetsNLO() && nSteps < nJetMax && tnow > tms()){
2610  // Set stored weights to zero.
2611  if ( !includeWGTinXSEC() ) setWeightCKKWL(vector<double>( nWgts, 0.));
2612  if ( includeWGTinXSEC() ) infoPtr->weightContainerPtr->
2613  setWeightNominal(0.);
2614  // Now allow veto.
2615  veto = true;
2616  }
2617 
2618  // If the emission is allowed, do not check any further emissions
2619  if ( !veto || !doIgnoreStepSave ) doIgnoreStepSave = true;
2620 
2621  // Done
2622  return veto;
2623 
2624  }
2625 
2626  // Done
2627  return false;
2628 
2629 }
2630 
2631 //--------------------------------------------------------------------------
2632 
2633 // Return event stripped from decay products.
2634 
2635 Event MergingHooks::bareEvent(const Event& inputEventIn,
2636  bool storeInputEvent ) {
2637 
2638  // Find and detach decay products.
2639  Event newProcess = Event();
2640  newProcess.init("(hard process-modified)", particleDataPtr);
2641 
2642  // If desired, store input event.
2643  if ( storeInputEvent ) {
2644  resonances.resize(0);
2645  inputEvent.clear();
2646  inputEvent.init("(hard process)", particleDataPtr);
2647  for (int i = 0; i < inputEventIn.size(); ++i)
2648  inputEvent.append( inputEventIn[i] );
2649  for (int i = 0; i < inputEventIn.sizeJunction(); ++i)
2650  inputEvent.appendJunction( inputEventIn.getJunction(i) );
2651  inputEvent.saveSize();
2652  inputEvent.saveJunctionSize();
2653  }
2654 
2655  // Now remove decay products.
2656  if ( doRemoveDecayProducts ) {
2657 
2658  // Add the beam and initial partons to the event record.
2659  for (int i = 0; i < inputEventIn.size(); ++ i) {
2660  if ( inputEventIn[i].mother1() > 4
2661  || inputEventIn[i].statusAbs() == 22
2662  || inputEventIn[i].statusAbs() == 23)
2663  break;
2664  newProcess.append(inputEventIn[i]);
2665  }
2666 
2667  // Add the intermediate particles to the event record.
2668  for (int i = 0; i < inputEventIn.size(); ++ i) {
2669  if (inputEventIn[i].mother1() > 4) break;
2670  if ( inputEventIn[i].statusAbs() == 22) {
2671  int j = newProcess.append(inputEventIn[i]);
2672  newProcess[j].statusPos();
2673  if ( storeInputEvent ) resonances.push_back( make_pair(j, i) );
2674  newProcess[j].daughters(0, 0);
2675  }
2676  }
2677 
2678  // Add remaining outgoing particles to the event record.
2679  for (int i = 0; i < inputEventIn.size(); ++ i) {
2680  if (inputEventIn[i].mother1() > 4) break;
2681  if ( inputEventIn[i].statusAbs() != 11
2682  && inputEventIn[i].statusAbs() != 12
2683  && inputEventIn[i].statusAbs() != 21
2684  && inputEventIn[i].statusAbs() != 22)
2685  newProcess.append(inputEventIn[i]);
2686  }
2687 
2688  // Update event colour tag to maximum in whole process.
2689  int maxColTag = 0;
2690  for (int i = 0; i < inputEventIn.size(); ++ i) {
2691  if ( inputEventIn[i].col() > maxColTag )
2692  maxColTag = inputEventIn[i].col();
2693  if ( inputEventIn[i].acol() > maxColTag )
2694  maxColTag = inputEventIn[i].acol();
2695  }
2696  newProcess.initColTag(maxColTag);
2697 
2698  // Copy junctions from process to newProcess.
2699  for (int i = 0; i < inputEventIn.sizeJunction(); ++i)
2700  newProcess.appendJunction( inputEventIn.getJunction(i));
2701 
2702  newProcess.saveSize();
2703  newProcess.saveJunctionSize();
2704 
2705  } else {
2706  newProcess = inputEventIn;
2707  }
2708 
2709  // Remember scale
2710  newProcess.scale( inputEventIn.scale() );
2711 
2712  // Done
2713  return newProcess;
2714 
2715 }
2716 
2717 //--------------------------------------------------------------------------
2718 
2719 // Write event with decay products attached to argument. Only possible if an
2720 // input event with decay producs had been stored before.
2721 
2722 bool MergingHooks::reattachResonanceDecays(Event& process ) {
2723 
2724  // Now reattach the decay products.
2725  if ( doRemoveDecayProducts && inputEvent.size() > 0 ) {
2726 
2727  int sizeBef = process.size();
2728  // Vector of resonances for which the decay products were already attached.
2729  vector<int> iAftChecked;
2730  // Reset daughters and status of intermediate particles.
2731  for ( int i = 0; i < int(resonances.size()); ++i ) {
2732  for (int j = 0; j < sizeBef; ++j ) {
2733  if ( j != resonances[i].first ) continue;
2734 
2735  int iOldDaughter1 = inputEvent[resonances[i].second].daughter1();
2736  int iOldDaughter2 = inputEvent[resonances[i].second].daughter2();
2737 
2738  // Get momenta in case of reclustering.
2739  int iHardMother = resonances[i].second;
2740  Particle& hardMother = inputEvent[iHardMother];
2741  // Find current mother copy (after clustering).
2742  int iAftMother = 0;
2743  for ( int k = 0; k < process.size(); ++k )
2744  if ( process[k].id() == inputEvent[resonances[i].second].id() ) {
2745  // Only attempt if decays of this resonance were not attached.
2746  bool checked = false;
2747  for ( int l = 0; l < int(iAftChecked.size()); ++l )
2748  if ( k == iAftChecked[l] )
2749  checked = true;
2750  if ( !checked ) {
2751  iAftChecked.push_back(k);
2752  iAftMother = k;
2753  break;
2754  }
2755  }
2756 
2757  Particle& aftMother = process[iAftMother];
2758 
2759  // Resonance can have been moved by clustering,
2760  // so prepare to update colour and momentum information for system.
2761  int colBef = hardMother.col();
2762  int acolBef = hardMother.acol();
2763  int colAft = aftMother.col();
2764  int acolAft = aftMother.acol();
2765  RotBstMatrix M;
2766  M.bst( hardMother.p(), aftMother.p());
2767 
2768  // Attach resonance decay products.
2769  int iNewDaughter1 = 0;
2770  int iNewDaughter2 = 0;
2771  for ( int k = iOldDaughter1; k <= iOldDaughter2; ++k ) {
2772  if ( k == iOldDaughter1 )
2773  iNewDaughter1 = process.append(inputEvent[k] );
2774  else
2775  iNewDaughter2 = process.append(inputEvent[k] );
2776  process.back().statusPos();
2777  Particle& now = process.back();
2778  // Update colour and momentum information.
2779  if (now.col() != 0 && now.col() == colBef ) now.col(colAft);
2780  if (now.acol() != 0 && now.acol() == acolBef) now.acol(acolAft);
2781  now.rotbst( M);
2782  // Update vertex information.
2783  if (now.hasVertex()) now.vProd( aftMother.vDec() );
2784  // Update mothers.
2785  now.mothers(iAftMother,0);
2786  }
2787 
2788  process[iAftMother].daughters( iNewDaughter1, iNewDaughter2 );
2789  process[iAftMother].statusNeg();
2790 
2791  // Loop through event and attach remaining decays
2792  int iDec = 0;
2793  do {
2794  if ( process[iDec].isFinal() && process[iDec].canDecay()
2795  && process[iDec].mayDecay() && process[iDec].isResonance() ) {
2796 
2797  int iD1 = process[iDec].daughter1();
2798  int iD2 = process[iDec].daughter2();
2799 
2800  // Done if no daughters exist.
2801  if ( iD1 == 0 || iD2 == 0 ) continue;
2802 
2803  // Attach daughters.
2804  int iNewDaughter12 = 0;
2805  int iNewDaughter22 = 0;
2806  for ( int k = iD1; k <= iD2; ++k ) {
2807  if ( k == iD1 )
2808  iNewDaughter12 = process.append(inputEvent[k] );
2809  else
2810  iNewDaughter22 = process.append(inputEvent[k] );
2811  process.back().statusPos();
2812  Particle& now = process.back();
2813  // Update colour and momentum information.
2814  if (now.col() != 0 && now.col() == colBef ) now.col(colAft);
2815  if (now.acol()!= 0 && now.acol()== acolBef) now.acol(acolAft);
2816  now.rotbst( M);
2817  // Update vertex information.
2818  if (now.hasVertex()) now.vProd( process[iDec].vDec() );
2819  // Update mothers.
2820  now.mothers(iDec,0);
2821  }
2822 
2823  // Modify mother status and daughters.
2824  process[iDec].status(-22);
2825  process[iDec].daughters(iNewDaughter12, iNewDaughter22);
2826 
2827  // End of loop over all entries.
2828  }
2829  } while (++iDec < process.size());
2830  } // End loop over process entries.
2831  } // End loop over resonances.
2832 
2833  // Update event colour tag to maximum in whole process.
2834  int maxColTag = 0;
2835  for (int i = 0; i < process.size(); ++ i) {
2836  if (process[i].col() > maxColTag) maxColTag = process[i].col();
2837  if (process[i].acol() > maxColTag) maxColTag = process[i].acol();
2838  }
2839  process.initColTag(maxColTag);
2840 
2841  }
2842 
2843  // Done.
2844  return (doRemoveDecayProducts) ? inputEvent.size() > 0 : true;
2845 
2846 }
2847 
2848 //--------------------------------------------------------------------------
2849 
2850 bool MergingHooks::isInHard( int iPos, const Event& event){
2851 
2852  // MPI not part of hard process
2853  if ( event[iPos].statusAbs() > 30 && event[iPos].statusAbs() < 40 )
2854  return false;
2855  // Beam remnants and hadronisation not part of hard process
2856  if ( event[iPos].statusAbs() > 60 )
2857  return false;
2858 
2859  // Still MPI: Check that the particle is not due to radiation off MPIs.
2860  // First get all intermediate MPI partons in the state.
2861  vector<int> mpiParticlePos;
2862  mpiParticlePos.clear();
2863  for ( int i=0; i < event.size(); ++i )
2864  if ( event[i].statusAbs() > 30
2865  && event[i].statusAbs() < 40 )
2866  mpiParticlePos.push_back(i);
2867  // Disregard any parton iPos that has MPI ancestors.
2868  for ( int i=0; i < int(mpiParticlePos.size()); ++i)
2869  if ( event[iPos].isAncestor( mpiParticlePos[i]) )
2870  return false;
2871 
2872  // Disallow other systems.
2873  // Get sub-system of particles for iPos
2874  int iSys = partonSystemsPtr->getSystemOf(iPos, !event[iPos].isFinal() );
2875  if ( iSys > 0 ) {
2876  int sysSize = partonSystemsPtr->sizeAll(iSys);
2877 
2878  // First do simple check if the system is sensible. Might not be the
2879  // case when constructing a process record by hand, yet still keeping the
2880  // partonSystems. Remember to not check problematic systems.
2881  bool isGoodSys = true;
2882  for ( int i = 0; i < sysSize; ++i ) {
2883  int iPosNow = partonSystemsPtr->getAll( iSys, i );
2884  if (iPosNow >= event.size()) isGoodSys = false;
2885  }
2886 
2887  // Check all partons belonging to the same system as iPos. If any is
2888  // produced in MPI or has MPI ancestors, the whole system is not the
2889  // hard subprocess, i.e. iPos is not in the hard subprocess.
2890  if (isGoodSys) {
2891  for ( int i = 0; i < sysSize; ++i ) {
2892  int iPosNow = partonSystemsPtr->getAll( iSys, i );
2893  // MPI not part of hard process
2894  if ( event[iPosNow].statusAbs() > 30
2895  && event[iPosNow].statusAbs() < 40 )
2896  return false;
2897  // Disregard any parton iPos that has MPI ancestors.
2898  for ( int j=0; j < int(mpiParticlePos.size()); ++j)
2899  if ( event[iPosNow].isAncestor( mpiParticlePos[j]) )
2900  return false;
2901  // Beam remnants and hadronisation not part of hard process
2902  if ( event[iPosNow].statusAbs() > 60 )
2903  return false;
2904  }
2905  }
2906  }
2907 
2908  // Check if any ancestor contains the hard incoming partons as daughters.
2909  // Begin loop to trace upwards from the daughter.
2910  bool containsInitialParton = false;
2911  int iUp = iPos;
2912  for ( ; ; ) {
2913  // If out of range then failed to find match.
2914  if (iUp <= 0 || iUp > event.size()) break;
2915  // If positive match then done.
2916  if ( iUp == 3 || iUp == 4 ) {
2917  containsInitialParton = true;
2918  break;
2919  }
2920  if ( event[iUp].mother1() == 1
2921  && (event[iUp].daughter1() == 3 || event[iUp].daughter2() == 3) ) {
2922  containsInitialParton = true;
2923  break;
2924  }
2925  if ( event[iUp].mother1() == 2
2926  && (event[iUp].daughter1() == 4 || event[iUp].daughter2() == 4) ) {
2927  containsInitialParton = true;
2928  break;
2929  }
2930  // If unique mother then keep on moving up the chain.
2931  iUp = event[iUp].mother1();
2932  }
2933 
2934  if ( !containsInitialParton ) return false;
2935 
2936  // Done
2937  return true;
2938 
2939 }
2940 
2941 //--------------------------------------------------------------------------
2942 
2943 // Function to return the number of clustering steps for the current event
2944 
2945 int MergingHooks::getNumberOfClusteringSteps(const Event& event,
2946  bool resetJetMax ){
2947 
2948  // Count the number of final state partons
2949  int nFinalPartons = 0;
2950  for ( int i=0; i < event.size(); ++i)
2951  if ( event[i].isFinal()
2952  && isInHard( i, event)
2953  && (event[i].isQuark() || event[i].isGluon()) )
2954  nFinalPartons++;
2955 
2956  // Count the number of final state leptons
2957  int nFinalLeptons = 0;
2958  for( int i=0; i < event.size(); ++i)
2959  if ( event[i].isFinal() && isInHard( i, event) && event[i].isLepton())
2960  nFinalLeptons++;
2961 
2962  // Add neutralinos to number of leptons
2963  for( int i=0; i < event.size(); ++i)
2964  if ( event[i].isFinal() && isInHard( i, event)
2965  && event[i].idAbs() == 1000022)
2966  nFinalLeptons++;
2967 
2968  // Add sleptons to number of leptons
2969  for( int i=0; i < event.size(); ++i)
2970  if ( event[i].isFinal() && isInHard( i, event)
2971  && (event[i].idAbs() == 1000011
2972  || event[i].idAbs() == 2000011
2973  || event[i].idAbs() == 1000013
2974  || event[i].idAbs() == 2000013
2975  || event[i].idAbs() == 1000015
2976  || event[i].idAbs() == 2000015) )
2977  nFinalLeptons++;
2978 
2979  // Count the number of final state electroweak bosons
2980  int nFinalBosons = 0;
2981  for( int i=0; i < event.size(); ++i)
2982  if ( event[i].isFinal() && isInHard( i, event)
2983  && ( event[i].idAbs() == 22
2984  || event[i].idAbs() == 23
2985  || event[i].idAbs() == 24
2986  || event[i].idAbs() == 25 ) )
2987  nFinalBosons++;
2988 
2989  // Save sum of all final state particles
2990  int nFinal = nFinalPartons + nFinalLeptons
2991  + 2*(nFinalBosons - nHardOutBosons() );
2992 
2993  // Return the difference to the core process outgoing particles
2994  int nsteps = nFinal - nHardOutPartons() - nHardOutLeptons();
2995 
2996  // For inclusive handling, the number of reclustering steps
2997  // can be different within a single sample.
2998  if ( getProcessString().find("inc") != string::npos ) {
2999 
3000  // Final particle counters
3001  int njInc = 0, naInc = 0, nzInc = 0, nwInc =0;
3002  for (int i=0; i < event.size(); ++i){
3003  if ( event[i].isFinal() && event[i].colType() != 0 ) njInc++;
3004  if ( getProcessString().find("Ainc") != string::npos
3005  && event[i].isFinal() && event[i].idAbs() == 22 ) naInc++;
3006  if ( getProcessString().find("Zinc") != string::npos
3007  && event[i].isFinal() && event[i].idAbs() == 23 ) nzInc++;
3008  if ( getProcessString().find("Winc") != string::npos
3009  && event[i].isFinal() && event[i].idAbs() == 24 ) nwInc++;
3010  }
3011 
3012  // Set steps for QCD or QCD+QED events: Need at least two
3013  // massless particles at lowest multiplicity.
3014  if (nzInc == 0 && nwInc == 0 && njInc+naInc > 1) {
3015  nsteps = naInc + njInc - 2;
3016  if (resetJetMax) {
3017  hasJetMaxLocal = true;
3018  nJetMaxLocal = nJetMaxSave - 2;
3019  nRequestedSave = nsteps;
3020  }
3021  }
3022 
3023  // Set steps for events containing heavy bosons. Need at least one
3024  // massive particle at lowest multiplicity.
3025  if ( nzInc > 0 || nwInc > 0 ) {
3026  nsteps = njInc + naInc + nzInc + nwInc - 1;
3027  if (resetJetMax) {
3028  hasJetMaxLocal = true;
3029  nJetMaxLocal = nJetMaxSave - 1;
3030  nRequestedSave = nsteps;
3031  }
3032  }
3033 
3034  } // dynamical handling of steps
3035 
3036  // Return the difference to the core process outgoing particles
3037  return nsteps;
3038 
3039 }
3040 
3041 //--------------------------------------------------------------------------
3042 
3043 // Function to check if event contains an emission not present in the hard
3044 // process.
3045 
3046 bool MergingHooks::isFirstEmission(const Event& event ) {
3047 
3048  // If the beam remnant treatment or hadronisation has already started, do
3049  // no veto.
3050  for ( int i=0; i < event.size(); ++i)
3051  if ( event[i].statusAbs() > 60 ) return false;
3052 
3053  // Count particle types
3054  int nFinalQuarks = 0;
3055  int nFinalGluons = 0;
3056  int nFinalLeptons = 0;
3057  int nFinalBosons = 0;
3058  int nFinalPhotons = 0;
3059  int nFinalOther = 0;
3060  for( int i=0; i < event.size(); ++i) {
3061  if (event[i].isFinal() && isInHard(i, event) ){
3062  if ( event[i].isLepton())
3063  nFinalLeptons++;
3064  if ( event[i].id() == 23
3065  || event[i].idAbs() == 24
3066  || event[i].id() == 25)
3067  nFinalBosons++;
3068  if ( event[i].id() == 22)
3069  nFinalPhotons++;
3070  if ( event[i].isQuark())
3071  nFinalQuarks++;
3072  if ( event[i].isGluon())
3073  nFinalGluons++;
3074  if ( !event[i].isDiquark() )
3075  nFinalOther++;
3076  }
3077  }
3078 
3079  // Return highest value if the event does not contain any final state
3080  // coloured particles.
3081  if (nFinalQuarks + nFinalGluons == 0) return false;
3082 
3083  // Use MergingHooks functions to get information on the hard process.
3084  int nLeptons = nHardOutLeptons();
3085 
3086  // The state is already in the PS region if the number of leptons had been
3087  // increased by QED splittings.
3088  if (nFinalLeptons > nLeptons) return false;
3089 
3090  // If the mumber of photons if larger than in the hard process, QED
3091  // radiation has pushed the state into the PS region.
3092  int nPhotons = 0;
3093  for(int i =0; i< int(hardProcess->hardOutgoing1.size()); ++i)
3094  if (hardProcess->hardOutgoing1[i] == 22)
3095  nPhotons++;
3096  for(int i =0; i< int(hardProcess->hardOutgoing2.size()); ++i)
3097  if (hardProcess->hardOutgoing2[i] == 22)
3098  nPhotons++;
3099  if (nFinalPhotons > nPhotons) return false;
3100 
3101  // Done
3102  return true;
3103 }
3104 
3105 //--------------------------------------------------------------------------
3106 
3107 // Function to set the correct starting scales of the shower.
3108 // Note: 2 -> 2 QCD systems can be produced by MPI. Hence, there is an
3109 // overlap between MPI and "hard" 2 -> 2 QCD systems which needs to be
3110 // removed by no-MPI probabilities. This means that for any "hard" 2 -> 2 QCD
3111 // system, multiparton interactions should start at the maximal scale
3112 // of multiple interactions. The same argument holds for any "hard" process
3113 // that overlaps with MPI.
3114 
3115 bool MergingHooks::setShowerStartingScales( bool isTrial,
3116  bool doMergeFirstEmm, double& pTscaleIn, const Event& event,
3117  double& pTmaxFSRIn, bool& limitPTmaxFSRIn,
3118  double& pTmaxISRIn, bool& limitPTmaxISRIn,
3119  double& pTmaxMPIIn, bool& limitPTmaxMPIIn ) {
3120 
3121  // Local copies of power/wimpy shower booleans and scales.
3122  bool limitPTmaxFSR = limitPTmaxFSRIn;
3123  bool limitPTmaxISR = limitPTmaxISRIn;
3124  bool limitPTmaxMPI = limitPTmaxMPIIn;
3125  double pTmaxFSR = pTmaxFSRIn;
3126  double pTmaxISR = pTmaxISRIn;
3127  double pTmaxMPI = pTmaxMPIIn;
3128  double pTscale = pTscaleIn;
3129 
3130  // Merging of EW+QCD showers with matrix elements: Ensure that
3131  // 1. any event with more than one final state particle will be showered
3132  // from the reconstructed transverse momentum of the last emission,
3133  // even if the factorisation scale is low.
3134  // 2. the shower starting scale for events with no emission is given by
3135  // the (user-defined) choice.
3136  bool isInclusive = ( getProcessString().find("inc") != string::npos );
3137 
3138  // Check if the process only contains two outgoing partons. If so, then
3139  // this process could also have been produced by MPI. Thus, the MPI starting
3140  // scale would need to be set accordingly to correctly attach a
3141  // "no-MPI-probability" to multi-jet events. ("Hard" MPI are included
3142  // by not restricting MPI when showering the lowest-multiplicity sample.)
3143  double pT2to2 = 0;
3144  int nFinalPartons = 0, nInitialPartons = 0, nFinalOther = 0;
3145  for ( int i = 0; i < event.size(); ++i ) {
3146  if ( (event[i].mother1() == 1 || event[i].mother1() == 2 )
3147  && (event[i].idAbs() < 6 || event[i].id() == 21) )
3148  nInitialPartons++;
3149  if (event[i].isFinal() && (event[i].idAbs() < 6 || event[i].id() == 21)) {
3150  nFinalPartons++;
3151  pT2to2 = event[i].pT();
3152  } else if ( event[i].isFinal() ) nFinalOther++;
3153  }
3154  bool is2to2QCD = ( nFinalPartons == 2 && nInitialPartons == 2
3155  && nFinalOther == 0 );
3156  bool hasMPIoverlap = is2to2QCD;
3157  bool is2to1 = ( nFinalPartons == 0 );
3158 
3159  double scale = event.scale();
3160 
3161  // SET THE STARTING SCALES FOR TRIAL SHOWERS.
3162  if ( isTrial ) {
3163 
3164  // Reset shower and MPI scales.
3165  pTmaxISR = pTmaxFSR = pTmaxMPI = scale;
3166 
3167  // Reset to minimal scale for wimpy showers. Keep scales for EW+QCD
3168  // merging.
3169  if ( limitPTmaxISR && !isInclusive ) pTmaxISR = min(scale,muF());
3170  if ( limitPTmaxFSR && !isInclusive ) pTmaxFSR = min(scale,muF());
3171  if ( limitPTmaxMPI && !isInclusive ) pTmaxMPI = min(scale,muF());
3172 
3173  // For EW+QCD merging, apply wimpy shower only to 2->1 processes.
3174  if ( limitPTmaxISR && isInclusive && is2to1 ) pTmaxISR = min(scale,muF());
3175  if ( limitPTmaxFSR && isInclusive && is2to1 ) pTmaxFSR = min(scale,muF());
3176  if ( limitPTmaxMPI && isInclusive && is2to1 ) pTmaxMPI = min(scale,muF());
3177 
3178  // For pure QCD set the PS starting scales to the pT of the dijet system.
3179  if (is2to2QCD) {
3180  pTmaxFSR = pT2to2;
3181  pTmaxISR = pT2to2;
3182  }
3183 
3184  // If necessary, set the MPI starting scale to the collider energy.
3185  if ( hasMPIoverlap ) pTmaxMPI = infoPtr->eCM();
3186 
3187  // Reset phase space limitation flags
3188  if ( pTscale < infoPtr->eCM() ) {
3189  limitPTmaxISR = limitPTmaxFSR = limitPTmaxMPI = true;
3190  // If necessary, set the MPI starting scale to the collider energy.
3191  if ( hasMPIoverlap ) limitPTmaxMPI = false;
3192  }
3193 
3194  }
3195 
3196  // SET THE STARTING SCALES FOR REGULAR SHOWERS.
3197  if ( doMergeFirstEmm ) {
3198 
3199  // Remember if this is a "regular" shower off a reclustered event.
3200  bool doRecluster = doUMEPSSubt() || doNL3Subt() || doUNLOPSSubt()
3201  || doUNLOPSSubtNLO();
3202 
3203  // Reset shower and MPI scales.
3204  pTmaxISR = pTmaxFSR = pTmaxMPI = scale;
3205 
3206  // Reset to minimal scale for wimpy showers. Keep scales for EW+QCD
3207  // merging.
3208  if ( limitPTmaxISR && !isInclusive ) pTmaxISR = min(scale,muF());
3209  if ( limitPTmaxFSR && !isInclusive ) pTmaxFSR = min(scale,muF());
3210  if ( limitPTmaxMPI && !isInclusive ) pTmaxMPI = min(scale,muF());
3211 
3212  // For EW+QCD merging, apply wimpy shower only to 2->1 processes.
3213  if ( limitPTmaxISR && isInclusive && is2to1 ) pTmaxISR = min(scale,muF());
3214  if ( limitPTmaxFSR && isInclusive && is2to1 ) pTmaxFSR = min(scale,muF());
3215  if ( limitPTmaxMPI && isInclusive && is2to1 ) pTmaxMPI = min(scale,muF());
3216 
3217  // For pure QCD set the PS starting scales to the pT of the dijet system.
3218  if (is2to2QCD) {
3219  pTmaxFSR = pT2to2;
3220  pTmaxISR = pT2to2;
3221  }
3222 
3223  // If necessary, set the MPI starting scale to the collider energy.
3224  if ( hasMPIoverlap && !doRecluster ) {
3225  pTmaxMPI = infoPtr->eCM();
3226  limitPTmaxMPI = false;
3227  }
3228 
3229  // For reclustered events, no-MPI-probability between "pTmaxMPI" and
3230  // "scale" already included in the event weight.
3231  if ( doRecluster ) {
3232  pTmaxMPI = muMI();
3233  limitPTmaxMPI = true;
3234  }
3235  }
3236 
3237  // Reset power/wimpy shower switches iand scales if necessary.
3238  limitPTmaxFSRIn = limitPTmaxFSR;
3239  limitPTmaxISRIn = limitPTmaxISR;
3240  limitPTmaxMPIIn = limitPTmaxMPI;
3241  pTmaxFSRIn = pTmaxFSR;
3242  pTmaxISRIn = pTmaxISR;
3243  pTmaxMPIIn = pTmaxMPI;
3244  pTscaleIn = pTscale;
3245 
3246  // Done
3247  return true;
3248 
3249 }
3250 
3251 //--------------------------------------------------------------------------
3252 
3253 // Function to return the value of the merging scale function in the current
3254 // event.
3255 
3256 double MergingHooks::tmsNow( const Event& event ) {
3257 
3258  // Get merging scale in current event.
3259  double tnow = 0.;
3260  int unlopsType = mode("Merging:unlopsTMSdefinition");
3261  // Use KT/Durham merging scale definition.
3262  if ( doKTMerging() || doMGMerging() )
3263  tnow = kTms(event);
3264  // Use Lund PT merging scale definition.
3265  else if ( doPTLundMerging() )
3266  tnow = rhoms(event, false);
3267  // Use DeltaR_{ij}, pT_i, Q_{ij} combination merging scale definition.
3268  else if ( doCutBasedMerging() )
3269  tnow = cutbasedms(event);
3270  // Use NLO merging (Lund PT) merging scale definition.
3271  else if ( doNL3Merging() )
3272  tnow = rhoms(event, false);
3273  // Use NLO merging (Lund PT) merging scale definition.
3274  else if ( doUNLOPSMerging() )
3275  tnow = (unlopsType < 0) ? rhoms(event, false) : tmsDefinition(event);
3276  // Use UMEPS (Lund PT) merging scale definition.
3277  else if ( doUMEPSMerging() )
3278  tnow = rhoms(event, false);
3279  // Use user-defined merging scale.
3280  else
3281  tnow = tmsDefinition(event);
3282  // Return merging scale value. Done
3283  return tnow;
3284 }
3285 
3286 //--------------------------------------------------------------------------
3287 
3288 // Function to check if the properties of the input particle should be
3289 // checked against the cut-based merging scale defintion.
3290 
3291 bool MergingHooks::checkAgainstCut( const Particle& particle){
3292 
3293  // Do not check uncoloured particles.
3294  if (particle.colType() == 0) return false;
3295  // By default, use u-, d-, c-, s- and b-quarks.
3296  if ( particle.idAbs() != 21 && particle.idAbs() > nQuarksMergeSave )
3297  return false;
3298  // Done
3299  return true;
3300 
3301 }
3302 
3303 //--------------------------------------------------------------------------
3304 
3305 // Function to return the minimal kT in the event. If doKTMerging = true, this
3306 // function will be used as a merging scale definition.
3307 
3308 double MergingHooks::kTms(const Event& event) {
3309 
3310  // Only check first emission.
3311  if (!isFirstEmission(event)) return 0.;
3312 
3313  // Find all electroweak decayed bosons in the state.
3314  vector<int> ewResonancePos;
3315  ewResonancePos.clear();
3316  for (int i=0; i < event.size(); ++i)
3317  if ( abs(event[i].status()) == 22
3318  && ( event[i].idAbs() == 22
3319  || event[i].idAbs() == 23
3320  || event[i].idAbs() == 24
3321  || event[i].idAbs() == 25
3322  || event[i].idAbs() == 6 ) )
3323  ewResonancePos.push_back(i);
3324 
3325  // Declare final parton vectors
3326  vector <int> FinalPartPos;
3327  FinalPartPos.clear();
3328  // Search in Event record for final state partons.
3329  // Exclude decay products of ew resonance.
3330  for (int i=0; i < event.size(); ++i){
3331  if ( event[i].isFinal()
3332  && isInHard( i, event )
3333  && event[i].colType() != 0
3334  && checkAgainstCut(event[i]) ){
3335  bool isDecayProduct = false;
3336  for(int j=0; j < int(ewResonancePos.size()); ++j)
3337  if ( event[i].isAncestor( ewResonancePos[j]) )
3338  isDecayProduct = true;
3339  // Except for e+e- -> jets, do not check radiation in resonance decays.
3340  if ( !isDecayProduct
3341  || getProcessString().compare("e+e->jj") == 0
3342  || getProcessString().compare("e+e->(z>jj)") == 0 )
3343  FinalPartPos.push_back(i);
3344  }
3345  }
3346 
3347  // Find minimal Durham kT in event, using own function: Check
3348  // definition of separation
3349  int type = (event[3].colType() == 0
3350  && event[4].colType() == 0) ? -1 : ktTypeSave;
3351  // Find minimal kT
3352  double ktmin = event[0].e();
3353  for(int i=0; i < int(FinalPartPos.size()); ++i){
3354  double kt12 = ktmin;
3355  // Compute separation to the beam axis for hadronic collisions
3356  if (type == 1 || type == 2) {
3357  double temp = event[FinalPartPos[i]].pT();
3358  kt12 = min(kt12, temp);
3359  }
3360  // Compute separation to other final state jets
3361  for(int j=i+1; j < int(FinalPartPos.size()); ++j) {
3362  double temp = kTdurham( event[FinalPartPos[i]], event[FinalPartPos[j]],
3363  type, DparameterSave);
3364  kt12 = min(kt12, temp);
3365  }
3366  // Keep the minimal Durham separation
3367  ktmin = min(ktmin,kt12);
3368  }
3369 
3370  // Return minimal Durham kT
3371  return ktmin;
3372 
3373 }
3374 
3375 //--------------------------------------------------------------------------
3376 
3377 // Function to compute durham y separation from Particle input.
3378 
3379 double MergingHooks::kTdurham(const Particle& RadAfterBranch,
3380  const Particle& EmtAfterBranch, int Type, double D ){
3381 
3382  // Declare return variable
3383  double ktdur;
3384  // Save 4-momenta of final state particles
3385  Vec4 jet1 = RadAfterBranch.p();
3386  Vec4 jet2 = EmtAfterBranch.p();
3387 
3388  if ( Type == -1) {
3389  // Get angle between jets for e+e- collisions, make sure that
3390  // -1 <= cos(theta) <= 1
3391  double costh;
3392  if (jet1.pAbs()*jet2.pAbs() <=0.) costh = 1.;
3393  else {
3394  costh = costheta(jet1,jet2);
3395  }
3396  // Calculate kt durham separation between jets for e+e- collisions
3397  ktdur = 2.0*min( pow(jet1.e(),2) , (pow(jet2.e(),2)) )*(1.0 - costh);
3398  } else if ( Type == 1 ){
3399  // Get delta_y for hadronic collisions:
3400  // Get mT of first jet
3401  double mT1sq = jet1.m2Calc() + jet1.pT2();
3402  double mT1 = 0.;
3403  if (mT1sq < 0) mT1 = - sqrt(-mT1sq);
3404  else mT1 = sqrt(mT1sq);
3405  // Get mT of second jet
3406  double mT2sq = jet2.m2Calc() + jet2.pT2();
3407  double mT2 = 0.;
3408  if (mT2sq < 0) mT2 = - sqrt(-mT2sq);
3409  else mT2 = sqrt(mT2sq);
3410  // Get rapidity of first jet
3411  double y1 = log( ( jet1.e() + abs(jet1.pz()) ) / mT1 );
3412  if (jet1.pz() < 0) y1 *= -1.;
3413  // Get rapidity of second jet
3414  double y2 = log( ( jet2.e() + abs(jet2.pz()) ) / mT2 );
3415  if (jet2.pz() < 0) y2 *= -1.;
3416  // Get delta_phi for hadronic collisions
3417  double pt1 = sqrt( pow(jet1.px(),2) + pow(jet1.py(),2) );
3418  double pt2 = sqrt( pow(jet2.px(),2) + pow(jet2.py(),2) );
3419  double cosdPhi = ( jet1.px()*jet2.px() + jet1.py()*jet2.py() ) / (pt1*pt2);
3420  double dPhi = acos( cosdPhi );
3421  // Calculate kT durham like fastjet,
3422  // but with rapidity instead of pseudo-rapidity
3423  ktdur = min( pow(pt1,2),pow(pt2,2) )
3424  * ( pow(y1-y2,2) + pow(dPhi,2) ) / pow(D,2);
3425  } else if ( Type == 2 ){
3426 
3427  // Get mT of first jet
3428  double mT1sq = jet1.m2Calc() + jet1.pT2();
3429  double mT1 = 0.;
3430  if (mT1sq < 0) mT1 = - sqrt(-mT1sq);
3431  else mT1 = sqrt(mT1sq);
3432  // Get mT of second jet
3433  double mT2sq = jet2.m2Calc() + jet2.pT2();
3434  double mT2 = 0.;
3435  if (mT2sq < 0) mT2 = - sqrt(-mT2sq);
3436  else mT2 = sqrt(mT2sq);
3437  // Get pseudo-rapidity of first jet
3438  double eta1 = log( ( sqrt(jet1.px()*jet1.px() + jet1.py()*jet1.py()
3439  + jet1.pz()*jet1.pz()) + abs(jet1.pz()) ) / mT1);
3440  if (jet1.pz() < 0) eta1 *= -1.;
3441  // Get pseudo-rapidity of second jet
3442  double eta2 = log( ( sqrt(jet2.px()*jet2.px() + jet2.py()*jet2.py()
3443  + jet2.pz()*jet2.pz()) + abs(jet2.pz()) ) / mT2);
3444  if (jet2.pz() < 0) eta2 *= -1.;
3445 
3446  // Get delta_phi and cos(Delta_phi) for hadronic collisions
3447  double pt1 = sqrt( pow(jet1.px(),2) + pow(jet1.py(),2) );
3448  double pt2 = sqrt( pow(jet2.px(),2) + pow(jet2.py(),2) );
3449  double cosdPhi = ( jet1.px()*jet2.px() + jet1.py()*jet2.py() ) / (pt1*pt2);
3450  double dPhi = acos( cosdPhi );
3451  // Calculate kT durham like fastjet
3452  ktdur = min( pow(pt1,2),pow(pt2,2) )
3453  * ( pow(eta1-eta2,2) + pow(dPhi,2) ) / pow(D,2);
3454  } else if ( Type == 3 ){
3455  // Get cosh(Delta_eta) for hadronic collisions
3456  double eta1 = 0.5*log( (jet1.e() + jet1.pz()) / (jet1.e() - jet1.pz()) );
3457  double eta2 = 0.5*log( (jet2.e() + jet2.pz()) / (jet2.e() - jet2.pz()) );
3458  double coshdEta = cosh( eta1 - eta2 );
3459  // Get delta_phi and cos(Delta_phi) for hadronic collisions
3460  double pt1 = sqrt( pow(jet1.px(),2) + pow(jet1.py(),2) );
3461  double pt2 = sqrt( pow(jet2.px(),2) + pow(jet2.py(),2) );
3462  double cosdPhi = ( jet1.px()*jet2.px() + jet1.py()*jet2.py() ) / (pt1*pt2);
3463  // Calculate kT durham separation "SHERPA-like"
3464  ktdur = 2.0*min( pow(pt1,2),pow(pt2,2) )
3465  * ( coshdEta - cosdPhi ) / pow(D,2);
3466  } else {
3467  ktdur = 0.0;
3468  }
3469  // Return kT
3470  return sqrt(ktdur);
3471 }
3472 
3473 //--------------------------------------------------------------------------
3474 
3475 // Find the minimal Lund pT between coloured partons in the input
3476 // event. If doPTLundMerging = true, this function will be used as a merging
3477 // scale definition.
3478 
3479 double MergingHooks::rhoms( const Event& event, bool withColour){
3480 
3481  // Only check first emission.
3482  if (!isFirstEmission(event)) return 0.;
3483 
3484  if ( useShowerPlugin() ) {
3485  double ptret=event[0].e();
3486  for(int i=0; i < event.size(); ++i) {
3487  for(int j=0; j < event.size(); ++j) {
3488  if (i==j) continue;
3489  double temp = rhoPythia( event, i, j, 0, 0 );
3490  if (temp > 0.) ptret = min(ptret, temp);
3491  }
3492  }
3493  return ptret;
3494  }
3495 
3496  // Find all electroweak decayed bosons in the state.
3497  vector<int> ewResonancePos;
3498  ewResonancePos.clear();
3499  for (int i=0; i < event.size(); ++i)
3500  if ( abs(event[i].status()) == 22
3501  && ( event[i].idAbs() == 22
3502  || event[i].idAbs() == 23
3503  || event[i].idAbs() == 24
3504  || event[i].idAbs() == 25
3505  || event[i].idAbs() == 6 ) )
3506  ewResonancePos.push_back(i);
3507 
3508  // Declare final parton vectors
3509  vector <int> FinalPartPos;
3510  FinalPartPos.clear();
3511  // Search inEvent record for final state partons.
3512  // Exclude decay products of ew resonance.
3513  for (int i=0; i < event.size(); ++i){
3514 
3515  if ( event[i].isFinal()
3516  && isInHard( i, event )
3517  && event[i].colType() != 0
3518  && checkAgainstCut(event[i]) ){
3519  bool isDecayProduct = false;
3520  for(int j=0; j < int(ewResonancePos.size()); ++j)
3521  if ( event[i].isAncestor( ewResonancePos[j]) )
3522  isDecayProduct = true;
3523  // Except for e+e- -> jets, do not check radiation in resonance decays.
3524  if ( !isDecayProduct
3525  || getProcessString().compare("e+e->jj") == 0
3526  || getProcessString().compare("e+e->(z>jj)") == 0 )
3527  FinalPartPos.push_back(i);
3528  }
3529 
3530  // Include photons into the tms definition for "weak+QCD merging".
3531  if ( getProcessString().find("Ainc") != string::npos
3532  && event[i].isFinal() && event[i].idAbs() == 22 )
3533  FinalPartPos.push_back(i);
3534  // Include Z-bosons into the tms definition for "weak+QCD merging".
3535  if ( getProcessString().find("Zinc") != string::npos
3536  && event[i].isFinal() && event[i].idAbs() == 23 )
3537  FinalPartPos.push_back(i);
3538  // Include W-bosons into the tms definition for "weak+QCD merging".
3539  if ( getProcessString().find("Winc") != string::npos
3540  && event[i].isFinal() && event[i].idAbs() == 24 )
3541  FinalPartPos.push_back(i);
3542  }
3543 
3544  // Get index of first incoming
3545  int in1 = 0;
3546  for (int i=0; i < event.size(); ++i)
3547  if (abs(event[i].status()) == 41 ){
3548  in1 = i;
3549  break;
3550  }
3551 
3552  // Get index of second incoming
3553  int in2 = 0;
3554  for (int i=0; i < event.size(); ++i)
3555  if (abs(event[i].status()) == 42 ){
3556  in2 = i;
3557  break;
3558  }
3559 
3560  // If no incoming of the cascade are found, try incoming
3561  if (in1 == 0 || in2 == 0){
3562  // Find current incoming partons
3563  for(int i=3; i < int(event.size()); ++i){
3564  if ( !isInHard( i, event ) ) continue;
3565  if (event[i].mother1() == 1) in1 = i;
3566  if (event[i].mother1() == 2) in2 = i;
3567  }
3568  }
3569 
3570  int nInitialPartons = 0, nFinalOther = 0;
3571  for ( int i = 0; i < event.size(); ++i ) {
3572  if ( (event[i].mother1() == 1 || event[i].mother1() == 2 )
3573  && (event[i].idAbs() < 6 || event[i].id() == 21) )
3574  nInitialPartons++;
3575  if (event[i].isFinal() && event[i].idAbs() >= 6 && event[i].id() != 21)
3576  nFinalOther++;
3577  }
3578  bool is2to2QCD = ( int(FinalPartPos.size()) == 2 && nInitialPartons == 2
3579  && nFinalOther == 0 );
3580 
3581  // For pure QCD set the cut to the pT of the dijet system.
3582  if (is2to2QCD) {
3583  double pt12 = min(event[FinalPartPos[0]].pT(),
3584  event[FinalPartPos[1]].pT());
3585  return pt12;
3586  }
3587 
3588  // Find minimal pythia pt in event
3589  double ptmin = event[0].e();
3590  for(int i=0; i < int(FinalPartPos.size()); ++i){
3591 
3592  double pt12 = ptmin;
3593  // Compute pythia ISR separation i-jet and first incoming
3594  if (event[in1].colType() != 0) {
3595  double temp = rhoPythia( event, in1, FinalPartPos[i], in2, -1 );
3596  pt12 = min(pt12, temp);
3597  }
3598 
3599  // Compute pythia ISR separation i-jet and second incoming
3600  if ( event[in2].colType() != 0) {
3601  double temp = rhoPythia( event, in2, FinalPartPos[i], in1, -1 );
3602  pt12 = min(pt12, temp);
3603  }
3604 
3605  if (withColour) {
3606  // Compute pythia FSR separation between two jets,
3607  // with knowledge of colour connections
3608  for(int j=0; j < int(FinalPartPos.size()); ++j) {
3609 
3610  // Find recoiler in event
3611  if ( i!=j ){
3612  bool isHard = false;
3613  int radAcl = event[FinalPartPos[i]].acol();
3614  int radCol = event[FinalPartPos[i]].col();
3615  int emtAcl = event[FinalPartPos[j]].acol();
3616  int emtCol = event[FinalPartPos[j]].col();
3617  int iRec = -1;
3618  // Check in final state
3619  if (radAcl > 0 && radAcl != emtCol)
3620  iRec = findColour(radAcl, FinalPartPos[i], FinalPartPos[j],
3621  event,1, isHard);
3622  if (iRec <= 0 && radCol > 0 && radCol != emtAcl)
3623  iRec = findColour(radCol, FinalPartPos[i], FinalPartPos[j],
3624  event,1, isHard);
3625  if (iRec <= 0 && emtAcl > 0 && emtAcl != radCol)
3626  iRec = findColour(emtAcl, FinalPartPos[i], FinalPartPos[j],
3627  event,1, isHard);
3628  if (iRec <= 0 && emtCol > 0 && emtCol != radAcl)
3629  iRec = findColour(emtCol, FinalPartPos[i], FinalPartPos[j],
3630  event,1, isHard);
3631 
3632  // Check in initial state
3633  if (iRec <= 0 && radAcl > 0 && radAcl != emtCol)
3634  iRec = findColour(radAcl, FinalPartPos[i], FinalPartPos[j],
3635  event,2, isHard);
3636  if (iRec <= 0 && radCol > 0 && radCol != emtAcl)
3637  iRec = findColour(radCol, FinalPartPos[i], FinalPartPos[j],
3638  event,2, isHard);
3639  if (iRec <= 0 && emtAcl > 0 && emtAcl != radCol)
3640  iRec = findColour(emtAcl, FinalPartPos[i], FinalPartPos[j],
3641  event,2, isHard);
3642  if (iRec <= 0 && emtCol > 0 && emtCol != radAcl)
3643  iRec = findColour(emtCol, FinalPartPos[i], FinalPartPos[j],
3644  event,2, isHard);
3645 
3646  if (iRec > 0) {
3647  double temp = rhoPythia( event, FinalPartPos[i], FinalPartPos[j],
3648  iRec, 1 );
3649  pt12 = min(pt12, temp);
3650  }
3651  }
3652  }
3653 
3654  } else {
3655  // Compute pythia FSR separation between two jets,
3656  // without any knowledge of colour connections
3657  for(int j=0; j < int(FinalPartPos.size()); ++j) {
3658  for(int k=0; k < int(FinalPartPos.size()); ++k) {
3659  // Allow any parton as recoiler
3660  if ( (i != j) && (i != k) && (j != k) ){
3661 
3662  double temp = 0.;
3663  // Only check splittings allowed by flavour, e.g.
3664  // only q -> qg and g -> qqbar
3665  temp = rhoPythia( event, FinalPartPos[i], FinalPartPos[j],
3666  FinalPartPos[k], 1 );
3667  pt12 = min(pt12, temp);
3668  temp = rhoPythia( event, FinalPartPos[j], FinalPartPos[i],
3669  FinalPartPos[k], 1 );
3670  pt12 = min(pt12, temp);
3671  }
3672  }
3673  }
3674 
3675  // Compute pythia FSR separation between two jets, with initial recoiler
3676  // without any knowledge of colour connections
3677  if ( event[in1].colType() != 0 && event[in2].colType() != 0) {
3678  for(int j=0; j < int(FinalPartPos.size()); ++j) {
3679  // Allow both initial partons as recoiler
3680  if ( i != j ){
3681  double temp = pt12;
3682 
3683  // Check with first initial as recoiler
3684  if (event[in1].colType() != 0)
3685  temp = rhoPythia( event, FinalPartPos[i],FinalPartPos[j],in1, 1);
3686  pt12 = min(pt12, temp);
3687  // Check with second initial as recoiler
3688  if (event[in2].colType() != 0)
3689  temp = rhoPythia( event, FinalPartPos[i],FinalPartPos[j],in2, 1);
3690  pt12 = min(pt12, temp);
3691  }
3692  }
3693  }
3694 
3695  }
3696  // Reset minimal y separation
3697  ptmin = min(ptmin,pt12);
3698  }
3699 
3700  return ptmin;
3701 
3702 }
3703 
3704 //--------------------------------------------------------------------------
3705 
3706 // Function to compute "pythia pT separation" from Particle input, as a helper
3707 // for rhoms(...).
3708 
3709 double MergingHooks::rhoPythia(const Event& event, int rad, int emt, int rec,
3710  int ShowerType){
3711 
3712  Particle RadAfterBranch = event[rad];
3713  Particle EmtAfterBranch = event[emt];
3714  Particle RecAfterBranch = event[rec];
3715 
3716  // Use external shower for merging.
3717  // Ask showers for evolution variable.
3718  if ( useShowerPlugin() ) {
3719  map<string,double> stateVars;
3720  double ptret = event[0].m();
3721  bool isFSR = showers->timesPtr->allowedSplitting(event, rad, emt);
3722  bool isISR = showers->spacePtr->allowedSplitting(event, rad, emt);
3723  if (isFSR) {
3724  vector<string> names
3725  = showers->timesPtr->getSplittingName(event, rad, emt, 0);
3726  for (int iName=0; iName < int(names.size()); ++iName) {
3727  vector<int> recsNow
3728  = showers->timesPtr->getRecoilers(event, rad, emt, names[iName]);
3729  for ( int i = 0; i < int(recsNow.size()); ++i ) {
3730  stateVars = showers->timesPtr->getStateVariables(event, rad, emt,
3731  recsNow[i], names[iName]);
3732  double pttemp = ptret;
3733  if (stateVars.size() > 0 && stateVars.find("t") != stateVars.end())
3734  pttemp = sqrt(stateVars["t"]);
3735  ptret = min(ptret,pttemp);
3736  }
3737  }
3738  }
3739 
3740  if (isISR) {
3741  vector<string> names
3742  = showers->spacePtr->getSplittingName(event, rad, emt, 0);
3743  for (int iName=0; iName < int(names.size()); ++iName) {
3744  vector<int> recsNow
3745  = showers->spacePtr->getRecoilers(event, rad, emt, names[iName]);
3746  for ( int i = 0; i < int(recsNow.size()); ++i ) {
3747  stateVars = showers->spacePtr->getStateVariables(event, rad, emt,
3748  recsNow[i], names[iName]);
3749  double pttemp = ptret;
3750  if (stateVars.size() > 0 && stateVars.find("t") != stateVars.end())
3751  pttemp = sqrt(stateVars["t"]);
3752  ptret = min(ptret,pttemp);
3753  }
3754  }
3755  }
3756 
3757  return ptret;
3758  }
3759 
3760  // Note: If massive particles are involved, this definition slightly differs
3761  // from History:pTLund(), as we need to ensure consistency with
3762  // aMC@NLO_MadGraph5 (!). In the latter, no masses are available at the
3763  // point where the merging scale value is calculated, and thus masses are set
3764  // by hand there, and consequently here.
3765 
3766  bool allowed = true;
3767 
3768  // Save type: 1 = FSR pT definition, else ISR definition
3769  int Type = ShowerType;
3770 
3771  // Set masses (as used in MG5).
3772  double m0u = 0.0, m0d = 0.0, m0c = 1.5, m0s = 0.0, m0t = 172.5,
3773  m0b = 4.7, m0w = 80.4, m0z = 91.188, m0x = 1000.0;
3774  if (false) cout << m0u*m0d*m0c*m0s*m0t*m0b*m0w*m0z*m0x;
3775 
3776  // Calculate virtuality of splitting
3777  int sign = (Type==1) ? 1 : -1;
3778  Vec4 Q(RadAfterBranch.p() + sign*EmtAfterBranch.p());
3779  double Qsq = sign * Q.m2Calc();
3780 
3781  // Splitting not possible for negative virtuality.
3782  if ( Qsq < 0.0 ) allowed = false;
3783 
3784  // Construct 2->3 variables for FSR
3785  Vec4 radAft(RadAfterBranch.p());
3786  Vec4 recAft(RecAfterBranch.p());
3787  Vec4 emtAft(EmtAfterBranch.p());
3788 
3789  // Try to reconstruct flavour of radiator before emission.
3790  int idRadBef = 0;
3791  int flavEmt = EmtAfterBranch.id();
3792  int flavRad = RadAfterBranch.id();
3793  // gluon radiation: idBef = idAft
3794  if (abs(flavEmt) == 21 || abs(flavEmt) == 22 ) idRadBef=flavRad;
3795  // final state gluon splitting: idBef = 21
3796  if (Type == 1 && flavEmt == -flavRad) idRadBef=21;
3797  // final state quark -> gluon conversion
3798  if (Type == 1 && abs(flavEmt) < 10 && flavRad == 21) idRadBef=flavEmt;
3799  // initial state gluon splitting: idBef = -idEmt
3800  if (Type == -1 && abs(flavEmt) < 10 && flavRad == 21) idRadBef=-flavEmt;
3801  // initial state gluon -> quark conversion
3802  if (Type == -1 && abs(flavEmt) < 10 && flavRad == flavEmt) idRadBef=21;
3803  // W-boson radiation
3804  if (flavEmt == 24) idRadBef = RadAfterBranch.id()+1;
3805  if (flavEmt == -24) idRadBef = RadAfterBranch.id()-1;
3806 
3807  // ee flavour sensitive cut
3808  if (false) {
3809  infoPtr->errorMsg("Warning in MergingHooks::rhoPythia: Using flavour "
3810  " sensitive pythia pT merging cut.");
3811  if (Type == 1 && abs(flavEmt) < 7 && flavEmt != -flavRad) allowed = false;
3812  }
3813  // Store masses both after and prior to emission.
3814  double m2RadAft = radAft.m2Calc();
3815  double m2EmtAft = emtAft.m2Calc();
3816  double m2RadBef = 0.;
3817  if ( RadAfterBranch.idAbs() != 21 && RadAfterBranch.idAbs() != 22
3818  && EmtAfterBranch.idAbs() != 24
3819  && RadAfterBranch.idAbs() != EmtAfterBranch.idAbs() )
3820  m2RadBef = m2RadAft;
3821  else if (EmtAfterBranch.idAbs() == 24) {
3822  if (idRadBef != 0) {
3823  if( abs(idRadBef) == 4 ) m2RadBef = pow(m0c,2);
3824  if( abs(idRadBef) == 5 ) m2RadBef = pow(m0b,2);
3825  if( abs(idRadBef) == 6 ) m2RadBef = pow(m0t,2);
3826  if( abs(idRadBef) == 9000001 ) m2RadBef = pow(m0x,2);
3827  }
3828  } else if (!RadAfterBranch.isFinal()) {
3829  if (RadAfterBranch.idAbs() == 21 && EmtAfterBranch.idAbs() != 21)
3830  m2RadBef = m2EmtAft;
3831  }
3832 
3833  double m2Final = (radAft + recAft + emtAft).m2Calc();
3834  // Final state splitting not possible for negative "dipole mass".
3835  if (m2Final < 0.0) allowed = false;
3836 
3837  // Rescaling of recoiler for FSR with initial state recoiler.
3838  if ( !RecAfterBranch.isFinal() && RadAfterBranch.isFinal() ){
3839  double mar2 = m2Final - 2. * Qsq + 2. * m2RadBef;
3840  double rescale = (1. - (Qsq - m2RadBef)/(mar2 - m2RadBef))
3841  /(1. + (Qsq - m2RadBef)/(mar2 - m2RadBef));
3842  // Final-initial splitting not possible for negative rescaling.
3843  if (rescale < 0.0) allowed = false;
3844  recAft *= rescale;
3845  }
3846 
3847  Vec4 sum = radAft + recAft + emtAft;
3848  double m2Dip = sum.m2Calc();
3849  double x1 = 2. * (sum * radAft) / m2Dip;
3850  double x2 = 2. * (sum * recAft) / m2Dip;
3851 
3852  // Final state splitting not possible for ill-defined 3-body-variables.
3853  if ( RadAfterBranch.isFinal()
3854  && ( x1 < 0.0 || x1 > 1.0 || x2 < 0.0 || x2 > 1.0)) allowed = false;
3855 
3856  // Construct momenta of dipole before/after splitting for ISR
3857  Vec4 qBR(RadAfterBranch.p() - EmtAfterBranch.p() + RecAfterBranch.p());
3858  Vec4 qAR(RadAfterBranch.p() + RecAfterBranch.p());
3859 
3860  // Prepare for more complicated z definition for massive splittings.
3861  double lambda13 = sqrt( pow2(Qsq - m2RadAft - m2EmtAft )
3862  - 4. * m2RadAft*m2EmtAft );
3863  double k1 = ( Qsq - lambda13 + (m2EmtAft - m2RadAft ) ) / ( 2. * Qsq );
3864  double k3 = ( Qsq - lambda13 - (m2EmtAft - m2RadAft ) ) / ( 2. * Qsq );
3865 
3866  // Calculate z of splitting, different for FSR and ISR
3867  double z = (Type==1) ? 1./ ( 1- k1 -k3) * ( x1 / (2.-x2) - k3)
3868  : (qBR.m2Calc())/( qAR.m2Calc());
3869 
3870  // Splitting not possible for ill-defined energy sharing.
3871  if ( z < 0.0 || z > 1.0) allowed = false;
3872 
3873  // Separation of splitting, different for FSR and ISR
3874  double pTpyth = (Type==1) ? z*(1.-z) : (1.-z);
3875 
3876  // pT^2 = separation*virtuality
3877  if (Type == 1) pTpyth *= (Qsq - m2RadBef);
3878  else pTpyth *= Qsq;
3879 
3880  // Check for threshold in ISR, only relevant for c and b.
3881  // Use pT2 = (1 - z) * (Qsq + m^2).
3882  if ( Type != 1) {
3883  if ( ( RadAfterBranch.idAbs() == 4 || EmtAfterBranch.idAbs() == 4)
3884  && RadAfterBranch.idAbs() != EmtAfterBranch.idAbs() ) {
3885  if (pTpyth < 2 * pow(m0c,2)) pTpyth = (Qsq + pow(m0c,2)) * (1. - z);
3886  } else if ( (RadAfterBranch.idAbs() == 5 || EmtAfterBranch.idAbs() == 5)
3887  && RadAfterBranch.idAbs() != EmtAfterBranch.idAbs() ) {
3888  if (pTpyth < 2 * pow(m0b,2))
3889  pTpyth = (Qsq + pow(m0b,2) ) * (1. - z);
3890  }
3891  }
3892 
3893  // Kinematically impossible splittings should not be included in the
3894  // pT definition!
3895  if (!allowed) pTpyth = 1e15;
3896 
3897  if ( pTpyth < 0. ) pTpyth = 0.;
3898 
3899  // Return pT
3900  return sqrt(pTpyth);
3901 }
3902 
3903 //--------------------------------------------------------------------------
3904 
3905 // Function to find a colour (anticolour) index in the input event.
3906 // Helper for rhoms
3907 // IN int col : Colour tag to be investigated
3908 // int iExclude1 : Identifier of first particle to be excluded
3909 // from search
3910 // int iExclude2 : Identifier of second particle to be excluded
3911 // from search
3912 // Event event : event to be searched for colour tag
3913 // int type : Tag to define if col should be counted as
3914 // colour (type = 1) [->find anti-colour index
3915 // contracted with col]
3916 // anticolour (type = 2) [->find colour index
3917 // contracted with col]
3918 // OUT int : Position of particle in event record
3919 // contraced with col [0 if col is free tag]
3920 
3921 int MergingHooks::findColour(int col, int iExclude1, int iExclude2,
3922  const Event& event, int type, bool isHardIn){
3923 
3924  bool isHard = isHardIn;
3925  int index = 0;
3926 
3927  if (isHard){
3928  // Search event record for matching colour & anticolour
3929  for(int n = 0; n < event.size(); ++n) {
3930  if ( n != iExclude1 && n != iExclude2
3931  && event[n].colType() != 0
3932  &&( event[n].status() > 0 // Check outgoing
3933  || event[n].status() == -21) ) { // Check incoming
3934  if ( event[n].acol() == col ) {
3935  index = -n;
3936  break;
3937  }
3938  if ( event[n].col() == col ){
3939  index = n;
3940  break;
3941  }
3942  }
3943  }
3944  } else {
3945 
3946  // Search event record for matching colour & anticolour
3947  for(int n = 0; n < event.size(); ++n) {
3948  if ( n != iExclude1 && n != iExclude2
3949  && event[n].colType() != 0
3950  &&( event[n].status() == 43 // Check outgoing from ISR
3951  || event[n].status() == 51 // Check outgoing from FSR
3952  || event[n].status() == 52 // Check outgoing from FSR
3953  || event[n].status() == -41 // first initial
3954  || event[n].status() == -42) ) { // second initial
3955  if ( event[n].acol() == col ) {
3956  index = -n;
3957  break;
3958  }
3959  if ( event[n].col() == col ){
3960  index = n;
3961  break;
3962  }
3963  }
3964  }
3965  }
3966  // if no matching colour / anticolour has been found, return false
3967  if ( type == 1 && index < 0) return abs(index);
3968  if ( type == 2 && index > 0) return abs(index);
3969 
3970  return 0;
3971 }
3972 
3973 //--------------------------------------------------------------------------
3974 
3975 // Find the if the event passes the Delta R_{ij}, pT_{i} and Q_{ij} cuts on
3976 // the matrix element, as needed for cut-based merging scale definition.
3977 
3978 double MergingHooks::cutbasedms( const Event& event ){
3979 
3980  // Only check first emission.
3981  if (!isFirstEmission(event)) return -1.;
3982 
3983  // Save allowed final state particles
3984  vector<int> partons;
3985  for( int i=0; i < event.size(); ++i) {
3986  if ( event[i].isFinal()
3987  && isInHard( i, event )
3988  && checkAgainstCut(event[i]) )
3989  partons.push_back(i);
3990  }
3991 
3992  // Declare overall veto
3993  bool doVeto = false;
3994  // Declare vetoes
3995  bool vetoPT = false;
3996  bool vetoRjj = false;
3997  bool vetoMjj = false;
3998  // Declare cuts used in matrix element
3999  double pTjmin = pTiMS();
4000  double mjjmin = QijMS();
4001  double rjjmin = dRijMS();
4002 
4003  // Declare minimum values
4004  double minPT = event[0].e();
4005  double minRJJ = 10.;
4006  double minMJJ = event[0].e();
4007 
4008  // Check matrix element cuts
4009  for( int i=0; i < int(partons.size()); ++i){
4010  // Save pT value
4011  minPT = min(minPT,event[partons[i]].pT());
4012 
4013  // Check two-parton cuts
4014  for( int j=0; j < int(partons.size()); ++j){
4015  if (i!=j){
4016 
4017  // Save delta R value
4018  minRJJ = min(minRJJ, deltaRij( event[partons[i]].p(),
4019  event[partons[j]].p()) );
4020  // Save delta R value
4021  minMJJ = min(minMJJ, ( event[partons[i]].p()
4022  +event[partons[j]].p() ).mCalc() );
4023 
4024  }
4025  }
4026  // Done with cut evaluation
4027  }
4028 
4029  // Check if all partons are in the matrix element region
4030  if (minPT > pTjmin) vetoPT = true;
4031  if (minRJJ > rjjmin) vetoRjj = true;
4032  if (minMJJ > mjjmin) vetoMjj = true;
4033 
4034  // In the matrix element calculation, we have rejected the events if any of
4035  // the cuts had not been fulfilled,
4036  // i.e. we are in the matrix element domain if all cuts are fulfilled.
4037  // We veto any emission in the ME region.
4038  // Disregard the two-parton cuts if only one parton in the final state
4039  if (int(partons.size() == 1))
4040  doVeto = vetoPT;
4041  else
4042  // Veto if the combination of cuts would be in the ME region
4043  doVeto = vetoPT && vetoRjj && vetoMjj;
4044 
4045  // If event is above merging scale, veto
4046  if (doVeto) return 1.;
4047 
4048  // Else, do nothing
4049  return -1.;
4050 
4051 }
4052 
4053 //--------------------------------------------------------------------------
4054 
4055 // Function to compute Delta R separation from 4-vector input.
4056 
4057 double MergingHooks::deltaRij(Vec4 jet1, Vec4 jet2){
4058 
4059  // Declare return variable
4060  double deltaR = 0.;
4061  // Get delta_eta and cosh(Delta_eta) for hadronic collisions
4062  double eta1 = 0.5*log( (jet1.e() + jet1.pz()) / (jet1.e() - jet1.pz()) );
4063  double eta2 = 0.5*log( (jet2.e() + jet2.pz()) / (jet2.e() - jet2.pz()) );
4064  // Get delta_phi and cos(Delta_phi) for hadronic collisions
4065  double pt1 = sqrt( pow(jet1.px(),2) + pow(jet1.py(),2) );
4066  double pt2 = sqrt( pow(jet2.px(),2) + pow(jet2.py(),2) );
4067  double cosdPhi = ( jet1.px()*jet2.px() + jet1.py()*jet2.py() ) / (pt1*pt2);
4068  double dPhi = acos( cosdPhi );
4069  // Calculate kT durham like fastjet
4070  deltaR = sqrt(pow(eta1-eta2,2) + pow(dPhi,2));
4071  // Return kT
4072  return deltaR;
4073 }
4074 
4075 //--------------------------------------------------------------------------
4076 
4077 // Function to print individual merging weight components, for debugging.
4078 void MergingHooks::printIndividualWeights() {
4079  cout << "Individual merging weight components, muR scales 1, ";
4080  for (double muRfac: muRVarFactors) cout << muRfac << " ";
4081  cout << endl;
4082  cout << "wt: ";
4083  for (double wt: individualWeights.wtSave) cout << wt << " ";
4084  cout << endl;
4085  cout << "pdfWeight: ";
4086  for (double wt: individualWeights.pdfWeightSave) cout << wt << " ";
4087  cout << endl;
4088  cout << "mpiWeight: ";
4089  for (double wt: individualWeights.mpiWeightSave) cout << wt << " ";
4090  cout << endl;
4091  cout << "asWeight: ";
4092  for (double wt: individualWeights.asWeightSave) cout << wt << " ";
4093  cout << endl;
4094  cout << "aemWeight: ";
4095  for (double wt: individualWeights.aemWeightSave) cout << wt << " ";
4096  cout << endl;
4097  cout << "bornAsVarFac: ";
4098  for (double wt: individualWeights.bornAsVarFac) cout << wt << " ";
4099  cout << endl;
4100 
4101 }
4102 
4103 //==========================================================================
4104 
4105 } // end namespace Pythia8
Definition: AgUStep.h:26