10 #include "Pythia8/MergingHooks.h"
11 #include "Pythia8/PartonLevel.h"
27 void HardProcess::initOnProcess(
string process, ParticleData* particleData) {
28 state.init(
"(hard process)", particleData);
29 translateProcessString(process);
36 void HardProcess::initOnLHEF(
string LHEfile, ParticleData* particleData) {
37 state.init(
"(hard process)", particleData);
38 translateLHEFString(LHEfile);
52 void HardProcess::translateLHEFString(
string LHEpath){
56 infile.open( (
char*)( LHEpath +
"_0.lhe").c_str());
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){
69 getline(infile,lineGenerator);
78 int inParticleNumbers[] = {
80 -11,11,-12,12,-13,13,-14,14,-15,15,-16,16,
84 -1,1,-2,2,-3,3,-4,4,-5,5,-6,6};
86 string inParticleNamesSH[] = {
88 "-11",
"11",
"-12",
"12",
"-13",
"13",
"-14",
"14",
"-15",
"15",
"-16",
"16",
90 "-93",
"93",
"-90",
"90",
"-91",
"91",
92 "-1",
"1",
"-2",
"2",
"-3",
"3",
"-4",
"4",
"-5",
"5",
"-6",
"6"};
93 string inParticleNamesMG[] = {
95 "e+",
"e-",
"ve~",
"ve",
"mu+",
"mu-",
"vm~",
"vm",
"ta+",
"ta-",
"vt~",
"vt",
97 "p~",
"p",
"l+",
"l-",
"vl~",
"vl",
99 "d~",
"d",
"u~",
"u",
"s~",
"s",
"c~",
"c",
"b~",
"b",
"t~",
"t"};
102 int interParticleNumbers[] = {
104 22,23,-24,24,25,2400,
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};
114 string interParticleNamesMG[] = {
116 "a",
"z",
"w-",
"w+",
"h",
"W",
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"};
126 int outParticleNumbers[] = {
128 -11,11,-12,12,-13,13,-14,14,-15,15,-16,16,
130 2212,2212,0,0,0,0,1200,1100,5000,
132 -1,1,-2,2,-3,3,-4,4,-5,5,-6,6,
134 22,23,-24,24,25,2400,
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};
142 string outParticleNamesMG[] = {
144 "e+",
"e-",
"ve~",
"ve",
"mu+",
"mu-",
"vm~",
"vm",
"ta+",
"ta-",
"vt~",
"vt",
146 "j~",
"j",
"l+",
"l-",
"vl~",
"vl",
"NEUTRINOS",
"LEPTONS",
"BQUARKS",
148 "d~",
"d",
"u~",
"u",
"s~",
"s",
"c~",
"c",
"b~",
"b",
"t~",
"t",
150 "a",
"z",
"w-",
"w+",
"h",
"W",
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"};
157 string outParticleNamesSH[] = {
159 "-11",
"11",
"-12",
"12",
"-13",
"13",
"-14",
"14",
"-15",
"15",
"-16",
"16",
161 "-93",
"93",
"-90",
"90",
"-91",
"91",
"0",
"0",
"0",
163 "-1",
"1",
"-2",
"2",
"-3",
"3",
"-4",
"4",
"-5",
"5",
"-6",
"6",
165 "22",
"23",
"-24",
"24",
"25",
"0",
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"};
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
189 if (meGenType == -2){
192 infile.open( (
char*)( LHEpath +
"_1.lhe").c_str());
194 while(lineTMS.find(
"NJetFinder ", 0) == string::npos){
196 getline(infile,lineTMS);
199 lineTMS = lineTMS.substr(0,lineTMS.find(
" 0.0 ",0));
200 lineTMS = lineTMS.substr(lineTMS.find(
" ", 0)+3,lineTMS.size());
202 while(lineTMS.find(
" ", 0) != string::npos)
203 lineTMS.erase(lineTMS.begin()+lineTMS.find(
" ",0));
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());
211 infile.open( (
char*)( LHEpath +
"_0.lhe").c_str());
213 while(line.find(
"Process", 0) == string::npos){
215 getline(infile,line);
218 line = line.substr(line.find(
" ",0),line.size());
221 vector <string> pieces;
222 pieces.push_back( line.substr(0,line.find(
"->", 0)) );
224 int end = (line.find(
"{", 0) != string::npos) ? line.find(
"{", 0)-2
226 pieces.push_back( line.substr(line.find(
"->", 0)+2, end) );
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());
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());
254 }
else if (meGenType == -1 || meGenType == -3 || meGenType == -4){
259 if (meGenType == -1) {
261 infile.open( (
char*)( LHEpath +
"_1.lhe").c_str());
262 while(lineTMS.find(
"ktdurham", 0) == string::npos){
264 getline(infile,lineTMS);
266 lineTMS = lineTMS.substr(0,lineTMS.find(
"=",0));
273 while(lineTMS.find(
" ", 0) != string::npos)
274 lineTMS.erase(lineTMS.begin()+lineTMS.find(
" ",0));
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());
282 infile.open( (
char*)( LHEpath +
"_0.lhe").c_str());
284 while(line.find(
"@1", 0) == string::npos){
286 getline(infile,line);
289 line = line.substr(0,line.find(
"@",0));
293 for(
int n = line.find(
"(", 0); n != int(string::npos);
294 n = line.find(
"(", n)) {
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());
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()) );
314 if (pieces.empty() ){
316 for(
int n = line.find(
">", 0); n != int(string::npos);
317 n = line.find(
">", n)) {
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());
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()) );
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());
349 for(
int i =1; i < int(pieces.size()); ++i){
351 int k = pieces[i].find(
">", 0);
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];
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());
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());
389 for(
int l=0; l < int(outgo.size()); ++l)
390 if ( (abs(outgo[l]) > 20 && abs(outgo[l]) <= 25) || outgo[l] == 2400)
393 int nZeros = (outgo.size() - nBosons)/2;
394 for(
int l=0; l < nZeros; ++l)
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]);
408 cout <<
"Reading of tms and hard process information from LHEF currently"
409 <<
" only automated for MadEvent- or SHERPA-produced LHEF" << endl;
411 cout <<
"Use default process pp -> e+ve + jets? (0:no / 1:yes): ";
417 double tempDouble = 0.0;
418 cout <<
"Please specify merging scale (kT Durham, in GeV): ";
422 cout <<
"Please specify first incoming particle ";
423 cout <<
"(p+/p- = 2212, e- = 11, e+ = -11): ";
425 incom.push_back(tempInt);
428 cout <<
"Please specify second incoming particle ";
429 cout <<
"(p+/p- = 2212, e- = 11, e+ = -11): ";
431 incom.push_back(tempInt);
434 cout <<
"Please specify intermediate particle, if any ";
435 cout <<
"(0 for none, else PDG code): ";
437 inter.push_back(tempInt);
441 cout <<
"Please specify outgoing particle ";
442 cout <<
"(jet=2212, else PDG code, exit with 99): ";
444 if (tempInt != 99) outgo.push_back(tempInt);
445 }
while(tempInt != 99);
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);
453 outgo.push_back(-11);
461 for(
int i=0; i < int(inter.size()); ++i)
462 hardIntermediate.push_back(inter[i]);
465 if (incom.size() != 2)
466 cout <<
"Only two incoming particles allowed" << endl;
468 hardIncoming1 = incom[0];
469 hardIncoming2 = incom[1];
474 for(
int i=0; i < int(outgo.size()); ++i)
475 if ( (abs(outgo[i]) > 20 && abs(outgo[i]) <= 25) || outgo[i] == 2400)
479 for(
int i=0; i < int(outgo.size()); ++i)
480 if ( outgo[i] == 5000)
484 for(
int i=0; i < int(outgo.size()); ++i)
485 if ( outgo[i] == 2212)
489 for(
int i=0; i < int(outgo.size()); ++i)
490 if ( outgo[i] == 1100)
494 for(
int i=0; i < int(outgo.size()); ++i)
495 if ( outgo[i] == 1200)
497 int nContainers = nLeptons + nNeutrinos + nJets + nBQuarks;
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;
507 for(
int i=0; i < int(outgo.size()); ++i)
514 && outgo[i] != 1000022)
515 hardOutgoing2.push_back( outgo[i]);
516 else if (outgo[i] < 0)
517 hardOutgoing1.push_back( outgo[i]);
520 for(
int i=0; i < int(outgo.size()); ++i)
521 if ( outgo[i] == 2400)
522 hardOutgoing2.push_back( outgo[i]);
527 for(
int i=0; i < int(outgo.size()); ++i)
528 if ( (outgo[i] == 2212
531 || outgo[i] == 1000022)
533 hardOutgoing2.push_back( outgo[i]);
535 }
else if ( (outgo[i] == 2212
538 || outgo[i] == 1000022)
540 hardOutgoing1.push_back( outgo[i]);
554 void HardProcess::translateProcessString(
string process){
561 int inParticleNumbers[] = {
563 -11,11,-12,12,-13,13,-14,14,-15,15,-16,16,
567 -1,1,-2,2,-3,3,-4,4,-5,5,-6,6};
568 string inParticleNamesMG[] = {
570 "e+",
"e-",
"ve~",
"ve",
"mu+",
"mu-",
"vm~",
"vm",
"ta+",
"ta-",
"vt~",
"vt",
572 "p~",
"p",
"l+",
"l-",
"vl~",
"vl",
574 "d~",
"d",
"u~",
"u",
"s~",
"s",
"c~",
"c",
"b~",
"b",
"t~",
"t"};
577 int interParticleNumbers[] = {
579 22,23,-24,24,25,2400,
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,
589 string interParticleNamesMG[] = {
591 "a",
"z",
"w-",
"w+",
"h",
"W",
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",
601 int outParticleNumbers[] = {
603 -11,11,-12,12,-13,13,-14,14,-15,15,-16,16,
605 2212,2212,0,0,0,0,1200,1100,5000,
607 10000022,10000023,10000024,10002212,
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,
613 -1,1,-2,2,-3,3,-4,4,-5,5,-6,6,
615 22,23,-24,24,25,2400,
619 string outParticleNamesMG[] = {
621 "e+",
"e-",
"ve~",
"ve",
"mu+",
"mu-",
"vm~",
"vm",
"ta+",
"ta-",
"vt~",
"vt",
623 "j~",
"j",
"l+",
"l-",
"vl~",
"vl",
"NEUTRINOS",
"LEPTONS",
"BQUARKS",
625 "Ainc",
"Zinc",
"Winc",
"Jinc",
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",
630 "d~",
"d",
"u~",
"u",
"s~",
"s",
"c~",
"c",
"b~",
"b",
"t~",
"t",
632 "a",
"z",
"w-",
"w+",
"h",
"W",
642 string fullProc = process;
645 while(fullProc.find(
" ", 0) != string::npos)
646 fullProc.erase(fullProc.begin()+fullProc.find(
" ",0));
650 int nUserParticles = 0;
651 for(
int n = fullProc.find(
"{", 0); n != int(string::npos);
652 n = fullProc.find(
"{", n)) {
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());
666 if (nUserParticles > 0)
667 userParticleStrings.push_back(
668 fullProc.substr( 0, fullProc.find(
"}",0) ) );
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));
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() ) );
694 if (nUserParticles > 0)
695 userParticleStrings.push_back(
697 fullProc.find(
"}",0)+1, fullProc.size() ) );
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));
714 if (
int(userParticleStrings.size()) > 1 )
715 residualProc = userParticleStrings.front() + userParticleStrings.back();
717 residualProc = fullProc;
720 while(residualProc.find(
",", 0) != string::npos)
721 residualProc.erase(residualProc.begin()+residualProc.find(
",",0));
725 for(
int n = residualProc.find(
"(", 0); n != int(string::npos);
726 n = residualProc.find(
"(", n)) {
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());
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()) );
748 if (pieces.empty() ){
750 for(
int n = residualProc.find(
">", 0); n != int(string::npos);
751 n = residualProc.find(
">", n)) {
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());
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()) );
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());
784 for(
int i =1; i < int(pieces.size()); ++i){
786 int k = pieces[i].find(
">", 0);
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];
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());
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());
824 for(
int l=0; l < int(outgo.size()); ++l)
825 if ( (abs(outgo[l]) > 20 && abs(outgo[l]) <= 25) || outgo[l] == 2400)
828 int nZeros = (outgo.size() - nBosons)/2;
829 for(
int l=0; l < nZeros; ++l)
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]);
843 for(
int i=0; i < int(inter.size()); ++i)
844 hardIntermediate.push_back(inter[i]);
847 if (incom.size() != 2)
848 cout <<
"Only two incoming particles allowed" << endl;
850 hardIncoming1 = incom[0];
851 hardIncoming2 = incom[1];
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);
861 }
else if (userParticleNumbers[i] < 0) {
862 hardOutgoing1.push_back( userParticleNumbers[i]);
864 hardIntermediate.push_back(0);
868 for(
int i=0; i < int(outgo.size()); ++i)
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]);
882 for(
int i=0; i < int(outgo.size()); ++i)
883 if ( outgo[i] == 2400)
884 hardOutgoing2.push_back( outgo[i]);
889 for(
int i=0; i < int(outgo.size()); ++i)
890 if ( (outgo[i] == 2212
893 || outgo[i] == 1000022
894 || outgo[i] > 10000000)
896 hardOutgoing2.push_back( outgo[i]);
898 }
else if ( (outgo[i] == 2212
901 || outgo[i] == 1000022
902 || outgo[i] > 10000000)
904 hardOutgoing1.push_back( outgo[i]);
916 bool HardProcess::allowCandidates(
int iPos, vector<int> Pos1,
917 vector<int> Pos2,
const Event& event){
922 int type = (
event[iPos].col() > 0) ? 1 : (event[iPos].acol() > 0) ? -1 : 0;
924 if (type == 0)
return true;
927 int col =
event[iPos].col();
929 for(
int i=0; i < int(event.size()); ++i)
931 && (( event[i].isFinal() && event[i].acol() == col)
932 ||(
event[i].status() == -21 &&
event[i].col() == col) ))
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);
945 if (event[iPartner].status() == -21){
946 for(
int i=0; i < int(partners.size()); ++i)
947 if ( partners[i] == iPartner)
952 int col =
event[iPos].acol();
954 for(
int i=0; i < int(event.size()); ++i)
956 && (( event[i].isFinal() && event[i].col() == col)
957 ||(!
event[i].isFinal() &&
event[i].acol() == col) ))
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);
970 if (event[iPartner].status() == -21){
971 for(
int i=0; i < int(partners.size()); ++i){
972 if ( partners[i] == iPartner)
987 void HardProcess::storeCandidates(
const Event& event,
string process){
994 vector<int> intermediates;
995 for(
int i =0; i < int(hardIntermediate.size());++i)
996 intermediates.push_back( hardIntermediate[i]);
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]);
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);
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;
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;
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;
1048 vector<int> iPosChecked;
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;
1064 if (hasOnlyContainers){
1066 PosOutgoing1.resize(0);
1067 PosOutgoing2.resize(0);
1071 for(
int i=0; i < int(event.size()); ++i){
1074 if ( !event[i].isFinal() )
continue;
1078 for(
int k=0; k < int(iPosChecked.size()); ++k){
1079 if (i == iPosChecked[k])
1084 for(
int j=0; j < int(outgoing2.size()); ++j){
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);
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);
1105 if ( outgoing2[j] == 5000 && event[i].idAbs() == 5 ){
1106 PosOutgoing2.push_back(i);
1107 iPosChecked.push_back(i);
1114 for(
int k=0; k < int(iPosChecked.size()); ++k){
1115 if (i == iPosChecked[k])
1120 for(
int j=0; j < int(outgoing1.size()); ++j){
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);
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);
1141 if ( outgoing1[j] == 5000 && event[i].idAbs() == 5 ){
1142 PosOutgoing1.push_back(i);
1143 iPosChecked.push_back(i);
1156 for(
int i=0; i < int(intermediates.size()); ++i){
1159 if (intermediates[i] == 0)
continue;
1162 bool matchesFinalBoson =
false;
1163 for(
int j =0; j< int(outgoing1.size()); ++j){
1164 if ( intermediates[i] == outgoing1[j] )
1165 matchesFinalBoson =
true;
1167 for(
int j =0; j< int(outgoing2.size()); ++j){
1168 if ( intermediates[i] == outgoing2[j] )
1169 matchesFinalBoson =
true;
1171 if (!matchesFinalBoson)
continue;
1174 for(
int j=0; j < int(event.size()); ++j) {
1178 for(
int m=0; m < int(iPosChecked.size()); ++m)
1179 if (j == iPosChecked[m]) skip =
true;
1184 if ( (event[j].
id() == intermediates[i])
1185 ||(event[j].idAbs() == 24 && intermediates[i] == 2400) ) {
1187 PosIntermediate[i] = j;
1188 intermediates[i] = 0;
1190 bool indexSet =
false;
1192 for(
int k=0; k < int(outgoing1.size()); ++k) {
1193 if (event[j].
id() == outgoing1[k] && !indexSet){
1194 PosOutgoing1[k] = j;
1200 for(
int k=0; k < int(outgoing2.size()); ++k) {
1201 if (event[j].
id() == outgoing2[k] && !indexSet){
1202 PosOutgoing2[k] = j;
1209 for(
int k=0; k < int(outgoing2.size()); ++k) {
1210 if (event[j].idAbs() == 24 && outgoing2[k] == 2400 && !indexSet ){
1211 PosOutgoing2[k] = j;
1217 iPosChecked.push_back(j);
1224 for(
int i=0; i < int(intermediates.size()); ++i){
1227 if (intermediates[i] == 0)
continue;
1230 for(
int j=0; j < int(event.size()); ++j) {
1233 if ( (event[j].
id() == intermediates[i])
1234 ||(event[j].idAbs() == 24 && intermediates[i] == 2400) ) {
1236 PosIntermediate[i] = j;
1237 intermediates[i] = 0;
1239 int iPos1 =
event[j].daughter1();
1240 int iPos2 =
event[j].daughter2();
1244 for(
int k=iPos1; k <= iPos2; ++k){
1245 int id =
event[k].id();
1249 for(
int m=0; m < int(iPosChecked.size()); ++m)
1250 if (k == iPosChecked[m]) skip =
true;
1254 for(
int l=0; l < int(outgoing2.size()); ++l)
1255 if ( outgoing2[l] != 99 ){
1257 if (
id == outgoing2[l]
1259 || (
id > 0 && abs(
id) < 10 && outgoing2[l] == 2212) ){
1261 PosOutgoing2[l] = k;
1264 iPosChecked.push_back(k);
1271 for(
int l=0; l < int(outgoing1.size()); ++l)
1272 if ( outgoing1[l] != 99 ){
1274 if (
id == outgoing1[l]
1276 || (
id < 0 && abs(
id) < 10 && outgoing1[l] == 2212) ){
1278 PosOutgoing1[l] = k;
1281 iPosChecked.push_back(k);
1294 for(
int i=0; i < int(outgoing1.size()); ++i)
1295 if (outgoing1[i] != 99)
1297 for(
int i=0; i < int(outgoing2.size()); ++i)
1298 if (outgoing2[i] != 99)
1306 for(
int i=0; i < int(event.size()); ++i){
1308 if ( !event[i].isFinal() ||
event[i].colType() != 0)
1312 for(
int k=0; k < int(iPosChecked.size()); ++k){
1313 if (i == iPosChecked[k])
1319 for(
int j=0; j < int(outgoing2.size()); ++j){
1322 if ( outgoing2[j] == 99
1323 || outgoing2[j] == 2212
1324 || abs(outgoing2[j]) < 10)
1328 if ( event[i].
id() == outgoing2[j] ){
1329 PosOutgoing2[j] = i;
1331 iPosChecked.push_back(i);
1336 for(
int j=0; j < int(outgoing1.size()); ++j){
1339 if ( outgoing1[j] == 99
1340 || outgoing1[j] == 2212
1341 || abs(outgoing1[j]) < 10)
1345 if (event[i].
id() == outgoing1[j] ){
1346 PosOutgoing1[j] = i;
1348 iPosChecked.push_back(i);
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)
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));
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)
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));
1385 if ( out1copy.size() > out2copy.size()){
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) ){
1396 for(
int k=0; k < int(iPosChecked.size()); ++k)
1397 if (it->second == iPosChecked[k]) skip =
true;
1399 for(
int k=0; k < int(indexWasSet.size()); ++k)
1400 if (it->first == indexWasSet[k]) skip =
true;
1404 PosOutgoing2[it->first] = it->second;
1406 outgoing2[it->first] = 99;
1407 iPosChecked.push_back(it->second);
1408 indexWasSet.push_back(it->first);
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) ){
1419 for(
int k=0; k < int(iPosChecked.size()); ++k)
1420 if (it->second == iPosChecked[k]) skip =
true;
1422 for(
int k=0; k < int(indexWasSet.size()); ++k)
1423 if (it->first == indexWasSet[k]) skip =
true;
1427 PosOutgoing1[it->first] = it->second;
1429 outgoing1[it->first] = 99;
1430 iPosChecked.push_back(it->second);
1431 indexWasSet.push_back(it->first);
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) ){
1446 for(
int k=0; k < int(iPosChecked.size()); ++k)
1447 if (it->second == iPosChecked[k]) skip =
true;
1449 for(
int k=0; k < int(indexWasSet.size()); ++k)
1450 if (it->first == indexWasSet[k]) skip =
true;
1454 PosOutgoing1[it->first] = it->second;
1456 outgoing1[it->first] = 99;
1457 iPosChecked.push_back(it->second);
1458 indexWasSet.push_back(it->first);
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) ){
1469 for(
int k=0; k < int(iPosChecked.size()); ++k)
1470 if (it->second == iPosChecked[k]) skip =
true;
1472 for(
int k=0; k < int(indexWasSet.size()); ++k)
1473 if (it->first == indexWasSet[k]) skip =
true;
1477 PosOutgoing2[it->first] = it->second;
1479 outgoing2[it->first] = 99;
1480 iPosChecked.push_back(it->second);
1481 indexWasSet.push_back(it->first);
1491 for(
int i=0; i < int(event.size()); ++i){
1494 if ( !event[i].isFinal() ||
event[i].colType() == 0)
1499 for(
int k=0; k < int(iPosChecked.size()); ++k){
1500 if (i == iPosChecked[k])
1506 for(
int j=0; j < int(outgoing2.size()); ++j){
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 )
1519 if (event[i].
id() == outgoing2[j]){
1521 PosOutgoing2[j] = i;
1524 iPosChecked.push_back(i);
1530 for(
int j=0; j < int(outgoing1.size()); ++j){
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 )
1541 if (event[i].
id() == outgoing1[j]){
1543 PosOutgoing1[j] = i;
1546 iPosChecked.push_back(i);
1560 bool HardProcess::matchesAnyOutgoing(
int iPos,
const Event& event){
1563 bool matchQN1 =
false;
1565 bool matchQN2 =
false;
1569 bool matchHP =
false;
1572 for(
int i=0; i < int(PosOutgoing1.size()); ++i)
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() )
1585 for(
int i=0; i < int(PosOutgoing2.size()); ++i)
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() )
1599 if ( event[iPos].mother1()*
event[iPos].mother2() == 12
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 )
1608 || ( event[iPos].status() == 23
1609 &&
event[
event[iPos].mother1()].mother1()
1610 *
event[
event[iPos].mother1()].mother2() == 12 )
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 ) )
1621 return ( matchHP && (matchQN1 || matchQN2) );
1632 bool HardProcess::findOtherCandidates(
int iPos,
const Event& event,
1636 bool foundCopy =
false;
1639 int id =
event[iPos].id();
1640 int col =
event[iPos].col();
1641 int acl =
event[iPos].acol();
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)
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;
1662 vector<int> candidates1;
1663 vector<int> candidates2;
1665 for(
int i=0; i < int(PosOutgoing1.size()); ++i)
1667 if (
id == state[PosOutgoing1[i]].
id()
1668 && col == state[PosOutgoing1[i]].col()
1669 && acl == state[PosOutgoing1[i]].acol() )
1670 candidates1.push_back(i);
1672 for(
int i=0; i < int(PosOutgoing2.size()); ++i)
1674 if (
id == state[PosOutgoing2[i]].
id()
1675 && col == state[PosOutgoing2[i]].col()
1676 && acl == state[PosOutgoing2[i]].acol() )
1677 candidates2.push_back(i);
1680 if ( candidates1.size() + candidates2.size() != 1 )
return false;
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)
1688 if ( state[i].isFinal()
1689 && i != PosOutgoing1[j]
1690 && state[PosOutgoing1[j]].id() ==
id
1691 && state[i].id() == id ){
1693 vector<int> newPosOutgoing1;
1694 for(
int k=0; k < int(PosOutgoing1.size()); ++k)
1695 if ( k != j ) newPosOutgoing1.push_back( PosOutgoing1[k] );
1697 if ( allowCandidates(i, newPosOutgoing1, PosOutgoing2, state) )
1698 further1.insert(make_pair(j, i));
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)
1707 if ( state[i].isFinal()
1708 && i != PosOutgoing2[j]
1709 && state[PosOutgoing2[j]].id() ==
id
1710 && state[i].id() == id ){
1712 vector<int> newPosOutgoing2;
1713 for(
int k=0; k < int(PosOutgoing2.size()); ++k)
1714 if ( k != j ) newPosOutgoing2.push_back( PosOutgoing2[k] );
1716 if ( allowCandidates(i, PosOutgoing1, newPosOutgoing2, state) )
1717 further2.insert(make_pair(j, i));
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++);
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++);
1739 foundCopy = (doReplace)
1740 ? exchangeCandidates(candidates1, candidates2, further1, further2)
1741 : (further1.size() + further2.size() > 0);
1752 bool HardProcess::exchangeCandidates( vector<int> candidates1,
1753 vector<int> candidates2, unordered_map<int,int> further1,
1754 unordered_map<int,int> further2) {
1756 int nOld1 = candidates1.size();
1757 int nOld2 = candidates2.size();
1758 int nNew1 = further1.size();
1759 int nNew2 = further2.size();
1760 bool exchanged =
false;
1762 if ( nOld1 == 1 && nOld2 == 0 && nNew1 == 1 && nNew2 == 0){
1763 PosOutgoing1[further1.begin()->first] = further1.begin()->second;
1765 }
else if ( nOld1 == 0 && nOld2 == 1 && nNew1 == 0 && nNew2 == 1){
1766 PosOutgoing2[further2.begin()->first] = further2.begin()->second;
1769 }
else if ( nNew1 > 1 && nNew2 == 0 ) {
1770 PosOutgoing1[further1.begin()->first] = further1.begin()->second;
1772 }
else if ( nNew1 == 0 && nNew2 > 0 ) {
1773 PosOutgoing2[further2.begin()->first] = further2.begin()->second;
1787 int HardProcess::nQuarksOut(){
1789 for(
int i =0; i< int(hardOutgoing1.size()); ++i){
1790 if (hardOutgoing1[i] == 2212 || abs(hardOutgoing1[i]) < 10) nFin++;
1792 for(
int i =0; i< int(hardOutgoing2.size()); ++i){
1793 if (hardOutgoing2[i] == 2212 || abs(hardOutgoing2[i]) < 10) nFin++;
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)
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)
1815 int HardProcess::nLeptonOut(){
1817 for(
int i =0; i< int(hardOutgoing1.size()); ++i){
1818 if (abs(hardOutgoing1[i]) > 10 && abs(hardOutgoing1[i]) < 20) nFin++;
1820 if (abs(hardOutgoing1[i]) == 1000022) nFin++;
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)
1827 for(
int i =0; i< int(hardOutgoing2.size()); ++i){
1828 if (abs(hardOutgoing2[i]) > 10 && abs(hardOutgoing2[i]) < 20) nFin++;
1830 if (abs(hardOutgoing2[i]) == 1000022) nFin++;
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)
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 )
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 )
1862 int HardProcess::nBosonsOut(){
1864 for(
int i =0; i< int(hardOutgoing1.size()); ++i){
1865 if (abs(hardOutgoing1[i]) > 20 && abs(hardOutgoing1[i]) <= 25) nFin++;
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++;
1879 int HardProcess::nQuarksIn(){
1881 if (hardIncoming1 == 2212 || abs(hardIncoming1) < 10) nIn++;
1882 if (hardIncoming2 == 2212 || abs(hardIncoming2) < 10) nIn++;
1891 int HardProcess::nLeptonIn(){
1893 if (abs(hardIncoming1) > 10 && abs(hardIncoming1) < 20) nIn++;
1894 if (abs(hardIncoming2) > 10 && abs(hardIncoming2) < 20) nIn++;
1903 int HardProcess::hasResInCurrent(){
1904 for(
int i =0; i< int(PosIntermediate.size()); ++i)
1905 if (PosIntermediate[i] == 0)
return 0;
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] )
1912 for(
int j =0; j< int(PosOutgoing2.size()); ++j){
1913 if ( PosIntermediate[i] == PosOutgoing2[j] )
1925 int HardProcess::nResInCurrent(){
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;
1934 for(
int j =0; j< int(PosOutgoing2.size()); ++j){
1935 if ( PosIntermediate[i] == PosOutgoing2[j] )
1936 matchesFinalBoson =
true;
1938 if (!matchesFinalBoson) nRes++;
1949 bool HardProcess::hasResInProc(){
1951 for(
int i =0; i< int(hardIntermediate.size()); ++i)
1952 if (hardIntermediate[i] == 0)
return false;
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] )
1959 for(
int j =0; j< int(hardOutgoing2.size()); ++j){
1960 if ( hardIntermediate[i] == hardOutgoing2[j] )
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] <<
" ";
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] <<
" ";
2008 void HardProcess::clear() {
2011 hardIncoming1 = hardIncoming2 = 0;
2013 hardOutgoing1.resize(0);
2014 hardOutgoing2.resize(0);
2016 hardIntermediate.resize(0);
2022 PosOutgoing1.resize(0);
2023 PosOutgoing2.resize(0);
2025 PosIntermediate.resize(0);
2039 MergingHooks::~MergingHooks() {
if (useOwnHardProcess)
delete hardProcess; }
2045 void MergingHooks::init(){
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,
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,
2064 int alphaEMFSRorder = mode(
"TimeShower:alphaEMorder");
2065 AlphaEM_FSRSave.init(alphaEMFSRorder, settingsPtr);
2066 int alphaEMISRorder = mode(
"SpaceShower:alphaEMorder");
2067 AlphaEM_ISRSave.init(alphaEMISRorder, settingsPtr);
2070 doUserMergingSave = flag(
"Merging:doUserMerging");
2072 doMGMergingSave = flag(
"Merging:doMGMerging");
2074 doKTMergingSave = flag(
"Merging:doKTMerging");
2076 doPTLundMergingSave = flag(
"Merging:doPTLundMerging");
2078 doCutBasedMergingSave = flag(
"Merging:doCutBasedMerging");
2080 ktTypeSave = mode(
"Merging:ktType");
2083 doNL3TreeSave = flag(
"Merging:doNL3Tree");
2084 doNL3LoopSave = flag(
"Merging:doNL3Loop");
2085 doNL3SubtSave = flag(
"Merging:doNL3Subt");
2086 bool doNL3 = doNL3TreeSave || doNL3LoopSave || doNL3SubtSave;
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;
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;
2105 doEstimateXSection = flag(
"Merging:doXSectionEstimate");
2109 includeWGTinXSECSave = flag(
"Merging:includeWeightInXsection");
2112 applyVeto = flag(
"Merging:applyVeto");
2115 processSave = word(
"Merging:Process");
2116 processNow = processSave;
2117 bool doGuess = (processNow.find(
"guess") != string::npos);
2121 if (processNow.find(
"guess") != string::npos) processNow =
"pp>e+e-";
2124 hardProcess =
new HardProcess();
2125 useOwnHardProcess =
true;
2129 hardProcess->clear();
2132 inputEvent.init(
"(hard process)", particleDataPtr);
2133 doRemoveDecayProducts = doGuess || flag(
"Merging:mayRemoveDecayProducts");
2134 settingsPtr->flag(
"Merging:mayRemoveDecayProducts",doRemoveDecayProducts);
2137 if ( doMGMergingSave )
2138 hardProcess->initOnLHEF(lheInputFile, particleDataPtr);
2140 hardProcess->initOnProcess(processNow, particleDataPtr);
2143 while(processSave.find(
" ", 0) != string::npos)
2144 processSave.erase(processSave.begin()+processSave.find(
" ",0));
2147 includeMassiveSave = flag(
"Merging:includeMassive");
2148 enforceStrongOrderingSave = flag(
"Merging:enforceStrongOrdering");
2149 scaleSeparationFactorSave = parm(
"Merging:scaleSeparationFactor");
2150 orderInRapiditySave = flag(
"Merging:orderInRapidity");
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");
2160 unorderedScalePrescipSave = mode(
"Merging:unorderedScalePrescrip");
2161 unorderedASscalePrescipSave = mode(
"Merging:unorderedASscalePrescrip");
2162 unorderedPDFscalePrescipSave = mode(
"Merging:unorderedPDFscalePrescrip");
2163 incompleteScalePrescipSave = mode(
"Merging:incompleteScalePrescrip");
2166 allowColourShufflingSave = flag(
"Merging:allowColourShuffling");
2170 resetHardQRenSave = flag(
"Merging:usePythiaQRenHard");
2171 resetHardQFacSave = flag(
"Merging:usePythiaQFacHard");
2174 pickBySumPTSave = flag(
"Merging:pickBySumPT");
2175 herwigAcollFSRSave = parm(
"Merging:aCollFSR");
2176 herwigAcollISRSave = parm(
"Merging:aCollISR");
2179 pT0ISRSave = parm(
"SpaceShower:pT0Ref");
2180 pTcutSave = parm(
"SpaceShower:pTmin");
2181 pTcutSave = max(pTcutSave,pT0ISRSave);
2184 muRVarFactors = infoPtr->weightContainerPtr->weightsMerging.
2186 doVariations = muRVarFactors.size() ?
true :
false;
2187 nWgts = 1+muRVarFactors.size();
2190 weightCKKWLSave = vector<double>( nWgts, 1. );
2191 weightFIRSTSave = vector<double>( nWgts, 0. );
2196 vector<string> weightNames = {
"MUR1.0_MUF1.0"};
2197 for (
double fact: muRVarFactors) {
2198 weightNames.push_back(
"MUR"+std::to_string(fact)+
"_MUF1.0");
2200 infoPtr->weightContainerPtr->weightsMerging.bookVectors(
2201 weightCKKWLSave,weightFIRSTSave,weightNames);
2205 tmsListSave.resize(0);
2207 kFactor0jSave = parm(
"Merging:kFactor0j");
2208 kFactor1jSave = parm(
"Merging:kFactor1j");
2209 kFactor2jSave = parm(
"Merging:kFactor2j");
2211 muFSave = parm(
"Merging:muFac");
2212 muRSave = parm(
"Merging:muRen");
2213 muFinMESave = parm(
"Merging:muFacInME");
2214 muRinMESave = parm(
"Merging:muRenInME");
2216 doWeakClusteringSave = flag(
"Merging:allowWeakClustering");
2217 doSQCDClusteringSave = flag(
"Merging:allowSQCDClustering");
2218 DparameterSave = parm(
"Merging:Dparameter");
2221 if ( doKTMergingSave || doUserMergingSave || doPTLundMergingSave
2224 tmsValueSave = parm(
"Merging:TMS");
2225 nJetMaxSave = mode(
"Merging:nJetMax");
2226 nJetMaxNLOSave = -1;
2227 }
else if (doMGMergingSave) {
2229 tmsValueSave = hardProcess->tms;
2230 nJetMaxSave = mode(
"Merging:nJetMax");
2231 nJetMaxNLOSave = -1;
2232 }
else if (doCutBasedMergingSave) {
2235 nJetMaxSave = mode(
"Merging:nJetMax");
2236 nJetMaxNLOSave = -1;
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);
2250 if ( doNL3 || doUNLOPS || doEstimateXSection ) {
2251 tmsValueSave = parm(
"Merging:TMS");
2252 nJetMaxSave = mode(
"Merging:nJetMax");
2253 nJetMaxNLOSave = mode(
"Merging:nJetMaxNLO");
2256 tmsValueNow = tmsValueSave;
2259 if ( doNL3 || doUNLOPS ) includeWGTinXSECSave =
false;
2261 hasJetMaxLocal =
false;
2262 nJetMaxLocal = nJetMaxSave;
2263 nJetMaxNLOLocal = nJetMaxNLOSave;
2266 useShowerPluginSave = flag(
"Merging:useShowerPlugin");
2268 bool writeBanner = doKTMergingSave || doMGMergingSave
2269 || doUserMergingSave
2270 || doNL3 || doUNLOPS || doUMEPS
2271 || doPTLundMergingSave || doCutBasedMergingSave;
2273 if (!writeBanner)
return;
2276 cout <<
"\n *------------------ MEPS Merging Initialization ---------------"
2280 if ( doKTMergingSave || doMGMergingSave || doUserMergingSave
2281 || doPTLundMergingSave || doCutBasedMergingSave )
2282 cout <<
" | CKKW-L merge "
2284 <<
" |"<< setw(34) << processSave <<
" with up to"
2285 << setw(3) << nJetMaxSave <<
" additional jets |\n";
2287 cout <<
" | NL3 merge "
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 "
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";
2301 cout <<
" | UMEPS merge "
2303 <<
" |" << setw(34) << processSave <<
" with up to"
2304 << setw(3) << nJetMaxSave <<
" additional jets |\n";
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 "
2322 <<
" | and Q_{ij} cut, with values "
2324 <<
" | Delta R_{ij,min} = "
2325 << setw(7) << scientific << setprecision(2) << tmsListSave[0]
2327 <<
" | pT_{i,min} = "
2328 << setw(6) << fixed << setprecision(1) << tmsListSave[1]
2330 <<
" | Q_{ij,min} = "
2331 << setw(6) << fixed << setprecision(1) << tmsListSave[2]
2333 else if ( doNL3TreeSave )
2334 cout <<
" | Generate tree-level O(alpha_s)-subtracted events "
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 "
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 "
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 "
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 "
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 "
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 "
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 "
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 "
2376 <<
" | Merging scale is defined by Lund pT, with value tMS = "
2377 << setw(6) << fixed << setprecision(1) << tmsValueSave <<
" GeV |";
2381 cout <<
"\n *-------------- END MEPS Merging Initialization ---------------"
2390 bool MergingHooks::doVetoEmission(
const Event& event) {
2393 if ( doIgnoreEmissionsSave )
return false;
2396 if ( doUserMerging() || doMGMerging() || doKTMerging()
2397 || doPTLundMerging() || doCutBasedMerging() )
2403 int nSteps = getNumberOfClusteringSteps(event);
2405 double tnow = tmsNow( event);
2408 int nJetMax = nMaxJets();
2411 if ( nRecluster() > 0 ) nSteps = 1;
2413 if ( nSteps - 1 < nJetMax && nSteps >= 1 && tnow > tms() ) veto =
true;
2416 if ( infoPtr->nMPI() > 1 ) veto =
false;
2420 if ( veto && doNL3Tree() ) setWeightCKKWL(vector<double>(nWgts, 0.));
2423 if ( !veto ) doIgnoreEmissionsSave =
true;
2434 bool MergingHooks::doVetoStep(
const Event& process,
const Event& event,
2435 bool doResonance ) {
2438 if ( doIgnoreStepSave && !doResonance )
return false;
2441 if ( doUMEPSTree() || doUMEPSSubt() || doUMEPSMerging() || doUNLOPSTree()
2442 || doUNLOPSLoop() || doUNLOPSSubt() || doUNLOPSSubtNLO()
2443 || doUNLOPSMerging() )
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);
2455 int nJetMax = nMaxJets();
2458 double tnow = tmsNow( event );
2464 if ( !doResonance ) {
2467 pTsave = infoPtr->pTnow();
2468 if ( nRecluster() == 1) nSteps--;
2472 setEventVetoInfo(nSteps, tnow);
2473 if ( nStepsAfter > nSteps && nSteps > nMaxJetsNLO() && nSteps < nJetMax
2476 weightCKKWL1Save = vector<double>(nWgts, 0.);
2478 weightCKKWL2Save = getWeightCKKWL();
2480 if ( !includeWGTinXSEC() ) setWeightCKKWL(vector<double>( nWgts, 0. ));
2481 if ( includeWGTinXSEC() ) infoPtr->weightContainerPtr->
2482 setWeightNominal(0.);
2490 if ( nStepsAfter > nSteps && nSteps > nMaxJetsNLO() && nSteps < nJetMax
2493 weightCKKWL1Save = vector<double>( nWgts, 0. );
2495 weightCKKWL2Save = getWeightCKKWL();
2497 if ( !includeWGTinXSEC() ) setWeightCKKWL(vector<double>( nWgts, 0. ));
2498 if ( includeWGTinXSEC() ) infoPtr->weightContainerPtr->
2499 setWeightNominal(0.);
2514 bool revokeVeto =
false;
2520 bool check = (nHardInLeptons() == 0)&& (nHardOutLeptons() == 2)
2521 && (nHardOutPartons() == 2);
2529 if ( pTsave > 0. && check ) {
2532 int nResNow = nResInCurrent();
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);
2546 for (
int i=0; i < int(goodSys.size()); ++i ) {
2549 int iMem1 = partonSystemsPtr->getOut(goodSys[i],0);
2550 int iMem2 = partonSystemsPtr->getOut(goodSys[i],1);
2551 int iMem3 = partonSystemsPtr->getOut(goodSys[i],2);
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)));
2561 int iEmt = (iEmtGlue != 0) ? iEmtGlue : iEmtGamm;
2565 if ( iEmt == iMem1 ) {
2566 iRad = (
event[iMem2].mother1() !=
event[iMem2].mother2())
2568 iRec = (
event[iMem3].mother1() ==
event[iMem3].mother2())
2570 }
else if ( iEmt == iMem2 ) {
2571 iRad = (
event[iMem1].mother1() !=
event[iMem1].mother2())
2573 iRec = (
event[iMem3].mother1() ==
event[iMem3].mother2())
2576 iRad = (
event[iMem1].mother1() !=
event[iMem1].mother2())
2578 iRec = (
event[iMem2].mother1() ==
event[iMem2].mother2())
2582 double pTres = rhoPythia(event, iRad, iEmt, iRec, 1);
2587 if ( pTres > pTsave ) {
2601 if ( revokeVeto && check ) {
2602 setWeightCKKWL(weightCKKWL2Save);
2603 }
else if ( check ) {
2604 setWeightCKKWL(weightCKKWL1Save);
2605 if ( weightCKKWL1Save[0] == 0. ) veto =
true;
2609 if ( !check && nSteps > nMaxJetsNLO() && nSteps < nJetMax && tnow > tms()){
2611 if ( !includeWGTinXSEC() ) setWeightCKKWL(vector<double>( nWgts, 0.));
2612 if ( includeWGTinXSEC() ) infoPtr->weightContainerPtr->
2613 setWeightNominal(0.);
2619 if ( !veto || !doIgnoreStepSave ) doIgnoreStepSave =
true;
2635 Event MergingHooks::bareEvent(
const Event& inputEventIn,
2636 bool storeInputEvent ) {
2640 newProcess.init(
"(hard process-modified)", particleDataPtr);
2643 if ( storeInputEvent ) {
2644 resonances.resize(0);
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();
2656 if ( doRemoveDecayProducts ) {
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)
2664 newProcess.append(inputEventIn[i]);
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);
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]);
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();
2696 newProcess.initColTag(maxColTag);
2699 for (
int i = 0; i < inputEventIn.sizeJunction(); ++i)
2700 newProcess.appendJunction( inputEventIn.getJunction(i));
2702 newProcess.saveSize();
2703 newProcess.saveJunctionSize();
2706 newProcess = inputEventIn;
2710 newProcess.scale( inputEventIn.scale() );
2722 bool MergingHooks::reattachResonanceDecays(
Event& process ) {
2725 if ( doRemoveDecayProducts && inputEvent.size() > 0 ) {
2727 int sizeBef = process.size();
2729 vector<int> iAftChecked;
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;
2735 int iOldDaughter1 = inputEvent[resonances[i].second].daughter1();
2736 int iOldDaughter2 = inputEvent[resonances[i].second].daughter2();
2739 int iHardMother = resonances[i].second;
2740 Particle& hardMother = inputEvent[iHardMother];
2743 for (
int k = 0; k < process.size(); ++k )
2744 if ( process[k].
id() == inputEvent[resonances[i].second].id() ) {
2746 bool checked =
false;
2747 for (
int l = 0; l < int(iAftChecked.size()); ++l )
2748 if ( k == iAftChecked[l] )
2751 iAftChecked.push_back(k);
2757 Particle& aftMother = process[iAftMother];
2761 int colBef = hardMother.col();
2762 int acolBef = hardMother.acol();
2763 int colAft = aftMother.col();
2764 int acolAft = aftMother.acol();
2766 M.bst( hardMother.p(), aftMother.p());
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] );
2775 iNewDaughter2 = process.append(inputEvent[k] );
2776 process.back().statusPos();
2777 Particle& now = process.back();
2779 if (now.col() != 0 && now.col() == colBef ) now.col(colAft);
2780 if (now.acol() != 0 && now.acol() == acolBef) now.acol(acolAft);
2783 if (now.hasVertex()) now.vProd( aftMother.vDec() );
2785 now.mothers(iAftMother,0);
2788 process[iAftMother].daughters( iNewDaughter1, iNewDaughter2 );
2789 process[iAftMother].statusNeg();
2794 if ( process[iDec].isFinal() && process[iDec].canDecay()
2795 && process[iDec].mayDecay() && process[iDec].isResonance() ) {
2797 int iD1 = process[iDec].daughter1();
2798 int iD2 = process[iDec].daughter2();
2801 if ( iD1 == 0 || iD2 == 0 )
continue;
2804 int iNewDaughter12 = 0;
2805 int iNewDaughter22 = 0;
2806 for (
int k = iD1; k <= iD2; ++k ) {
2808 iNewDaughter12 = process.append(inputEvent[k] );
2810 iNewDaughter22 = process.append(inputEvent[k] );
2811 process.back().statusPos();
2812 Particle& now = process.back();
2814 if (now.col() != 0 && now.col() == colBef ) now.col(colAft);
2815 if (now.acol()!= 0 && now.acol()== acolBef) now.acol(acolAft);
2818 if (now.hasVertex()) now.vProd( process[iDec].vDec() );
2820 now.mothers(iDec,0);
2824 process[iDec].status(-22);
2825 process[iDec].daughters(iNewDaughter12, iNewDaughter22);
2829 }
while (++iDec < process.size());
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();
2839 process.initColTag(maxColTag);
2844 return (doRemoveDecayProducts) ? inputEvent.size() > 0 :
true;
2850 bool MergingHooks::isInHard(
int iPos,
const Event& event){
2853 if ( event[iPos].statusAbs() > 30 && event[iPos].statusAbs() < 40 )
2856 if ( event[iPos].statusAbs() > 60 )
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);
2868 for (
int i=0; i < int(mpiParticlePos.size()); ++i)
2869 if ( event[iPos].isAncestor( mpiParticlePos[i]) )
2874 int iSys = partonSystemsPtr->getSystemOf(iPos, !event[iPos].isFinal() );
2876 int sysSize = partonSystemsPtr->sizeAll(iSys);
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;
2891 for (
int i = 0; i < sysSize; ++i ) {
2892 int iPosNow = partonSystemsPtr->getAll( iSys, i );
2894 if ( event[iPosNow].statusAbs() > 30
2895 && event[iPosNow].statusAbs() < 40 )
2898 for (
int j=0; j < int(mpiParticlePos.size()); ++j)
2899 if ( event[iPosNow].isAncestor( mpiParticlePos[j]) )
2902 if ( event[iPosNow].statusAbs() > 60 )
2910 bool containsInitialParton =
false;
2914 if (iUp <= 0 || iUp > event.size())
break;
2916 if ( iUp == 3 || iUp == 4 ) {
2917 containsInitialParton =
true;
2920 if ( event[iUp].mother1() == 1
2921 && (
event[iUp].daughter1() == 3 ||
event[iUp].daughter2() == 3) ) {
2922 containsInitialParton =
true;
2925 if ( event[iUp].mother1() == 2
2926 && (
event[iUp].daughter1() == 4 ||
event[iUp].daughter2() == 4) ) {
2927 containsInitialParton =
true;
2931 iUp =
event[iUp].mother1();
2934 if ( !containsInitialParton )
return false;
2945 int MergingHooks::getNumberOfClusteringSteps(
const Event& event,
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()) )
2957 int nFinalLeptons = 0;
2958 for(
int i=0; i <
event.size(); ++i)
2959 if ( event[i].isFinal() && isInHard( i, event) &&
event[i].isLepton())
2963 for(
int i=0; i <
event.size(); ++i)
2964 if ( event[i].isFinal() && isInHard( i, event)
2965 &&
event[i].idAbs() == 1000022)
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) )
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 ) )
2990 int nFinal = nFinalPartons + nFinalLeptons
2991 + 2*(nFinalBosons - nHardOutBosons() );
2994 int nsteps = nFinal - nHardOutPartons() - nHardOutLeptons();
2998 if ( getProcessString().find(
"inc") != string::npos ) {
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++;
3014 if (nzInc == 0 && nwInc == 0 && njInc+naInc > 1) {
3015 nsteps = naInc + njInc - 2;
3017 hasJetMaxLocal =
true;
3018 nJetMaxLocal = nJetMaxSave - 2;
3019 nRequestedSave = nsteps;
3025 if ( nzInc > 0 || nwInc > 0 ) {
3026 nsteps = njInc + naInc + nzInc + nwInc - 1;
3028 hasJetMaxLocal =
true;
3029 nJetMaxLocal = nJetMaxSave - 1;
3030 nRequestedSave = nsteps;
3046 bool MergingHooks::isFirstEmission(
const Event& event ) {
3050 for (
int i=0; i <
event.size(); ++i)
3051 if ( event[i].statusAbs() > 60 )
return false;
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())
3064 if ( event[i].
id() == 23
3065 ||
event[i].idAbs() == 24
3066 ||
event[i].id() == 25)
3068 if ( event[i].
id() == 22)
3070 if ( event[i].isQuark())
3072 if ( event[i].isGluon())
3074 if ( !event[i].isDiquark() )
3081 if (nFinalQuarks + nFinalGluons == 0)
return false;
3084 int nLeptons = nHardOutLeptons();
3088 if (nFinalLeptons > nLeptons)
return false;
3093 for(
int i =0; i< int(hardProcess->hardOutgoing1.size()); ++i)
3094 if (hardProcess->hardOutgoing1[i] == 22)
3096 for(
int i =0; i< int(hardProcess->hardOutgoing2.size()); ++i)
3097 if (hardProcess->hardOutgoing2[i] == 22)
3099 if (nFinalPhotons > nPhotons)
return false;
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 ) {
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;
3136 bool isInclusive = ( getProcessString().find(
"inc") != string::npos );
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) )
3149 if (event[i].isFinal() && (
event[i].idAbs() < 6 ||
event[i].id() == 21)) {
3151 pT2to2 =
event[i].pT();
3152 }
else if ( event[i].isFinal() ) nFinalOther++;
3154 bool is2to2QCD = ( nFinalPartons == 2 && nInitialPartons == 2
3155 && nFinalOther == 0 );
3156 bool hasMPIoverlap = is2to2QCD;
3157 bool is2to1 = ( nFinalPartons == 0 );
3159 double scale =
event.scale();
3165 pTmaxISR = pTmaxFSR = pTmaxMPI = scale;
3169 if ( limitPTmaxISR && !isInclusive ) pTmaxISR = min(scale,muF());
3170 if ( limitPTmaxFSR && !isInclusive ) pTmaxFSR = min(scale,muF());
3171 if ( limitPTmaxMPI && !isInclusive ) pTmaxMPI = min(scale,muF());
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());
3185 if ( hasMPIoverlap ) pTmaxMPI = infoPtr->eCM();
3188 if ( pTscale < infoPtr->eCM() ) {
3189 limitPTmaxISR = limitPTmaxFSR = limitPTmaxMPI =
true;
3191 if ( hasMPIoverlap ) limitPTmaxMPI =
false;
3197 if ( doMergeFirstEmm ) {
3200 bool doRecluster = doUMEPSSubt() || doNL3Subt() || doUNLOPSSubt()
3201 || doUNLOPSSubtNLO();
3204 pTmaxISR = pTmaxFSR = pTmaxMPI = scale;
3208 if ( limitPTmaxISR && !isInclusive ) pTmaxISR = min(scale,muF());
3209 if ( limitPTmaxFSR && !isInclusive ) pTmaxFSR = min(scale,muF());
3210 if ( limitPTmaxMPI && !isInclusive ) pTmaxMPI = min(scale,muF());
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());
3224 if ( hasMPIoverlap && !doRecluster ) {
3225 pTmaxMPI = infoPtr->eCM();
3226 limitPTmaxMPI =
false;
3231 if ( doRecluster ) {
3233 limitPTmaxMPI =
true;
3238 limitPTmaxFSRIn = limitPTmaxFSR;
3239 limitPTmaxISRIn = limitPTmaxISR;
3240 limitPTmaxMPIIn = limitPTmaxMPI;
3241 pTmaxFSRIn = pTmaxFSR;
3242 pTmaxISRIn = pTmaxISR;
3243 pTmaxMPIIn = pTmaxMPI;
3244 pTscaleIn = pTscale;
3256 double MergingHooks::tmsNow(
const Event& event ) {
3260 int unlopsType = mode(
"Merging:unlopsTMSdefinition");
3262 if ( doKTMerging() || doMGMerging() )
3265 else if ( doPTLundMerging() )
3266 tnow = rhoms(event,
false);
3268 else if ( doCutBasedMerging() )
3269 tnow = cutbasedms(event);
3271 else if ( doNL3Merging() )
3272 tnow = rhoms(event,
false);
3274 else if ( doUNLOPSMerging() )
3275 tnow = (unlopsType < 0) ? rhoms(event,
false) : tmsDefinition(event);
3277 else if ( doUMEPSMerging() )
3278 tnow = rhoms(event,
false);
3281 tnow = tmsDefinition(event);
3291 bool MergingHooks::checkAgainstCut(
const Particle& particle){
3294 if (particle.colType() == 0)
return false;
3296 if ( particle.idAbs() != 21 && particle.idAbs() > nQuarksMergeSave )
3308 double MergingHooks::kTms(
const Event& event) {
3311 if (!isFirstEmission(event))
return 0.;
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);
3326 vector <int> FinalPartPos;
3327 FinalPartPos.clear();
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;
3340 if ( !isDecayProduct
3341 || getProcessString().compare(
"e+e->jj") == 0
3342 || getProcessString().compare(
"e+e->(z>jj)") == 0 )
3343 FinalPartPos.push_back(i);
3349 int type = (
event[3].colType() == 0
3350 &&
event[4].colType() == 0) ? -1 : ktTypeSave;
3352 double ktmin =
event[0].e();
3353 for(
int i=0; i < int(FinalPartPos.size()); ++i){
3354 double kt12 = ktmin;
3356 if (type == 1 || type == 2) {
3357 double temp =
event[FinalPartPos[i]].pT();
3358 kt12 = min(kt12, temp);
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);
3367 ktmin = min(ktmin,kt12);
3379 double MergingHooks::kTdurham(
const Particle& RadAfterBranch,
3380 const Particle& EmtAfterBranch,
int Type,
double D ){
3385 Vec4 jet1 = RadAfterBranch.p();
3386 Vec4 jet2 = EmtAfterBranch.p();
3392 if (jet1.pAbs()*jet2.pAbs() <=0.) costh = 1.;
3394 costh = costheta(jet1,jet2);
3397 ktdur = 2.0*min( pow(jet1.e(),2) , (pow(jet2.e(),2)) )*(1.0 - costh);
3398 }
else if ( Type == 1 ){
3401 double mT1sq = jet1.m2Calc() + jet1.pT2();
3403 if (mT1sq < 0) mT1 = - sqrt(-mT1sq);
3404 else mT1 = sqrt(mT1sq);
3406 double mT2sq = jet2.m2Calc() + jet2.pT2();
3408 if (mT2sq < 0) mT2 = - sqrt(-mT2sq);
3409 else mT2 = sqrt(mT2sq);
3411 double y1 = log( ( jet1.e() + abs(jet1.pz()) ) / mT1 );
3412 if (jet1.pz() < 0) y1 *= -1.;
3414 double y2 = log( ( jet2.e() + abs(jet2.pz()) ) / mT2 );
3415 if (jet2.pz() < 0) y2 *= -1.;
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 );
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 ){
3428 double mT1sq = jet1.m2Calc() + jet1.pT2();
3430 if (mT1sq < 0) mT1 = - sqrt(-mT1sq);
3431 else mT1 = sqrt(mT1sq);
3433 double mT2sq = jet2.m2Calc() + jet2.pT2();
3435 if (mT2sq < 0) mT2 = - sqrt(-mT2sq);
3436 else mT2 = sqrt(mT2sq);
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.;
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.;
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 );
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 ){
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 );
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);
3464 ktdur = 2.0*min( pow(pt1,2),pow(pt2,2) )
3465 * ( coshdEta - cosdPhi ) / pow(D,2);
3479 double MergingHooks::rhoms(
const Event& event,
bool withColour){
3482 if (!isFirstEmission(event))
return 0.;
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) {
3489 double temp = rhoPythia( event, i, j, 0, 0 );
3490 if (temp > 0.) ptret = min(ptret, temp);
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);
3509 vector <int> FinalPartPos;
3510 FinalPartPos.clear();
3513 for (
int i=0; i <
event.size(); ++i){
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;
3524 if ( !isDecayProduct
3525 || getProcessString().compare(
"e+e->jj") == 0
3526 || getProcessString().compare(
"e+e->(z>jj)") == 0 )
3527 FinalPartPos.push_back(i);
3531 if ( getProcessString().find(
"Ainc") != string::npos
3532 && event[i].isFinal() && event[i].idAbs() == 22 )
3533 FinalPartPos.push_back(i);
3535 if ( getProcessString().find(
"Zinc") != string::npos
3536 && event[i].isFinal() && event[i].idAbs() == 23 )
3537 FinalPartPos.push_back(i);
3539 if ( getProcessString().find(
"Winc") != string::npos
3540 && event[i].isFinal() && event[i].idAbs() == 24 )
3541 FinalPartPos.push_back(i);
3546 for (
int i=0; i <
event.size(); ++i)
3547 if (abs(event[i].status()) == 41 ){
3554 for (
int i=0; i <
event.size(); ++i)
3555 if (abs(event[i].status()) == 42 ){
3561 if (in1 == 0 || in2 == 0){
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;
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) )
3575 if (event[i].isFinal() &&
event[i].idAbs() >= 6 &&
event[i].id() != 21)
3578 bool is2to2QCD = ( int(FinalPartPos.size()) == 2 && nInitialPartons == 2
3579 && nFinalOther == 0 );
3583 double pt12 = min(event[FinalPartPos[0]].pT(),
3584 event[FinalPartPos[1]].pT());
3589 double ptmin =
event[0].e();
3590 for(
int i=0; i < int(FinalPartPos.size()); ++i){
3592 double pt12 = ptmin;
3594 if (event[in1].colType() != 0) {
3595 double temp = rhoPythia( event, in1, FinalPartPos[i], in2, -1 );
3596 pt12 = min(pt12, temp);
3600 if ( event[in2].colType() != 0) {
3601 double temp = rhoPythia( event, in2, FinalPartPos[i], in1, -1 );
3602 pt12 = min(pt12, temp);
3608 for(
int j=0; j < int(FinalPartPos.size()); ++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();
3619 if (radAcl > 0 && radAcl != emtCol)
3620 iRec = findColour(radAcl, FinalPartPos[i], FinalPartPos[j],
3622 if (iRec <= 0 && radCol > 0 && radCol != emtAcl)
3623 iRec = findColour(radCol, FinalPartPos[i], FinalPartPos[j],
3625 if (iRec <= 0 && emtAcl > 0 && emtAcl != radCol)
3626 iRec = findColour(emtAcl, FinalPartPos[i], FinalPartPos[j],
3628 if (iRec <= 0 && emtCol > 0 && emtCol != radAcl)
3629 iRec = findColour(emtCol, FinalPartPos[i], FinalPartPos[j],
3633 if (iRec <= 0 && radAcl > 0 && radAcl != emtCol)
3634 iRec = findColour(radAcl, FinalPartPos[i], FinalPartPos[j],
3636 if (iRec <= 0 && radCol > 0 && radCol != emtAcl)
3637 iRec = findColour(radCol, FinalPartPos[i], FinalPartPos[j],
3639 if (iRec <= 0 && emtAcl > 0 && emtAcl != radCol)
3640 iRec = findColour(emtAcl, FinalPartPos[i], FinalPartPos[j],
3642 if (iRec <= 0 && emtCol > 0 && emtCol != radAcl)
3643 iRec = findColour(emtCol, FinalPartPos[i], FinalPartPos[j],
3647 double temp = rhoPythia( event, FinalPartPos[i], FinalPartPos[j],
3649 pt12 = min(pt12, temp);
3657 for(
int j=0; j < int(FinalPartPos.size()); ++j) {
3658 for(
int k=0; k < int(FinalPartPos.size()); ++k) {
3660 if ( (i != j) && (i != k) && (j != k) ){
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);
3677 if ( event[in1].colType() != 0 && event[in2].colType() != 0) {
3678 for(
int j=0; j < int(FinalPartPos.size()); ++j) {
3684 if (event[in1].colType() != 0)
3685 temp = rhoPythia( event, FinalPartPos[i],FinalPartPos[j],in1, 1);
3686 pt12 = min(pt12, temp);
3688 if (event[in2].colType() != 0)
3689 temp = rhoPythia( event, FinalPartPos[i],FinalPartPos[j],in2, 1);
3690 pt12 = min(pt12, temp);
3697 ptmin = min(ptmin,pt12);
3709 double MergingHooks::rhoPythia(
const Event& event,
int rad,
int emt,
int rec,
3712 Particle RadAfterBranch =
event[rad];
3713 Particle EmtAfterBranch =
event[emt];
3714 Particle RecAfterBranch =
event[rec];
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);
3724 vector<string> names
3725 = showers->timesPtr->getSplittingName(event, rad, emt, 0);
3726 for (
int iName=0; iName < int(names.size()); ++iName) {
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);
3741 vector<string> names
3742 = showers->spacePtr->getSplittingName(event, rad, emt, 0);
3743 for (
int iName=0; iName < int(names.size()); ++iName) {
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);
3766 bool allowed =
true;
3769 int Type = ShowerType;
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;
3777 int sign = (Type==1) ? 1 : -1;
3778 Vec4 Q(RadAfterBranch.p() + sign*EmtAfterBranch.p());
3779 double Qsq = sign * Q.m2Calc();
3782 if ( Qsq < 0.0 ) allowed =
false;
3785 Vec4 radAft(RadAfterBranch.p());
3786 Vec4 recAft(RecAfterBranch.p());
3787 Vec4 emtAft(EmtAfterBranch.p());
3791 int flavEmt = EmtAfterBranch.id();
3792 int flavRad = RadAfterBranch.id();
3794 if (abs(flavEmt) == 21 || abs(flavEmt) == 22 ) idRadBef=flavRad;
3796 if (Type == 1 && flavEmt == -flavRad) idRadBef=21;
3798 if (Type == 1 && abs(flavEmt) < 10 && flavRad == 21) idRadBef=flavEmt;
3800 if (Type == -1 && abs(flavEmt) < 10 && flavRad == 21) idRadBef=-flavEmt;
3802 if (Type == -1 && abs(flavEmt) < 10 && flavRad == flavEmt) idRadBef=21;
3804 if (flavEmt == 24) idRadBef = RadAfterBranch.id()+1;
3805 if (flavEmt == -24) idRadBef = RadAfterBranch.id()-1;
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;
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);
3828 }
else if (!RadAfterBranch.isFinal()) {
3829 if (RadAfterBranch.idAbs() == 21 && EmtAfterBranch.idAbs() != 21)
3830 m2RadBef = m2EmtAft;
3833 double m2Final = (radAft + recAft + emtAft).m2Calc();
3835 if (m2Final < 0.0) allowed =
false;
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));
3843 if (rescale < 0.0) allowed =
false;
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;
3853 if ( RadAfterBranch.isFinal()
3854 && ( x1 < 0.0 || x1 > 1.0 || x2 < 0.0 || x2 > 1.0)) allowed =
false;
3857 Vec4 qBR(RadAfterBranch.p() - EmtAfterBranch.p() + RecAfterBranch.p());
3858 Vec4 qAR(RadAfterBranch.p() + RecAfterBranch.p());
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 );
3867 double z = (Type==1) ? 1./ ( 1- k1 -k3) * ( x1 / (2.-x2) - k3)
3868 : (qBR.m2Calc())/( qAR.m2Calc());
3871 if ( z < 0.0 || z > 1.0) allowed =
false;
3874 double pTpyth = (Type==1) ? z*(1.-z) : (1.-z);
3877 if (Type == 1) pTpyth *= (Qsq - m2RadBef);
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);
3895 if (!allowed) pTpyth = 1e15;
3897 if ( pTpyth < 0. ) pTpyth = 0.;
3900 return sqrt(pTpyth);
3921 int MergingHooks::findColour(
int col,
int iExclude1,
int iExclude2,
3922 const Event& event,
int type,
bool isHardIn){
3924 bool isHard = isHardIn;
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
3933 ||
event[n].status() == -21) ) {
3934 if ( event[n].acol() == col ) {
3938 if ( event[n].col() == col ){
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
3951 ||
event[n].status() == 51
3952 ||
event[n].status() == 52
3953 ||
event[n].status() == -41
3954 ||
event[n].status() == -42) ) {
3955 if ( event[n].acol() == col ) {
3959 if ( event[n].col() == col ){
3967 if ( type == 1 && index < 0)
return abs(index);
3968 if ( type == 2 && index > 0)
return abs(index);
3978 double MergingHooks::cutbasedms(
const Event& event ){
3981 if (!isFirstEmission(event))
return -1.;
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);
3993 bool doVeto =
false;
3995 bool vetoPT =
false;
3996 bool vetoRjj =
false;
3997 bool vetoMjj =
false;
3999 double pTjmin = pTiMS();
4000 double mjjmin = QijMS();
4001 double rjjmin = dRijMS();
4004 double minPT =
event[0].e();
4005 double minRJJ = 10.;
4006 double minMJJ =
event[0].e();
4009 for(
int i=0; i < int(partons.size()); ++i){
4011 minPT = min(minPT,event[partons[i]].pT());
4014 for(
int j=0; j < int(partons.size()); ++j){
4018 minRJJ = min(minRJJ, deltaRij( event[partons[i]].p(),
4019 event[partons[j]].p()) );
4021 minMJJ = min(minMJJ, ( event[partons[i]].p()
4022 +event[partons[j]].p() ).mCalc() );
4030 if (minPT > pTjmin) vetoPT =
true;
4031 if (minRJJ > rjjmin) vetoRjj =
true;
4032 if (minMJJ > mjjmin) vetoMjj =
true;
4039 if (
int(partons.size() == 1))
4043 doVeto = vetoPT && vetoRjj && vetoMjj;
4046 if (doVeto)
return 1.;
4057 double MergingHooks::deltaRij(Vec4 jet1, Vec4 jet2){
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()) );
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 );
4070 deltaR = sqrt(pow(eta1-eta2,2) + pow(dPhi,2));
4078 void MergingHooks::printIndividualWeights() {
4079 cout <<
"Individual merging weight components, muR scales 1, ";
4080 for (
double muRfac: muRVarFactors) cout << muRfac <<
" ";
4083 for (
double wt: individualWeights.wtSave) cout << wt <<
" ";
4085 cout <<
"pdfWeight: ";
4086 for (
double wt: individualWeights.pdfWeightSave) cout << wt <<
" ";
4088 cout <<
"mpiWeight: ";
4089 for (
double wt: individualWeights.mpiWeightSave) cout << wt <<
" ";
4091 cout <<
"asWeight: ";
4092 for (
double wt: individualWeights.asWeightSave) cout << wt <<
" ";
4094 cout <<
"aemWeight: ";
4095 for (
double wt: individualWeights.aemWeightSave) cout << wt <<
" ";
4097 cout <<
"bornAsVarFac: ";
4098 for (
double wt: individualWeights.bornAsVarFac) cout << wt <<
" ";