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(outgoing2[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 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 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 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 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, map<int,int> further1, map<int,int> further2) {
1755 int nOld1 = candidates1.size();
1756 int nOld2 = candidates2.size();
1757 int nNew1 = further1.size();
1758 int nNew2 = further2.size();
1759 bool exchanged =
false;
1761 if ( nOld1 == 1 && nOld2 == 0 && nNew1 == 1 && nNew2 == 0){
1762 PosOutgoing1[further1.begin()->first] = further1.begin()->second;
1764 }
else if ( nOld1 == 0 && nOld2 == 1 && nNew1 == 0 && nNew2 == 1){
1765 PosOutgoing2[further2.begin()->first] = further2.begin()->second;
1768 }
else if ( nNew1 > 1 && nNew2 == 0 ) {
1769 PosOutgoing1[further1.begin()->first] = further1.begin()->second;
1771 }
else if ( nNew1 == 0 && nNew2 > 0 ) {
1772 PosOutgoing2[further2.begin()->first] = further2.begin()->second;
1786 int HardProcess::nQuarksOut(){
1788 for(
int i =0; i< int(hardOutgoing1.size()); ++i){
1789 if (hardOutgoing1[i] == 2212 || abs(hardOutgoing1[i]) < 10) nFin++;
1791 for(
int i =0; i< int(hardOutgoing2.size()); ++i){
1792 if (hardOutgoing2[i] == 2212 || abs(hardOutgoing2[i]) < 10) nFin++;
1796 for(
int i =0; i< int(hardOutgoing1.size()); ++i)
1797 if (hardOutgoing1[i] == 5000)
1798 for(
int j =0; j< int(PosOutgoing1.size()); ++j)
1799 if (state[PosOutgoing1[j]].idAbs() == 5)
1801 for(
int i =0; i< int(hardOutgoing2.size()); ++i)
1802 if (hardOutgoing2[i] == 5000)
1803 for(
int j =0; j< int(PosOutgoing2.size()); ++j)
1804 if (state[PosOutgoing2[j]].idAbs() == 5)
1814 int HardProcess::nLeptonOut(){
1816 for(
int i =0; i< int(hardOutgoing1.size()); ++i){
1817 if (abs(hardOutgoing1[i]) > 10 && abs(hardOutgoing1[i]) < 20) nFin++;
1819 if (abs(hardOutgoing1[i]) == 1000022) nFin++;
1821 if ( abs(hardOutgoing1[i]) == 1000011 || abs(hardOutgoing1[i]) == 2000011
1822 || abs(hardOutgoing1[i]) == 1000013 || abs(hardOutgoing1[i]) == 2000013
1823 || abs(hardOutgoing1[i]) == 1000015 || abs(hardOutgoing1[i]) == 2000015)
1826 for(
int i =0; i< int(hardOutgoing2.size()); ++i){
1827 if (abs(hardOutgoing2[i]) > 10 && abs(hardOutgoing2[i]) < 20) nFin++;
1829 if (abs(hardOutgoing2[i]) == 1000022) nFin++;
1831 if ( abs(hardOutgoing2[i]) == 1000011 || abs(hardOutgoing2[i]) == 2000011
1832 || abs(hardOutgoing2[i]) == 1000013 || abs(hardOutgoing2[i]) == 2000013
1833 || abs(hardOutgoing2[i]) == 1000015 || abs(hardOutgoing2[i]) == 2000015)
1839 for(
int i =0; i< int(hardOutgoing1.size()); ++i)
1840 if (hardOutgoing1[i] == 1100)
1841 for(
int j =0; j< int(PosOutgoing1.size()); ++j)
1842 if ( abs(state[PosOutgoing1[j]].
id()) == 11
1843 || abs(state[PosOutgoing1[j]].
id()) == 13
1844 || abs(state[PosOutgoing1[j]].
id()) == 15 )
1846 for(
int i =0; i< int(hardOutgoing2.size()); ++i)
1847 if (hardOutgoing2[i] == 1200)
1848 for(
int j =0; j< int(PosOutgoing2.size()); ++j)
1849 if ( abs(state[PosOutgoing2[j]].
id()) == 12
1850 || abs(state[PosOutgoing2[j]].
id()) == 14
1851 || abs(state[PosOutgoing2[j]].
id()) == 16 )
1861 int HardProcess::nBosonsOut(){
1863 for(
int i =0; i< int(hardOutgoing1.size()); ++i){
1864 if (abs(hardOutgoing1[i]) > 20 && abs(hardOutgoing1[i]) <= 25) nFin++;
1866 for(
int i =0; i< int(hardOutgoing2.size()); ++i){
1867 if (abs(hardOutgoing2[i]) > 20 && abs(hardOutgoing2[i]) <= 25) nFin++;
1868 if ( hardOutgoing2[i] == 2400) nFin++;
1878 int HardProcess::nQuarksIn(){
1880 if (hardIncoming1 == 2212 || abs(hardIncoming1) < 10) nIn++;
1881 if (hardIncoming2 == 2212 || abs(hardIncoming2) < 10) nIn++;
1890 int HardProcess::nLeptonIn(){
1892 if (abs(hardIncoming1) > 10 && abs(hardIncoming1) < 20) nIn++;
1893 if (abs(hardIncoming2) > 10 && abs(hardIncoming2) < 20) nIn++;
1902 int HardProcess::hasResInCurrent(){
1903 for(
int i =0; i< int(PosIntermediate.size()); ++i)
1904 if (PosIntermediate[i] == 0)
return 0;
1906 for(
int i =0; i< int(PosIntermediate.size()); ++i){
1907 for(
int j =0; j< int(PosOutgoing1.size()); ++j){
1908 if ( PosIntermediate[i] == PosOutgoing1[j] )
1911 for(
int j =0; j< int(PosOutgoing2.size()); ++j){
1912 if ( PosIntermediate[i] == PosOutgoing2[j] )
1924 int HardProcess::nResInCurrent(){
1926 for(
int i =0; i< int(PosIntermediate.size()); ++i){
1927 if (PosIntermediate[i] != 0) {
1928 bool matchesFinalBoson =
false;
1929 for(
int j =0; j< int(PosOutgoing1.size()); ++j){
1930 if ( PosIntermediate[i] == PosOutgoing1[j] )
1931 matchesFinalBoson =
true;
1933 for(
int j =0; j< int(PosOutgoing2.size()); ++j){
1934 if ( PosIntermediate[i] == PosOutgoing2[j] )
1935 matchesFinalBoson =
true;
1937 if (!matchesFinalBoson) nRes++;
1948 bool HardProcess::hasResInProc(){
1950 for(
int i =0; i< int(hardIntermediate.size()); ++i)
1951 if (hardIntermediate[i] == 0)
return false;
1953 for(
int i =0; i< int(hardIntermediate.size()); ++i){
1954 for(
int j =0; j< int(hardOutgoing1.size()); ++j){
1955 if ( hardIntermediate[i] == hardOutgoing1[j] )
1958 for(
int j =0; j< int(hardOutgoing2.size()); ++j){
1959 if ( hardIntermediate[i] == hardOutgoing2[j] )
1970 void HardProcess::list()
const {
1971 cout <<
" Hard Process: ";
1972 cout <<
" \t " << hardIncoming1 <<
" + " << hardIncoming2;
1973 cout <<
" \t -----> \t ";
1974 for(
int i =0; i < int(hardIntermediate.size());++i)
1975 cout << hardIntermediate[i] <<
" ";
1976 cout <<
" \t -----> \t ";
1977 for(
int i =0; i < int(hardOutgoing1.size());++i)
1978 cout << hardOutgoing1[i] <<
" ";
1979 for(
int i =0; i < int(hardOutgoing2.size());++i)
1980 cout << hardOutgoing2[i] <<
" ";
1989 void HardProcess::listCandidates()
const {
1990 cout <<
" Hard Process candidates: ";
1991 cout <<
" \t " << hardIncoming1 <<
" + " << hardIncoming2;
1992 cout <<
" \t -----> \t ";
1993 for(
int i =0; i < int(PosIntermediate.size());++i)
1994 cout << PosIntermediate[i] <<
" ";
1995 cout <<
" \t -----> \t ";
1996 for(
int i =0; i < int(PosOutgoing1.size());++i)
1997 cout << PosOutgoing1[i] <<
" ";
1998 for(
int i =0; i < int(PosOutgoing2.size());++i)
1999 cout << PosOutgoing2[i] <<
" ";
2007 void HardProcess::clear() {
2010 hardIncoming1 = hardIncoming2 = 0;
2012 hardOutgoing1.resize(0);
2013 hardOutgoing2.resize(0);
2015 hardIntermediate.resize(0);
2021 PosOutgoing1.resize(0);
2022 PosOutgoing2.resize(0);
2024 PosIntermediate.resize(0);
2038 MergingHooks::~MergingHooks() {
if (useOwnHardProcess)
delete hardProcess; }
2044 void MergingHooks::init(){
2050 double alphaSvalueFSR = settingsPtr->parm(
"TimeShower:alphaSvalue");
2051 int alphaSorderFSR = settingsPtr->mode(
"TimeShower:alphaSorder");
2052 int alphaSnfmax = settingsPtr->mode(
"StandardModel:alphaSnfmax");
2053 int alphaSuseCMWFSR= settingsPtr->flag(
"TimeShower:alphaSuseCMW");
2054 AlphaS_FSRSave.init(alphaSvalueFSR, alphaSorderFSR, alphaSnfmax,
2056 double alphaSvalueISR = settingsPtr->parm(
"SpaceShower:alphaSvalue");
2057 int alphaSorderISR = settingsPtr->mode(
"SpaceShower:alphaSorder");
2058 int alphaSuseCMWISR= settingsPtr->flag(
"SpaceShower:alphaSuseCMW");
2059 AlphaS_ISRSave.init(alphaSvalueISR, alphaSorderISR, alphaSnfmax,
2063 int alphaEMFSRorder = settingsPtr->mode(
"TimeShower:alphaEMorder");
2064 AlphaEM_FSRSave.init(alphaEMFSRorder, settingsPtr);
2065 int alphaEMISRorder = settingsPtr->mode(
"SpaceShower:alphaEMorder");
2066 AlphaEM_ISRSave.init(alphaEMISRorder, settingsPtr);
2069 doUserMergingSave = settingsPtr->flag(
"Merging:doUserMerging");
2071 doMGMergingSave = settingsPtr->flag(
"Merging:doMGMerging");
2073 doKTMergingSave = settingsPtr->flag(
"Merging:doKTMerging");
2075 doPTLundMergingSave = settingsPtr->flag(
"Merging:doPTLundMerging");
2077 doCutBasedMergingSave = settingsPtr->flag(
"Merging:doCutBasedMerging");
2079 ktTypeSave = settingsPtr->mode(
"Merging:ktType");
2082 doNL3TreeSave = settingsPtr->flag(
"Merging:doNL3Tree");
2083 doNL3LoopSave = settingsPtr->flag(
"Merging:doNL3Loop");
2084 doNL3SubtSave = settingsPtr->flag(
"Merging:doNL3Subt");
2085 bool doNL3 = doNL3TreeSave || doNL3LoopSave || doNL3SubtSave;
2088 doUNLOPSTreeSave = settingsPtr->flag(
"Merging:doUNLOPSTree");
2089 doUNLOPSLoopSave = settingsPtr->flag(
"Merging:doUNLOPSLoop");
2090 doUNLOPSSubtSave = settingsPtr->flag(
"Merging:doUNLOPSSubt");
2091 doUNLOPSSubtNLOSave = settingsPtr->flag(
"Merging:doUNLOPSSubtNLO");
2092 bool doUNLOPS = doUNLOPSTreeSave || doUNLOPSLoopSave
2093 || doUNLOPSSubtSave || doUNLOPSSubtNLOSave;
2096 doUMEPSTreeSave = settingsPtr->flag(
"Merging:doUMEPSTree");
2097 doUMEPSSubtSave = settingsPtr->flag(
"Merging:doUMEPSSubt");
2098 nReclusterSave = settingsPtr->mode(
"Merging:nRecluster");
2099 nQuarksMergeSave = settingsPtr->mode(
"Merging:nQuarksMerge");
2100 nRequestedSave = settingsPtr->mode(
"Merging:nRequested");
2101 bool doUMEPS = doUMEPSTreeSave || doUMEPSSubtSave;
2104 doEstimateXSection = settingsPtr->flag(
"Merging:doXSectionEstimate");
2108 includeWGTinXSECSave = settingsPtr->flag(
"Merging:includeWeightInXsection");
2111 applyVeto = settingsPtr->flag(
"Merging:applyVeto");
2114 processSave = settingsPtr->word(
"Merging:Process");
2117 hardProcess =
new HardProcess();
2118 useOwnHardProcess =
true;
2122 hardProcess->clear();
2125 inputEvent.init(
"(hard process)", particleDataPtr);
2126 doRemoveDecayProducts = settingsPtr->flag(
"Merging:mayRemoveDecayProducts");
2129 if ( doMGMergingSave )
2130 hardProcess->initOnLHEF(lheInputFile, particleDataPtr);
2132 hardProcess->initOnProcess(processSave, particleDataPtr);
2135 while(processSave.find(
" ", 0) != string::npos)
2136 processSave.erase(processSave.begin()+processSave.find(
" ",0));
2139 includeMassiveSave = settingsPtr->flag(
"Merging:includeMassive");
2140 enforceStrongOrderingSave =
2141 settingsPtr->flag(
"Merging:enforceStrongOrdering");
2142 scaleSeparationFactorSave =
2143 settingsPtr->parm(
"Merging:scaleSeparationFactor");
2144 orderInRapiditySave = settingsPtr->flag(
"Merging:orderInRapidity");
2147 nonJoinedNormSave = settingsPtr->parm(
"Merging:nonJoinedNorm");
2148 fsrInRecNormSave = settingsPtr->parm(
"Merging:fsrInRecNorm");
2149 pickByFullPSave = settingsPtr->flag(
"Merging:pickByFullP");
2150 pickByPoPT2Save = settingsPtr->flag(
"Merging:pickByPoPT2");
2151 includeRedundantSave = settingsPtr->flag(
"Merging:includeRedundant");
2154 unorderedScalePrescipSave =
2155 settingsPtr->mode(
"Merging:unorderedScalePrescrip");
2156 unorderedASscalePrescipSave =
2157 settingsPtr->mode(
"Merging:unorderedASscalePrescrip");
2158 unorderedPDFscalePrescipSave =
2159 settingsPtr->mode(
"Merging:unorderedPDFscalePrescrip");
2160 incompleteScalePrescipSave =
2161 settingsPtr->mode(
"Merging:incompleteScalePrescrip");
2164 allowColourShufflingSave =
2165 settingsPtr->flag(
"Merging:allowColourShuffling");
2169 resetHardQRenSave = settingsPtr->flag(
"Merging:usePythiaQRenHard");
2170 resetHardQFacSave = settingsPtr->flag(
"Merging:usePythiaQFacHard");
2173 pickBySumPTSave = settingsPtr->flag(
"Merging:pickBySumPT");
2174 herwigAcollFSRSave = settingsPtr->parm(
"Merging:aCollFSR");
2175 herwigAcollISRSave = settingsPtr->parm(
"Merging:aCollISR");
2178 pT0ISRSave = settingsPtr->parm(
"SpaceShower:pT0Ref");
2179 pTcutSave = settingsPtr->parm(
"SpaceShower:pTmin");
2180 pTcutSave = max(pTcutSave,pT0ISRSave);
2183 weightCKKWLSave = 1.;
2184 weightFIRSTSave = 0.;
2190 tmsListSave.resize(0);
2192 kFactor0jSave = settingsPtr->parm(
"Merging:kFactor0j");
2193 kFactor1jSave = settingsPtr->parm(
"Merging:kFactor1j");
2194 kFactor2jSave = settingsPtr->parm(
"Merging:kFactor2j");
2196 muFSave = settingsPtr->parm(
"Merging:muFac");
2197 muRSave = settingsPtr->parm(
"Merging:muRen");
2198 muFinMESave = settingsPtr->parm(
"Merging:muFacInME");
2199 muRinMESave = settingsPtr->parm(
"Merging:muRenInME");
2201 doWeakClusteringSave = settingsPtr->flag(
"Merging:allowWeakClustering");
2202 doSQCDClusteringSave = settingsPtr->flag(
"Merging:allowSQCDClustering");
2203 DparameterSave = settingsPtr->parm(
"Merging:Dparameter");
2206 if ( doKTMergingSave || doUserMergingSave || doPTLundMergingSave
2209 tmsValueSave = settingsPtr->parm(
"Merging:TMS");
2210 nJetMaxSave = settingsPtr->mode(
"Merging:nJetMax");
2211 nJetMaxNLOSave = -1;
2212 }
else if (doMGMergingSave) {
2214 tmsValueSave = hardProcess->tms;
2215 nJetMaxSave = settingsPtr->mode(
"Merging:nJetMax");
2216 nJetMaxNLOSave = -1;
2217 }
else if (doCutBasedMergingSave) {
2220 nJetMaxSave = settingsPtr->mode(
"Merging:nJetMax");
2221 nJetMaxNLOSave = -1;
2224 tmsListSave.resize(0);
2225 double drms = settingsPtr->parm(
"Merging:dRijMS");
2226 double ptms = settingsPtr->parm(
"Merging:pTiMS");
2227 double qms = settingsPtr->parm(
"Merging:QijMS");
2228 tmsListSave.push_back(drms);
2229 tmsListSave.push_back(ptms);
2230 tmsListSave.push_back(qms);
2235 if ( doNL3 || doUNLOPS || doEstimateXSection ) {
2236 tmsValueSave = settingsPtr->parm(
"Merging:TMS");
2237 nJetMaxSave = settingsPtr->mode(
"Merging:nJetMax");
2238 nJetMaxNLOSave = settingsPtr->mode(
"Merging:nJetMaxNLO");
2241 tmsValueNow = tmsValueSave;
2244 if ( doNL3 || doUNLOPS ) includeWGTinXSECSave =
false;
2246 hasJetMaxLocal =
false;
2247 nJetMaxLocal = nJetMaxSave;
2248 nJetMaxNLOLocal = nJetMaxNLOSave;
2251 useShowerPluginSave = settingsPtr->flag(
"Merging:useShowerPlugin");
2253 bool writeBanner = doKTMergingSave || doMGMergingSave
2254 || doUserMergingSave
2255 || doNL3 || doUNLOPS || doUMEPS
2256 || doPTLundMergingSave || doCutBasedMergingSave;
2258 if (!writeBanner)
return;
2261 cout <<
"\n *------------------ MEPS Merging Initialization ---------------"
2265 if ( doKTMergingSave || doMGMergingSave || doUserMergingSave
2266 || doPTLundMergingSave || doCutBasedMergingSave )
2267 cout <<
" | CKKW-L merge "
2269 <<
" |"<< setw(34) << processSave <<
" with up to"
2270 << setw(3) << nJetMaxSave <<
" additional jets |\n";
2272 cout <<
" | NL3 merge "
2274 <<
" |" << setw(31) << processSave <<
" with jets up to"
2275 << setw(3) << nJetMaxNLOSave <<
" correct to NLO |\n"
2276 <<
" | and up to" << setw(3) << nJetMaxSave
2277 <<
" additional jets included by CKKW-L merging at LO |\n";
2278 else if ( doUNLOPS )
2279 cout <<
" | UNLOPS merge "
2281 <<
" |" << setw(31) << processSave <<
" with jets up to"
2282 << setw(3)<< nJetMaxNLOSave <<
" correct to NLO |\n"
2283 <<
" | and up to" << setw(3) << nJetMaxSave
2284 <<
" additional jets included by UMEPS merging at LO |\n";
2286 cout <<
" | UMEPS merge "
2288 <<
" |" << setw(34) << processSave <<
" with up to"
2289 << setw(3) << nJetMaxSave <<
" additional jets |\n";
2291 if ( doKTMergingSave )
2292 cout <<
" | Merging scale is defined in kT, with value ktMS = "
2293 << tmsValueSave <<
" GeV";
2294 else if ( doMGMergingSave )
2295 cout <<
" | Perform automanted MG/ME merging \n"
2296 <<
" | Merging scale is defined in kT, with value ktMS = "
2297 << setw(6) << fixed << setprecision(1) << tmsValueSave <<
" GeV |";
2298 else if ( doUserMergingSave )
2299 cout <<
" | Merging scale is defined by the user, with value tMS = "
2300 << setw(6) << fixed << setprecision(1) << tmsValueSave <<
" |";
2301 else if ( doPTLundMergingSave )
2302 cout <<
" | Merging scale is defined by Lund pT, with value tMS = "
2303 << setw(6) << fixed << setprecision(1) << tmsValueSave <<
" GeV |";
2304 else if ( doCutBasedMergingSave )
2305 cout <<
" | Merging scale is defined by combination of Delta R_{ij}, pT_i "
2307 <<
" | and Q_{ij} cut, with values "
2309 <<
" | Delta R_{ij,min} = "
2310 << setw(7) << scientific << setprecision(2) << tmsListSave[0]
2312 <<
" | pT_{i,min} = "
2313 << setw(6) << fixed << setprecision(1) << tmsListSave[1]
2315 <<
" | Q_{ij,min} = "
2316 << setw(6) << fixed << setprecision(1) << tmsListSave[2]
2318 else if ( doNL3TreeSave )
2319 cout <<
" | Generate tree-level O(alpha_s)-subtracted events "
2321 <<
" | Merging scale is defined by Lund pT, with value tMS = "
2322 << setw(6) << fixed << setprecision(1) << tmsValueSave <<
" GeV |";
2323 else if ( doNL3LoopSave )
2324 cout <<
" | Generate virtual correction unit-weight events "
2326 <<
" | Merging scale is defined by Lund pT, with value tMS = "
2327 << setw(6) << fixed << setprecision(1) << tmsValueSave <<
" GeV |";
2328 else if ( doNL3SubtSave )
2329 cout <<
" | Generate reclustered tree-level events "
2331 <<
" | Merging scale is defined by Lund pT, with value tMS = "
2332 << setw(6) << fixed << setprecision(1) << tmsValueSave <<
" GeV |";
2333 else if ( doUNLOPSTreeSave )
2334 cout <<
" | Generate tree-level O(alpha_s)-subtracted events "
2336 <<
" | Merging scale is defined by Lund pT, with value tMS = "
2337 << setw(6) << fixed << setprecision(1) << tmsValueSave <<
" GeV |";
2338 else if ( doUNLOPSLoopSave )
2339 cout <<
" | Generate virtual correction unit-weight events "
2341 <<
" | Merging scale is defined by Lund pT, with value tMS = "
2342 << setw(6) << fixed << setprecision(1) << tmsValueSave <<
" GeV |";
2343 else if ( doUNLOPSSubtSave )
2344 cout <<
" | Generate reclustered tree-level events "
2346 <<
" | Merging scale is defined by Lund pT, with value tMS = "
2347 << setw(6) << fixed << setprecision(1) << tmsValueSave <<
" GeV |";
2348 else if ( doUNLOPSSubtNLOSave )
2349 cout <<
" | Generate reclustered loop-level events "
2351 <<
" | Merging scale is defined by Lund pT, with value tMS = "
2352 << setw(6) << fixed << setprecision(1) << tmsValueSave <<
" GeV |";
2353 else if ( doUMEPSTreeSave )
2354 cout <<
" | Generate tree-level events "
2356 <<
" | Merging scale is defined by Lund pT, with value tMS = "
2357 << setw(6) << fixed << setprecision(1) << tmsValueSave <<
" GeV |";
2358 else if ( doUMEPSSubtSave )
2359 cout <<
" | Generate reclustered tree-level events "
2361 <<
" | Merging scale is defined by Lund pT, with value tMS = "
2362 << setw(6) << fixed << setprecision(1) << tmsValueSave <<
" GeV |";
2366 cout <<
"\n *-------------- END MEPS Merging Initialization ---------------"
2375 bool MergingHooks::doVetoEmission(
const Event& event) {
2378 if ( doIgnoreEmissionsSave )
return false;
2381 if ( doUserMerging() || doMGMerging() || doKTMerging()
2382 || doPTLundMerging() || doCutBasedMerging() )
2388 int nSteps = getNumberOfClusteringSteps(event);
2390 double tnow = tmsNow( event);
2393 int nJetMax = nMaxJets();
2396 if ( nRecluster() > 0 ) nSteps = max(1, min(nJetMax-2, 1));
2398 if ( nSteps - 1 < nJetMax && nSteps >= 1 && tnow > tms() ) veto =
true;
2401 if ( infoPtr->nMPI() > 1 ) veto =
false;
2405 if ( veto && doNL3Tree() ) setWeightCKKWL(0.);
2408 if ( !veto ) doIgnoreEmissionsSave =
true;
2419 bool MergingHooks::doVetoStep(
const Event& process,
const Event& event,
2420 bool doResonance ) {
2423 if ( doIgnoreStepSave && !doResonance )
return false;
2426 if ( doUMEPSTree() || doUMEPSSubt() || doUMEPSMerging() || doUNLOPSTree()
2427 || doUNLOPSLoop() || doUNLOPSSubt() || doUNLOPSSubtNLO()
2428 || doUNLOPSMerging() )
2434 if ( getProcessString().find(
"inc") != string::npos )
2435 nSteps = getNumberOfClusteringSteps( bareEvent( process,
false) );
2436 else nSteps = (doResonance) ? getNumberOfClusteringSteps(process)
2437 : getNumberOfClusteringSteps( bareEvent( process,
false) );
2439 int nStepsAfter = getNumberOfClusteringSteps(event);
2442 int nJetMax = nMaxJets();
2444 double tnow = tmsNow( event );
2450 if ( !doResonance ) {
2453 pTsave = infoPtr->pTnow();
2454 if ( nRecluster() == 1) nSteps--;
2458 setEventVetoInfo(nSteps, tnow);
2464 if ( nStepsAfter > nSteps && nSteps > nMaxJetsNLO() && nSteps < nJetMax
2467 weightCKKWL1Save = 0.;
2469 weightCKKWL2Save = getWeightCKKWL();
2471 if ( !includeWGTinXSEC() ) setWeightCKKWL(0.);
2472 if ( includeWGTinXSEC() ) infoPtr->updateWeight(0.);
2487 bool revokeVeto =
false;
2493 bool check = (nHardInLeptons() == 0)&& (nHardOutLeptons() == 2)
2494 && (nHardOutPartons() == 2);
2502 if ( pTsave > 0. && check ) {
2505 int nResNow = nResInCurrent();
2512 int sysSize = partonSystemsPtr->sizeSys();
2513 for (
int i=0; i < nResNow; ++i ) {
2514 if ( partonSystemsPtr->sizeOut(sysSize - 1 - i) == 3 )
2515 goodSys.push_back(sysSize - 1 - i);
2519 for (
int i=0; i < int(goodSys.size()); ++i ) {
2522 int iMem1 = partonSystemsPtr->getOut(goodSys[i],0);
2523 int iMem2 = partonSystemsPtr->getOut(goodSys[i],1);
2524 int iMem3 = partonSystemsPtr->getOut(goodSys[i],2);
2527 int iEmtGlue = ((
event[iMem1].id() == 21) ? iMem1
2528 : ((event[iMem2].
id() == 21) ? iMem2
2529 : ((
event[iMem3].id() == 21) ? iMem3: 0)));
2530 int iEmtGamm = ((
event[iMem1].id() == 22) ? iMem1
2531 : ((event[iMem2].
id() == 22) ? iMem2
2532 : ((
event[iMem3].id() == 22) ? iMem3: 0)));
2534 int iEmt = (iEmtGlue != 0) ? iEmtGlue : iEmtGamm;
2538 if ( iEmt == iMem1 ) {
2539 iRad = (
event[iMem2].mother1() !=
event[iMem2].mother2())
2541 iRec = (
event[iMem3].mother1() ==
event[iMem3].mother2())
2543 }
else if ( iEmt == iMem2 ) {
2544 iRad = (
event[iMem1].mother1() !=
event[iMem1].mother2())
2546 iRec = (
event[iMem3].mother1() ==
event[iMem3].mother2())
2549 iRad = (
event[iMem1].mother1() !=
event[iMem1].mother2())
2551 iRec = (
event[iMem2].mother1() ==
event[iMem2].mother2())
2555 double pTres = rhoPythia(event, iRad, iEmt, iRec, 1);
2560 if ( pTres > pTsave ) {
2574 if ( revokeVeto && check ) {
2575 setWeightCKKWL(weightCKKWL2Save);
2576 }
else if ( check ) {
2577 setWeightCKKWL(weightCKKWL1Save);
2578 if ( weightCKKWL1Save == 0. ) veto =
true;
2582 if ( !check && nSteps > nMaxJetsNLO() && nSteps < nJetMax && tnow > tms()){
2584 if ( !includeWGTinXSEC() ) setWeightCKKWL(0.);
2585 if ( includeWGTinXSEC() ) infoPtr->updateWeight(0.);
2591 if ( !veto || !doIgnoreStepSave ) doIgnoreStepSave =
true;
2607 Event MergingHooks::bareEvent(
const Event& inputEventIn,
2608 bool storeInputEvent ) {
2612 newProcess.init(
"(hard process-modified)", particleDataPtr);
2615 if ( storeInputEvent ) {
2616 resonances.resize(0);
2618 for (
int i = 0; i < inputEventIn.size(); ++i)
2619 inputEvent.append( inputEventIn[i] );
2620 for (
int i = 0; i < inputEventIn.sizeJunction(); ++i)
2621 inputEvent.appendJunction( inputEventIn.getJunction(i) );
2622 inputEvent.saveSize();
2623 inputEvent.saveJunctionSize();
2627 if ( doRemoveDecayProducts ) {
2630 for (
int i = 0; i < inputEventIn.size(); ++ i) {
2631 if ( inputEventIn[i].mother1() > 4
2632 || inputEventIn[i].statusAbs() == 22
2633 || inputEventIn[i].statusAbs() == 23)
2635 newProcess.append(inputEventIn[i]);
2639 for (
int i = 0; i < inputEventIn.size(); ++ i) {
2640 if (inputEventIn[i].mother1() > 4)
break;
2641 if ( inputEventIn[i].status() == -22) {
2642 int j = newProcess.append(inputEventIn[i]);
2643 newProcess[j].statusPos();
2644 if ( storeInputEvent ) resonances.push_back( make_pair(j, i) );
2645 newProcess[j].daughters(0, 0);
2650 for (
int i = 0; i < inputEventIn.size(); ++ i) {
2651 if (inputEventIn[i].mother1() > 4)
break;
2652 if ( inputEventIn[i].statusAbs() != 11
2653 && inputEventIn[i].statusAbs() != 12
2654 && inputEventIn[i].statusAbs() != 21
2655 && inputEventIn[i].statusAbs() != 22)
2656 newProcess.append(inputEventIn[i]);
2661 for (
int i = 0; i < inputEventIn.size(); ++ i) {
2662 if ( inputEventIn[i].col() > maxColTag )
2663 maxColTag = inputEventIn[i].col();
2664 if ( inputEventIn[i].acol() > maxColTag )
2665 maxColTag = inputEventIn[i].acol();
2667 newProcess.initColTag(maxColTag);
2670 for (
int i = 0; i < inputEventIn.sizeJunction(); ++i)
2671 newProcess.appendJunction( inputEventIn.getJunction(i));
2673 newProcess.saveSize();
2674 newProcess.saveJunctionSize();
2677 newProcess = inputEventIn;
2681 newProcess.scale( inputEventIn.scale() );
2693 bool MergingHooks::reattachResonanceDecays(
Event& process ) {
2696 if ( doRemoveDecayProducts && inputEvent.size() > 0 ) {
2698 int sizeBef = process.size();
2700 vector<int> iAftChecked;
2702 for (
int i = 0; i < int(resonances.size()); ++i ) {
2703 for (
int j = 0; j < sizeBef; ++j ) {
2704 if ( j != resonances[i].first )
continue;
2706 int iOldDaughter1 = inputEvent[resonances[i].second].daughter1();
2707 int iOldDaughter2 = inputEvent[resonances[i].second].daughter2();
2710 int iHardMother = resonances[i].second;
2711 Particle& hardMother = inputEvent[iHardMother];
2714 for (
int k = 0; k < process.size(); ++k )
2715 if ( process[k].
id() == inputEvent[resonances[i].second].id() ) {
2717 bool checked =
false;
2718 for (
int l = 0; l < int(iAftChecked.size()); ++l )
2719 if ( k == iAftChecked[l] )
2722 iAftChecked.push_back(k);
2728 Particle& aftMother = process[iAftMother];
2732 int colBef = hardMother.col();
2733 int acolBef = hardMother.acol();
2734 int colAft = aftMother.col();
2735 int acolAft = aftMother.acol();
2737 M.bst( hardMother.p(), aftMother.p());
2740 int iNewDaughter1 = 0;
2741 int iNewDaughter2 = 0;
2742 for (
int k = iOldDaughter1; k <= iOldDaughter2; ++k ) {
2743 if ( k == iOldDaughter1 )
2744 iNewDaughter1 = process.append(inputEvent[k] );
2746 iNewDaughter2 = process.append(inputEvent[k] );
2747 process.back().statusPos();
2748 Particle& now = process.back();
2750 if (now.col() != 0 && now.col() == colBef ) now.col(colAft);
2751 if (now.acol() != 0 && now.acol() == acolBef) now.acol(acolAft);
2754 if (now.hasVertex()) now.vProd( aftMother.vDec() );
2756 now.mothers(iAftMother,0);
2759 process[iAftMother].daughters( iNewDaughter1, iNewDaughter2 );
2760 process[iAftMother].statusNeg();
2765 if ( process[iDec].isFinal() && process[iDec].canDecay()
2766 && process[iDec].mayDecay() && process[iDec].isResonance() ) {
2768 int iD1 = process[iDec].daughter1();
2769 int iD2 = process[iDec].daughter2();
2772 if ( iD1 == 0 || iD2 == 0 )
continue;
2775 int iNewDaughter12 = 0;
2776 int iNewDaughter22 = 0;
2777 for (
int k = iD1; k <= iD2; ++k ) {
2779 iNewDaughter12 = process.append(inputEvent[k] );
2781 iNewDaughter22 = process.append(inputEvent[k] );
2782 process.back().statusPos();
2783 Particle& now = process.back();
2785 if (now.col() != 0 && now.col() == colBef ) now.col(colAft);
2786 if (now.acol()!= 0 && now.acol()== acolBef) now.acol(acolAft);
2789 if (now.hasVertex()) now.vProd( process[iDec].vDec() );
2791 now.mothers(iDec,0);
2795 process[iDec].status(-22);
2796 process[iDec].daughters(iNewDaughter12, iNewDaughter22);
2800 }
while (++iDec < process.size());
2806 for (
int i = 0; i < process.size(); ++ i) {
2807 if (process[i].col() > maxColTag) maxColTag = process[i].col();
2808 if (process[i].acol() > maxColTag) maxColTag = process[i].acol();
2810 process.initColTag(maxColTag);
2815 return (doRemoveDecayProducts) ? inputEvent.size() > 0 :
true;
2821 bool MergingHooks::isInHard(
int iPos,
const Event& event){
2824 if ( event[iPos].statusAbs() > 30 && event[iPos].statusAbs() < 40 )
2827 if ( event[iPos].statusAbs() > 60 )
2832 vector<int> mpiParticlePos;
2833 mpiParticlePos.clear();
2834 for (
int i=0; i <
event.size(); ++i )
2835 if ( event[i].statusAbs() > 30
2836 &&
event[i].statusAbs() < 40 )
2837 mpiParticlePos.push_back(i);
2839 for (
int i=0; i < int(mpiParticlePos.size()); ++i)
2840 if ( event[iPos].isAncestor( mpiParticlePos[i]) )
2845 int iSys = partonSystemsPtr->getSystemOf(iPos, !event[iPos].isFinal() );
2850 int sysSize = partonSystemsPtr->sizeAll(iSys);
2851 for (
int i = 0; i < sysSize; ++i ) {
2852 int iPosNow = partonSystemsPtr->getAll( iSys, i );
2854 if ( event[iPosNow].statusAbs() > 30
2855 && event[iPosNow].statusAbs() < 40 )
2858 for (
int j=0; j < int(mpiParticlePos.size()); ++j)
2859 if ( event[iPosNow].isAncestor( mpiParticlePos[j]) )
2862 if ( event[iPosNow].statusAbs() > 60 )
2869 bool containsInitialParton =
false;
2873 if (iUp <= 0 || iUp > event.size())
break;
2875 if ( iUp == 3 || iUp == 4 ) {
2876 containsInitialParton =
true;
2879 if ( event[iUp].mother1() == 1
2880 && (
event[iUp].daughter1() == 3 ||
event[iUp].daughter2() == 3) ) {
2881 containsInitialParton =
true;
2884 if ( event[iUp].mother1() == 2
2885 && (
event[iUp].daughter1() == 4 ||
event[iUp].daughter2() == 4) ) {
2886 containsInitialParton =
true;
2890 iUp =
event[iUp].mother1();
2893 if ( !containsInitialParton )
return false;
2904 int MergingHooks::getNumberOfClusteringSteps(
const Event& event,
2908 int nFinalPartons = 0;
2909 for (
int i=0; i <
event.size(); ++i)
2910 if ( event[i].isFinal()
2911 && isInHard( i, event)
2912 && (
event[i].isQuark() ||
event[i].isGluon()) )
2916 int nFinalLeptons = 0;
2917 for(
int i=0; i <
event.size(); ++i)
2918 if ( event[i].isFinal() && isInHard( i, event) &&
event[i].isLepton())
2922 for(
int i=0; i <
event.size(); ++i)
2923 if ( event[i].isFinal() && isInHard( i, event)
2924 &&
event[i].idAbs() == 1000022)
2928 for(
int i=0; i <
event.size(); ++i)
2929 if ( event[i].isFinal() && isInHard( i, event)
2930 && (
event[i].idAbs() == 1000011
2931 ||
event[i].idAbs() == 2000011
2932 ||
event[i].idAbs() == 1000013
2933 ||
event[i].idAbs() == 2000013
2934 ||
event[i].idAbs() == 1000015
2935 ||
event[i].idAbs() == 2000015) )
2939 int nFinalBosons = 0;
2940 for(
int i=0; i <
event.size(); ++i)
2941 if ( event[i].isFinal() && isInHard( i, event)
2942 && (
event[i].idAbs() == 22
2943 ||
event[i].idAbs() == 23
2944 ||
event[i].idAbs() == 24
2945 ||
event[i].idAbs() == 25 ) )
2949 int nFinal = nFinalPartons + nFinalLeptons
2950 + 2*(nFinalBosons - nHardOutBosons() );
2953 int nsteps = nFinal - nHardOutPartons() - nHardOutLeptons();
2957 if ( getProcessString().find(
"inc") != string::npos ) {
2960 int njInc = 0, naInc = 0, nzInc = 0, nwInc =0;
2961 for (
int i=0; i <
event.size(); ++i){
2962 if ( event[i].isFinal() &&
event[i].colType() != 0 ) njInc++;
2963 if ( getProcessString().find(
"Ainc") != string::npos
2964 &&
event[i].isFinal() &&
event[i].idAbs() == 22 ) naInc++;
2965 if ( getProcessString().find(
"Zinc") != string::npos
2966 &&
event[i].isFinal() &&
event[i].idAbs() == 23 ) nzInc++;
2967 if ( getProcessString().find(
"Winc") != string::npos
2968 &&
event[i].isFinal() &&
event[i].idAbs() == 24 ) nwInc++;
2973 if (nzInc == 0 && nwInc == 0 && njInc+naInc > 1) {
2974 nsteps = naInc + njInc - 2;
2976 hasJetMaxLocal =
true;
2977 nJetMaxLocal = nJetMaxSave - 2;
2978 nRequestedSave = nsteps;
2984 if ( nzInc > 0 || nwInc > 0 ) {
2985 nsteps = njInc + naInc + nzInc + nwInc - 1;
2987 hasJetMaxLocal =
true;
2988 nJetMaxLocal = nJetMaxSave - 1;
2989 nRequestedSave = nsteps;
3005 bool MergingHooks::isFirstEmission(
const Event& event ) {
3009 for (
int i=0; i <
event.size(); ++i)
3010 if ( event[i].statusAbs() > 60 )
return false;
3013 int nFinalQuarks = 0;
3014 int nFinalGluons = 0;
3015 int nFinalLeptons = 0;
3016 int nFinalBosons = 0;
3017 int nFinalPhotons = 0;
3019 for(
int i=0; i <
event.size(); ++i) {
3020 if (event[i].isFinal() && isInHard(i, event) ){
3021 if ( event[i].spinType() == 2 &&
event[i].colType() == 0)
3023 if ( event[i].
id() == 23
3024 ||
event[i].idAbs() == 24
3025 ||
event[i].id() == 25)
3027 if ( event[i].
id() == 22)
3029 if ( event[i].isQuark())
3031 if ( event[i].isGluon())
3033 if ( !event[i].isDiquark() )
3040 if (nFinalQuarks + nFinalGluons == 0)
return false;
3043 int nLeptons = nHardOutLeptons();
3047 if (nFinalLeptons > nLeptons)
return false;
3052 for(
int i =0; i< int(hardProcess->hardOutgoing1.size()); ++i)
3053 if (hardProcess->hardOutgoing1[i] == 22)
3055 for(
int i =0; i< int(hardProcess->hardOutgoing2.size()); ++i)
3056 if (hardProcess->hardOutgoing2[i] == 22)
3058 if (nFinalPhotons > nPhotons)
return false;
3074 bool MergingHooks::setShowerStartingScales(
bool isTrial,
3075 bool doMergeFirstEmm,
double& pTscaleIn,
const Event& event,
3076 double& pTmaxFSRIn,
bool& limitPTmaxFSRIn,
3077 double& pTmaxISRIn,
bool& limitPTmaxISRIn,
3078 double& pTmaxMPIIn,
bool& limitPTmaxMPIIn ) {
3081 bool limitPTmaxFSR = limitPTmaxFSRIn;
3082 bool limitPTmaxISR = limitPTmaxISRIn;
3083 bool limitPTmaxMPI = limitPTmaxMPIIn;
3084 double pTmaxFSR = pTmaxFSRIn;
3085 double pTmaxISR = pTmaxISRIn;
3086 double pTmaxMPI = pTmaxMPIIn;
3087 double pTscale = pTscaleIn;
3095 bool isInclusive = ( getProcessString().find(
"inc") != string::npos );
3103 int nFinalPartons = 0, nInitialPartons = 0, nFinalOther = 0;
3104 for (
int i = 0; i <
event.size(); ++i ) {
3105 if ( (event[i].mother1() == 1 || event[i].mother1() == 2 )
3106 && (
event[i].idAbs() < 6 ||
event[i].id() == 21) )
3108 if (event[i].isFinal() && (
event[i].idAbs() < 6 ||
event[i].id() == 21)) {
3110 pT2to2 =
event[i].pT();
3111 }
else if ( event[i].isFinal() ) nFinalOther++;
3113 bool is2to2QCD = ( nFinalPartons == 2 && nInitialPartons == 2
3114 && nFinalOther == 0 );
3115 bool hasMPIoverlap = is2to2QCD;
3116 bool is2to1 = ( nFinalPartons == 0 );
3118 double scale =
event.scale();
3124 pTmaxISR = pTmaxFSR = pTmaxMPI = scale;
3128 if ( limitPTmaxISR && !isInclusive ) pTmaxISR = min(scale,muF());
3129 if ( limitPTmaxFSR && !isInclusive ) pTmaxFSR = min(scale,muF());
3130 if ( limitPTmaxMPI && !isInclusive ) pTmaxMPI = min(scale,muF());
3133 if ( limitPTmaxISR && isInclusive && is2to1 ) pTmaxISR = min(scale,muF());
3134 if ( limitPTmaxFSR && isInclusive && is2to1 ) pTmaxFSR = min(scale,muF());
3135 if ( limitPTmaxMPI && isInclusive && is2to1 ) pTmaxMPI = min(scale,muF());
3144 if ( hasMPIoverlap ) pTmaxMPI = infoPtr->eCM();
3147 if ( pTscale < infoPtr->eCM() ) {
3148 limitPTmaxISR = limitPTmaxFSR = limitPTmaxMPI =
true;
3150 if ( hasMPIoverlap ) limitPTmaxMPI =
false;
3156 if ( doMergeFirstEmm ) {
3159 bool doRecluster = doUMEPSSubt() || doNL3Subt() || doUNLOPSSubt()
3160 || doUNLOPSSubtNLO();
3163 pTmaxISR = pTmaxFSR = pTmaxMPI = scale;
3167 if ( limitPTmaxISR && !isInclusive ) pTmaxISR = min(scale,muF());
3168 if ( limitPTmaxFSR && !isInclusive ) pTmaxFSR = min(scale,muF());
3169 if ( limitPTmaxMPI && !isInclusive ) pTmaxMPI = min(scale,muF());
3172 if ( limitPTmaxISR && isInclusive && is2to1 ) pTmaxISR = min(scale,muF());
3173 if ( limitPTmaxFSR && isInclusive && is2to1 ) pTmaxFSR = min(scale,muF());
3174 if ( limitPTmaxMPI && isInclusive && is2to1 ) pTmaxMPI = min(scale,muF());
3183 if ( hasMPIoverlap && !doRecluster ) {
3184 pTmaxMPI = infoPtr->eCM();
3185 limitPTmaxMPI =
false;
3190 if ( doRecluster ) {
3192 limitPTmaxMPI =
true;
3197 limitPTmaxFSRIn = limitPTmaxFSR;
3198 limitPTmaxISRIn = limitPTmaxISR;
3199 limitPTmaxMPIIn = limitPTmaxMPI;
3200 pTmaxFSRIn = pTmaxFSR;
3201 pTmaxISRIn = pTmaxISR;
3202 pTmaxMPIIn = pTmaxMPI;
3203 pTscaleIn = pTscale;
3215 double MergingHooks::tmsNow(
const Event& event ) {
3220 if ( doKTMerging() || doMGMerging() )
3223 else if ( doPTLundMerging() )
3224 tnow = rhoms(event,
false);
3226 else if ( doCutBasedMerging() )
3227 tnow = cutbasedms(event);
3229 else if ( doNL3Merging() )
3230 tnow = rhoms(event,
false);
3232 else if ( doUNLOPSMerging() )
3233 tnow = rhoms(event,
false);
3235 else if ( doUMEPSMerging() )
3236 tnow = rhoms(event,
false);
3239 tnow = tmsDefinition(event);
3249 bool MergingHooks::checkAgainstCut(
const Particle& particle){
3252 if (particle.colType() == 0)
return false;
3254 if ( particle.idAbs() != 21 && particle.idAbs() > nQuarksMergeSave )
3266 double MergingHooks::kTms(
const Event& event) {
3269 if (!isFirstEmission(event))
return 0.;
3272 vector<int> ewResonancePos;
3273 ewResonancePos.clear();
3274 for (
int i=0; i <
event.size(); ++i)
3275 if ( abs(event[i].status()) == 22
3276 && (
event[i].idAbs() == 22
3277 ||
event[i].idAbs() == 23
3278 ||
event[i].idAbs() == 24
3279 ||
event[i].idAbs() == 25
3280 ||
event[i].idAbs() == 6 ) )
3281 ewResonancePos.push_back(i);
3284 vector <int> FinalPartPos;
3285 FinalPartPos.clear();
3288 for (
int i=0; i <
event.size(); ++i){
3289 if ( event[i].isFinal()
3290 && isInHard( i, event )
3291 &&
event[i].colType() != 0
3292 && checkAgainstCut(event[i]) ){
3293 bool isDecayProduct =
false;
3294 for(
int j=0; j < int(ewResonancePos.size()); ++j)
3295 if ( event[i].isAncestor( ewResonancePos[j]) )
3296 isDecayProduct =
true;
3298 if ( !isDecayProduct
3299 || getProcessString().compare(
"e+e->jj") == 0
3300 || getProcessString().compare(
"e+e->(z>jj)") == 0 )
3301 FinalPartPos.push_back(i);
3307 int type = (
event[3].colType() == 0
3308 &&
event[4].colType() == 0) ? -1 : ktTypeSave;
3310 double ktmin =
event[0].e();
3311 for(
int i=0; i < int(FinalPartPos.size()); ++i){
3312 double kt12 = ktmin;
3314 if (type == 1 || type == 2) {
3315 double temp =
event[FinalPartPos[i]].pT();
3316 kt12 = min(kt12, temp);
3319 for(
int j=i+1; j < int(FinalPartPos.size()); ++j) {
3320 double temp = kTdurham( event[FinalPartPos[i]], event[FinalPartPos[j]],
3321 type, DparameterSave);
3322 kt12 = min(kt12, temp);
3325 ktmin = min(ktmin,kt12);
3337 double MergingHooks::kTdurham(
const Particle& RadAfterBranch,
3338 const Particle& EmtAfterBranch,
int Type,
double D ){
3343 Vec4 jet1 = RadAfterBranch.p();
3344 Vec4 jet2 = EmtAfterBranch.p();
3350 if (jet1.pAbs()*jet2.pAbs() <=0.) costh = 1.;
3352 costh = costheta(jet1,jet2);
3355 ktdur = 2.0*min( pow(jet1.e(),2) , (pow(jet2.e(),2)) )*(1.0 - costh);
3356 }
else if ( Type == 1 ){
3359 double mT1sq = jet1.m2Calc() + jet1.pT2();
3361 if (mT1sq < 0) mT1 = - sqrt(-mT1sq);
3362 else mT1 = sqrt(mT1sq);
3364 double mT2sq = jet2.m2Calc() + jet2.pT2();
3366 if (mT2sq < 0) mT2 = - sqrt(-mT2sq);
3367 else mT2 = sqrt(mT2sq);
3369 double y1 = log( ( jet1.e() + abs(jet1.pz()) ) / mT1 );
3370 if (jet1.pz() < 0) y1 *= -1.;
3372 double y2 = log( ( jet2.e() + abs(jet2.pz()) ) / mT2 );
3373 if (jet2.pz() < 0) y2 *= -1.;
3375 double pt1 = sqrt( pow(jet1.px(),2) + pow(jet1.py(),2) );
3376 double pt2 = sqrt( pow(jet2.px(),2) + pow(jet2.py(),2) );
3377 double cosdPhi = ( jet1.px()*jet2.px() + jet1.py()*jet2.py() ) / (pt1*pt2);
3378 double dPhi = acos( cosdPhi );
3381 ktdur = min( pow(pt1,2),pow(pt2,2) )
3382 * ( pow(y1-y2,2) + pow(dPhi,2) ) / pow(D,2);
3383 }
else if ( Type == 2 ){
3386 double mT1sq = jet1.m2Calc() + jet1.pT2();
3388 if (mT1sq < 0) mT1 = - sqrt(-mT1sq);
3389 else mT1 = sqrt(mT1sq);
3391 double mT2sq = jet2.m2Calc() + jet2.pT2();
3393 if (mT2sq < 0) mT2 = - sqrt(-mT2sq);
3394 else mT2 = sqrt(mT2sq);
3396 double eta1 = log( ( sqrt(jet1.px()*jet1.px() + jet1.py()*jet1.py()
3397 + jet1.pz()*jet1.pz()) + abs(jet1.pz()) ) / mT1);
3398 if (jet1.pz() < 0) eta1 *= -1.;
3400 double eta2 = log( ( sqrt(jet2.px()*jet2.px() + jet2.py()*jet2.py()
3401 + jet2.pz()*jet2.pz()) + abs(jet2.pz()) ) / mT2);
3402 if (jet2.pz() < 0) eta2 *= -1.;
3405 double pt1 = sqrt( pow(jet1.px(),2) + pow(jet1.py(),2) );
3406 double pt2 = sqrt( pow(jet2.px(),2) + pow(jet2.py(),2) );
3407 double cosdPhi = ( jet1.px()*jet2.px() + jet1.py()*jet2.py() ) / (pt1*pt2);
3408 double dPhi = acos( cosdPhi );
3410 ktdur = min( pow(pt1,2),pow(pt2,2) )
3411 * ( pow(eta1-eta2,2) + pow(dPhi,2) ) / pow(D,2);
3412 }
else if ( Type == 3 ){
3414 double eta1 = 0.5*log( (jet1.e() + jet1.pz()) / (jet1.e() - jet1.pz()) );
3415 double eta2 = 0.5*log( (jet2.e() + jet2.pz()) / (jet2.e() - jet2.pz()) );
3416 double coshdEta = cosh( eta1 - eta2 );
3418 double pt1 = sqrt( pow(jet1.px(),2) + pow(jet1.py(),2) );
3419 double pt2 = sqrt( pow(jet2.px(),2) + pow(jet2.py(),2) );
3420 double cosdPhi = ( jet1.px()*jet2.px() + jet1.py()*jet2.py() ) / (pt1*pt2);
3422 ktdur = 2.0*min( pow(pt1,2),pow(pt2,2) )
3423 * ( coshdEta - cosdPhi ) / pow(D,2);
3437 double MergingHooks::rhoms(
const Event& event,
bool withColour){
3440 if (!isFirstEmission(event))
return 0.;
3442 if ( useShowerPlugin() ) {
3443 double ptret=
event[0].e();
3444 for(
int i=0; i <
event.size(); ++i) {
3445 for(
int j=0; j <
event.size(); ++j) {
3447 double temp = rhoPythia( event, i, j, 0, 0 );
3448 if (temp > 0.) ptret = min(ptret, temp);
3455 vector<int> ewResonancePos;
3456 ewResonancePos.clear();
3457 for (
int i=0; i <
event.size(); ++i)
3458 if ( abs(event[i].status()) == 22
3459 && (
event[i].idAbs() == 22
3460 ||
event[i].idAbs() == 23
3461 ||
event[i].idAbs() == 24
3462 ||
event[i].idAbs() == 25
3463 ||
event[i].idAbs() == 6 ) )
3464 ewResonancePos.push_back(i);
3467 vector <int> FinalPartPos;
3468 FinalPartPos.clear();
3471 for (
int i=0; i <
event.size(); ++i){
3473 if ( event[i].isFinal()
3474 && isInHard( i, event )
3475 &&
event[i].colType() != 0
3476 && checkAgainstCut(event[i]) ){
3477 bool isDecayProduct =
false;
3478 for(
int j=0; j < int(ewResonancePos.size()); ++j)
3479 if ( event[i].isAncestor( ewResonancePos[j]) )
3480 isDecayProduct =
true;
3482 if ( !isDecayProduct
3483 || getProcessString().compare(
"e+e->jj") == 0
3484 || getProcessString().compare(
"e+e->(z>jj)") == 0 )
3485 FinalPartPos.push_back(i);
3489 if ( getProcessString().find(
"Ainc") != string::npos
3490 && event[i].isFinal() && event[i].idAbs() == 22 )
3491 FinalPartPos.push_back(i);
3493 if ( getProcessString().find(
"Zinc") != string::npos
3494 && event[i].isFinal() && event[i].idAbs() == 23 )
3495 FinalPartPos.push_back(i);
3497 if ( getProcessString().find(
"Winc") != string::npos
3498 && event[i].isFinal() && event[i].idAbs() == 24 )
3499 FinalPartPos.push_back(i);
3504 for (
int i=0; i <
event.size(); ++i)
3505 if (abs(event[i].status()) == 41 ){
3512 for (
int i=0; i <
event.size(); ++i)
3513 if (abs(event[i].status()) == 42 ){
3519 if (in1 == 0 || in2 == 0){
3521 for(
int i=3; i < int(event.size()); ++i){
3522 if ( !isInHard( i, event ) )
continue;
3523 if (event[i].mother1() == 1) in1 = i;
3524 if (event[i].mother1() == 2) in2 = i;
3528 int nInitialPartons = 0, nFinalOther = 0;
3529 for (
int i = 0; i <
event.size(); ++i ) {
3530 if ( (event[i].mother1() == 1 || event[i].mother1() == 2 )
3531 && (
event[i].idAbs() < 6 ||
event[i].id() == 21) )
3533 if (event[i].isFinal() &&
event[i].idAbs() >= 6 &&
event[i].id() != 21)
3536 bool is2to2QCD = ( int(FinalPartPos.size()) == 2 && nInitialPartons == 2
3537 && nFinalOther == 0 );
3541 double pt12 = min(event[FinalPartPos[0]].pT(),
3542 event[FinalPartPos[1]].pT());
3547 double ptmin =
event[0].e();
3548 for(
int i=0; i < int(FinalPartPos.size()); ++i){
3550 double pt12 = ptmin;
3552 if (event[in1].colType() != 0) {
3553 double temp = rhoPythia( event, in1, FinalPartPos[i], in2, -1 );
3554 pt12 = min(pt12, temp);
3558 if ( event[in2].colType() != 0) {
3559 double temp = rhoPythia( event, in2, FinalPartPos[i], in1, -1 );
3560 pt12 = min(pt12, temp);
3566 for(
int j=0; j < int(FinalPartPos.size()); ++j) {
3570 bool isHard =
false;
3571 int radAcl =
event[FinalPartPos[i]].acol();
3572 int radCol =
event[FinalPartPos[i]].col();
3573 int emtAcl =
event[FinalPartPos[j]].acol();
3574 int emtCol =
event[FinalPartPos[j]].col();
3577 if (iRec <= 0 && radAcl > 0 && radAcl != emtCol)
3578 iRec = findColour(radAcl, FinalPartPos[i], FinalPartPos[j],
3580 if (iRec <= 0 && radCol > 0 && radCol != emtAcl)
3581 iRec = findColour(radCol, FinalPartPos[i], FinalPartPos[j],
3583 if (iRec <= 0 && emtAcl > 0 && emtAcl != radCol)
3584 iRec = findColour(emtAcl, FinalPartPos[i], FinalPartPos[j],
3586 if (iRec <= 0 && emtCol > 0 && emtCol != radAcl)
3587 iRec = findColour(emtCol, FinalPartPos[i], FinalPartPos[j],
3591 if (iRec <= 0 && radAcl > 0 && radAcl != emtCol)
3592 iRec = findColour(radAcl, FinalPartPos[i], FinalPartPos[j],
3594 if (iRec <= 0 && radCol > 0 && radCol != emtAcl)
3595 iRec = findColour(radCol, FinalPartPos[i], FinalPartPos[j],
3597 if (iRec <= 0 && emtAcl > 0 && emtAcl != radCol)
3598 iRec = findColour(emtAcl, FinalPartPos[i], FinalPartPos[j],
3600 if (iRec <= 0 && emtCol > 0 && emtCol != radAcl)
3601 iRec = findColour(emtCol, FinalPartPos[i], FinalPartPos[j],
3605 double temp = rhoPythia( event, FinalPartPos[i], FinalPartPos[j],
3607 pt12 = min(pt12, temp);
3615 for(
int j=0; j < int(FinalPartPos.size()); ++j) {
3616 for(
int k=0; k < int(FinalPartPos.size()); ++k) {
3618 if ( (i != j) && (i != k) && (j != k) ){
3623 temp = rhoPythia( event, FinalPartPos[i], FinalPartPos[j],
3624 FinalPartPos[k], 1 );
3625 pt12 = min(pt12, temp);
3626 temp = rhoPythia( event, FinalPartPos[j], FinalPartPos[i],
3627 FinalPartPos[k], 1 );
3628 pt12 = min(pt12, temp);
3635 if ( event[in1].colType() != 0 && event[in2].colType() != 0) {
3636 for(
int j=0; j < int(FinalPartPos.size()); ++j) {
3642 if (event[in1].colType() != 0)
3643 temp = rhoPythia( event, FinalPartPos[i],FinalPartPos[j],in1, 1);
3644 pt12 = min(pt12, temp);
3646 if (event[in2].colType() != 0)
3647 temp = rhoPythia( event, FinalPartPos[i],FinalPartPos[j],in2, 1);
3648 pt12 = min(pt12, temp);
3655 ptmin = min(ptmin,pt12);
3667 double MergingHooks::rhoPythia(
const Event& event,
int rad,
int emt,
int rec,
3670 Particle RadAfterBranch =
event[rad];
3671 Particle EmtAfterBranch =
event[emt];
3672 Particle RecAfterBranch =
event[rec];
3676 if ( useShowerPlugin() ) {
3677 map<string,double> stateVars;
3678 double ptret =
event[0].m();
3679 bool isFSR = showers->timesPtr->allowedSplitting(event, rad, emt);
3680 bool isISR = showers->spacePtr->allowedSplitting(event, rad, emt);
3682 vector<string> names
3683 = showers->timesPtr->getSplittingName(event, rad, emt, 0);
3684 for (
int iName=0; iName < int(names.size()); ++iName) {
3686 = showers->timesPtr->getRecoilers(event, rad, emt, names[iName]);
3687 for (
int i = 0; i < int(recsNow.size()); ++i ) {
3688 stateVars = showers->timesPtr->getStateVariables(event, rad, emt,
3689 recsNow[i], names[iName]);
3690 double pttemp = ptret;
3691 if (stateVars.size() > 0 && stateVars.find(
"t") != stateVars.end())
3692 pttemp = sqrt(stateVars[
"t"]);
3693 ptret = min(ptret,pttemp);
3699 vector<string> names
3700 = showers->spacePtr->getSplittingName(event, rad, emt, 0);
3701 for (
int iName=0; iName < int(names.size()); ++iName) {
3703 = showers->timesPtr->getRecoilers(event, rad, emt, names[iName]);
3704 for (
int i = 0; i < int(recsNow.size()); ++i ) {
3705 stateVars = showers->spacePtr->getStateVariables(event, rad, emt,
3706 recsNow[i], names[iName]);
3707 double pttemp = ptret;
3708 if (stateVars.size() > 0 && stateVars.find(
"t") != stateVars.end())
3709 pttemp = sqrt(stateVars[
"t"]);
3710 ptret = min(ptret,pttemp);
3724 bool allowed =
true;
3727 int Type = ShowerType;
3730 double m0u = 0.0, m0d = 0.0, m0c = 1.5, m0s = 0.0, m0t = 172.5,
3731 m0b = 4.7, m0w = 80.4, m0z = 91.188, m0x = 1000.0;
3732 if (
false) cout << m0u*m0d*m0c*m0s*m0t*m0b*m0w*m0z*m0x;
3735 int sign = (Type==1) ? 1 : -1;
3736 Vec4 Q(RadAfterBranch.p() + sign*EmtAfterBranch.p());
3737 double Qsq = sign * Q.m2Calc();
3740 if ( Qsq < 0.0 ) allowed =
false;
3743 Vec4 radAft(RadAfterBranch.p());
3744 Vec4 recAft(RecAfterBranch.p());
3745 Vec4 emtAft(EmtAfterBranch.p());
3749 int flavEmt = EmtAfterBranch.id();
3750 int flavRad = RadAfterBranch.id();
3752 if (abs(flavEmt) == 21 || abs(flavEmt) == 22 ) idRadBef=flavRad;
3754 if (Type == 1 && flavEmt == -flavRad) idRadBef=21;
3756 if (Type == 1 && abs(flavEmt) < 10 && flavRad == 21) idRadBef=flavEmt;
3758 if (Type == -1 && abs(flavEmt) < 10 && flavRad == 21) idRadBef=-flavEmt;
3760 if (Type == -1 && abs(flavEmt) < 10 && flavRad == flavEmt) idRadBef=21;
3762 if (flavEmt == 24) idRadBef = RadAfterBranch.id()+1;
3763 if (flavEmt == -24) idRadBef = RadAfterBranch.id()-1;
3766 double m2RadAft = radAft.m2Calc();
3767 double m2EmtAft = emtAft.m2Calc();
3768 double m2RadBef = 0.;
3769 if ( RadAfterBranch.idAbs() != 21 && RadAfterBranch.idAbs() != 22
3770 && EmtAfterBranch.idAbs() != 24
3771 && RadAfterBranch.idAbs() != EmtAfterBranch.idAbs() )
3772 m2RadBef = m2RadAft;
3773 else if (EmtAfterBranch.idAbs() == 24) {
3774 if (idRadBef != 0) {
3775 if( abs(idRadBef) == 4 ) m2RadBef = pow(m0c,2);
3776 if( abs(idRadBef) == 5 ) m2RadBef = pow(m0b,2);
3777 if( abs(idRadBef) == 6 ) m2RadBef = pow(m0t,2);
3778 if( abs(idRadBef) == 9000001 ) m2RadBef = pow(m0x,2);
3780 }
else if (!RadAfterBranch.isFinal()) {
3781 if (RadAfterBranch.idAbs() == 21 && EmtAfterBranch.idAbs() != 21)
3782 m2RadBef = m2EmtAft;
3785 double m2Final = (radAft + recAft + emtAft).m2Calc();
3787 if (m2Final < 0.0) allowed =
false;
3790 if ( !RecAfterBranch.isFinal() && RadAfterBranch.isFinal() ){
3791 double mar2 = m2Final - 2. * Qsq + 2. * m2RadBef;
3792 double rescale = (1. - (Qsq - m2RadBef)/(mar2 - m2RadBef))
3793 /(1. + (Qsq - m2RadBef)/(mar2 - m2RadBef));
3795 if (rescale < 0.0) allowed =
false;
3799 Vec4 sum = radAft + recAft + emtAft;
3800 double m2Dip = sum.m2Calc();
3801 double x1 = 2. * (sum * radAft) / m2Dip;
3802 double x2 = 2. * (sum * recAft) / m2Dip;
3805 if ( RadAfterBranch.isFinal()
3806 && ( x1 < 0.0 || x1 > 1.0 || x2 < 0.0 || x2 > 1.0)) allowed =
false;
3809 Vec4 qBR(RadAfterBranch.p() - EmtAfterBranch.p() + RecAfterBranch.p());
3810 Vec4 qAR(RadAfterBranch.p() + RecAfterBranch.p());
3813 double lambda13 = sqrt( pow2(Qsq - m2RadAft - m2EmtAft )
3814 - 4. * m2RadAft*m2EmtAft );
3815 double k1 = ( Qsq - lambda13 + (m2EmtAft - m2RadAft ) ) / ( 2. * Qsq );
3816 double k3 = ( Qsq - lambda13 - (m2EmtAft - m2RadAft ) ) / ( 2. * Qsq );
3819 double z = (Type==1) ? 1./ ( 1- k1 -k3) * ( x1 / (2.-x2) - k3)
3820 : (qBR.m2Calc())/( qAR.m2Calc());
3823 if ( z < 0.0 || z > 1.0) allowed =
false;
3826 double pTpyth = (Type==1) ? z*(1.-z) : (1.-z);
3829 if (Type == 1) pTpyth *= (Qsq - m2RadBef);
3835 if ( ( RadAfterBranch.idAbs() == 4 || EmtAfterBranch.idAbs() == 4)
3836 && RadAfterBranch.idAbs() != EmtAfterBranch.idAbs() ) {
3837 if (pTpyth < 2 * pow(m0c,2)) pTpyth = (Qsq + pow(m0c,2)) * (1. - z);
3838 }
else if ( (RadAfterBranch.idAbs() == 5 || EmtAfterBranch.idAbs() == 5)
3839 && RadAfterBranch.idAbs() != EmtAfterBranch.idAbs() ) {
3840 if (pTpyth < 2 * pow(m0b,2))
3841 pTpyth = (Qsq + pow(m0b,2) ) * (1. - z);
3847 if (!allowed) pTpyth = 1e15;
3849 if ( pTpyth < 0. ) pTpyth = 0.;
3852 return sqrt(pTpyth);
3873 int MergingHooks::findColour(
int col,
int iExclude1,
int iExclude2,
3874 const Event& event,
int type,
bool isHardIn){
3876 bool isHard = isHardIn;
3881 for(
int n = 0; n <
event.size(); ++n) {
3882 if ( n != iExclude1 && n != iExclude2
3883 && event[n].colType() != 0
3884 &&(
event[n].status() > 0
3885 ||
event[n].status() == -21) ) {
3886 if ( event[n].acol() == col ) {
3890 if ( event[n].col() == col ){
3899 for(
int n = 0; n <
event.size(); ++n) {
3900 if ( n != iExclude1 && n != iExclude2
3901 && event[n].colType() != 0
3902 &&(
event[n].status() == 43
3903 ||
event[n].status() == 51
3904 ||
event[n].status() == 52
3905 ||
event[n].status() == -41
3906 ||
event[n].status() == -42) ) {
3907 if ( event[n].acol() == col ) {
3911 if ( event[n].col() == col ){
3919 if ( type == 1 && index < 0)
return abs(index);
3920 if ( type == 2 && index > 0)
return abs(index);
3930 double MergingHooks::cutbasedms(
const Event& event ){
3933 if (!isFirstEmission(event))
return -1.;
3936 vector<int> partons;
3937 for(
int i=0; i <
event.size(); ++i) {
3938 if ( event[i].isFinal()
3939 && isInHard( i, event )
3940 && checkAgainstCut(event[i]) )
3941 partons.push_back(i);
3945 bool doVeto =
false;
3947 bool vetoPT =
false;
3948 bool vetoRjj =
false;
3949 bool vetoMjj =
false;
3951 double pTjmin = pTiMS();
3952 double mjjmin = QijMS();
3953 double rjjmin = dRijMS();
3956 double minPT =
event[0].e();
3957 double minRJJ = 10.;
3958 double minMJJ =
event[0].e();
3961 for(
int i=0; i < int(partons.size()); ++i){
3963 minPT = min(minPT,event[partons[i]].pT());
3966 for(
int j=0; j < int(partons.size()); ++j){
3970 minRJJ = min(minRJJ, deltaRij( event[partons[i]].p(),
3971 event[partons[j]].p()) );
3973 minMJJ = min(minMJJ, ( event[partons[i]].p()
3974 +event[partons[j]].p() ).mCalc() );
3982 if (minPT > pTjmin) vetoPT =
true;
3983 if (minRJJ > rjjmin) vetoRjj =
true;
3984 if (minMJJ > mjjmin) vetoMjj =
true;
3991 if (
int(partons.size() == 1))
3995 doVeto = vetoPT && vetoRjj && vetoMjj;
3998 if (doVeto)
return 1.;
4009 double MergingHooks::deltaRij(Vec4 jet1, Vec4 jet2){
4014 double eta1 = 0.5*log( (jet1.e() + jet1.pz()) / (jet1.e() - jet1.pz()) );
4015 double eta2 = 0.5*log( (jet2.e() + jet2.pz()) / (jet2.e() - jet2.pz()) );
4017 double pt1 = sqrt( pow(jet1.px(),2) + pow(jet1.py(),2) );
4018 double pt2 = sqrt( pow(jet2.px(),2) + pow(jet2.py(),2) );
4019 double cosdPhi = ( jet1.px()*jet2.px() + jet1.py()*jet2.py() ) / (pt1*pt2);
4020 double dPhi = acos( cosdPhi );
4022 deltaR = sqrt(pow(eta1-eta2,2) + pow(dPhi,2));