10 #include "Pythia8/MergingHooks.h"
26 void HardProcess::initOnProcess(
string process, ParticleData* particleData) {
27 state.init(
"(hard process)", particleData);
28 translateProcessString(process);
35 void HardProcess::initOnLHEF(
string LHEfile, ParticleData* particleData) {
36 state.init(
"(hard process)", particleData);
37 translateLHEFString(LHEfile);
51 void HardProcess::translateLHEFString(
string LHEpath){
55 infile.open( (
char*)( LHEpath +
"_0.lhe").c_str());
61 while( iLine < nLinesMax
62 && lineGenerator.find(
"SHERPA", 0) == string::npos
63 && lineGenerator.find(
"POWHEG-BOX", 0) == string::npos
64 && lineGenerator.find(
"Pythia8", 0) == string::npos
65 && lineGenerator.find(
"MadGraph", 0) == string::npos){
68 getline(infile,lineGenerator);
77 int inParticleNumbers[] = {
79 -11,11,-12,12,-13,13,-14,14,-15,15,-16,16,
83 -1,1,-2,2,-3,3,-4,4,-5,5,-6,6};
85 string inParticleNamesSH[] = {
87 "-11",
"11",
"-12",
"12",
"-13",
"13",
"-14",
"14",
"-15",
"15",
"-16",
"16",
89 "-93",
"93",
"-90",
"90",
"-91",
"91",
91 "-1",
"1",
"-2",
"2",
"-3",
"3",
"-4",
"4",
"-5",
"5",
"-6",
"6"};
92 string inParticleNamesMG[] = {
94 "e+",
"e-",
"ve~",
"ve",
"mu+",
"mu-",
"vm~",
"vm",
"ta+",
"ta-",
"vt~",
"vt",
96 "p~",
"p",
"l+",
"l-",
"vl~",
"vl",
98 "d~",
"d",
"u~",
"u",
"s~",
"s",
"c~",
"c",
"b~",
"b",
"t~",
"t"};
101 int interParticleNumbers[] = {
103 22,23,-24,24,25,2400,
109 -1000001,1000001,-1000002,1000002,-1000003,1000003,-1000004,1000004,
110 -1000005,1000005,-1000006,1000006,-2000001,2000001,-2000002,2000002,
111 -2000003,2000003,-2000004,2000004,-2000005,2000005,-2000006,2000006};
113 string interParticleNamesMG[] = {
115 "a",
"z",
"w-",
"w+",
"h",
"W",
121 "dl~",
"dl",
"ul~",
"ul",
"sl~",
"sl",
"cl~",
"cl",
"b1~",
"b1",
"t1~",
"t1",
122 "dr~",
"dr",
"ur~",
"ur",
"sr~",
"sr",
"cr~",
"cr",
"b2~",
"b2",
"t2~",
"t2"};
125 int outParticleNumbers[] = {
127 -11,11,-12,12,-13,13,-14,14,-15,15,-16,16,
129 2212,2212,0,0,0,0,1200,1100,5000,
131 -1,1,-2,2,-3,3,-4,4,-5,5,-6,6,
133 22,23,-24,24,25,2400,
137 -1000001,1000001,-1000002,1000002,-1000003,1000003,-1000004,1000004,
138 -1000005,1000005,-1000006,1000006,-2000001,2000001,-2000002,2000002,
139 -2000003,2000003,-2000004,2000004,-2000005,2000005,-2000006,2000006};
141 string outParticleNamesMG[] = {
143 "e+",
"e-",
"ve~",
"ve",
"mu+",
"mu-",
"vm~",
"vm",
"ta+",
"ta-",
"vt~",
"vt",
145 "j~",
"j",
"l+",
"l-",
"vl~",
"vl",
"NEUTRINOS",
"LEPTONS",
"BQUARKS",
147 "d~",
"d",
"u~",
"u",
"s~",
"s",
"c~",
"c",
"b~",
"b",
"t~",
"t",
149 "a",
"z",
"w-",
"w+",
"h",
"W",
153 "dl~",
"dl",
"ul~",
"ul",
"sl~",
"sl",
"cl~",
"cl",
"b1~",
"b1",
"t1~",
"t1",
154 "dr~",
"dr",
"ur~",
"ur",
"sr~",
"sr",
"cr~",
"cr",
"b2~",
"b2",
"t2~",
"t2"};
156 string outParticleNamesSH[] = {
158 "-11",
"11",
"-12",
"12",
"-13",
"13",
"-14",
"14",
"-15",
"15",
"-16",
"16",
160 "-93",
"93",
"-90",
"90",
"-91",
"91",
"0",
"0",
"0",
162 "-1",
"1",
"-2",
"2",
"-3",
"3",
"-4",
"4",
"-5",
"5",
"-6",
"6",
164 "22",
"23",
"-24",
"24",
"25",
"0",
168 "-1000001",
"1000001",
"-1000002",
"1000002",
"-1000003",
"1000003",
169 "-1000004",
"1000004",
170 "-1000005",
"1000005",
"-1000006",
"1000006",
"-2000001",
"2000001",
171 "-2000002",
"2000002",
172 "-2000003",
"2000003",
"-2000004",
"2000004",
"-2000005",
"2000005",
173 "-2000006",
"2000006"};
182 int meGenType = (lineGenerator.find(
"MadGraph", 0) != string::npos) ? -1
183 : (lineGenerator.find(
"SHERPA", 0) != string::npos) ? -2
184 : (lineGenerator.find(
"POWHEG-BOX", 0) != string::npos) ? -3
185 : (lineGenerator.find(
"Pythia8", 0) != string::npos) ? -4
188 if (meGenType == -2){
191 infile.open( (
char*)( LHEpath +
"_1.lhe").c_str());
193 while(lineTMS.find(
"NJetFinder ", 0) == string::npos){
195 getline(infile,lineTMS);
198 lineTMS = lineTMS.substr(0,lineTMS.find(
" 0.0 ",0));
199 lineTMS = lineTMS.substr(lineTMS.find(
" ", 0)+3,lineTMS.size());
201 while(lineTMS.find(
" ", 0) != string::npos)
202 lineTMS.erase(lineTMS.begin()+lineTMS.find(
" ",0));
204 if ( lineTMS.find(
"d", 0) != string::npos)
205 lineTMS.replace(lineTMS.find(
"d", 0),1,1,
'e');
206 tms = atof((
char*)lineTMS.c_str());
210 infile.open( (
char*)( LHEpath +
"_0.lhe").c_str());
212 while(line.find(
"Process", 0) == string::npos){
214 getline(infile,line);
217 line = line.substr(line.find(
" ",0),line.size());
220 vector <string> pieces;
221 pieces.push_back( line.substr(0,line.find(
"->", 0)) );
223 int end = (line.find(
"{", 0) != string::npos) ? line.find(
"{", 0)-2
225 pieces.push_back( line.substr(line.find(
"->", 0)+2, end) );
228 for(
int i=0; i < nIn; ++i) {
229 for(
int n = pieces[0].find(inParticleNamesSH[i], 0);
230 n != int(string::npos);
231 n = pieces[0].find(inParticleNamesSH[i], n)) {
232 incom.push_back(inParticleNumbers[i]);
233 pieces[0].erase(pieces[0].begin()+n,
234 pieces[0].begin()+n+inParticleNamesSH[i].size());
242 for(
int i=0; i < nOut; ++i) {
243 for(
int n = pieces[1].find(outParticleNamesSH[i], 0);
244 n != int(string::npos);
245 n = pieces[1].find(outParticleNamesSH[i], n)) {
246 outgo.push_back(outParticleNumbers[i]);
247 pieces[1].erase(pieces[1].begin()+n,
248 pieces[1].begin()+n+outParticleNamesSH[i].size());
253 }
else if (meGenType == -1 || meGenType == -3 || meGenType == -4){
258 if (meGenType == -1) {
260 infile.open( (
char*)( LHEpath +
"_1.lhe").c_str());
261 while(lineTMS.find(
"ktdurham", 0) == string::npos){
263 getline(infile,lineTMS);
265 lineTMS = lineTMS.substr(0,lineTMS.find(
"=",0));
272 while(lineTMS.find(
" ", 0) != string::npos)
273 lineTMS.erase(lineTMS.begin()+lineTMS.find(
" ",0));
275 if ( lineTMS.find(
"d", 0) != string::npos)
276 lineTMS.replace(lineTMS.find(
"d", 0),1,1,
'e');
277 tms = atof((
char*)lineTMS.c_str());
281 infile.open( (
char*)( LHEpath +
"_0.lhe").c_str());
283 while(line.find(
"@1", 0) == string::npos){
285 getline(infile,line);
288 line = line.substr(0,line.find(
"@",0));
292 for(
int n = line.find(
"(", 0); n != int(string::npos);
293 n = line.find(
"(", n)) {
299 vector <string> pieces;
300 for(
int i =0; i < appearances;++i) {
301 int n = line.find(
"(", 0);
302 pieces.push_back(line.substr(0,n));
303 line = line.substr(n+1,line.size());
306 if (appearances > 0) {
307 pieces.push_back( line.substr(0,line.find(
")",0)) );
308 pieces.push_back( line.substr(line.find(
")",0)+1,line.size()) );
313 if (pieces.empty() ){
315 for(
int n = line.find(
">", 0); n != int(string::npos);
316 n = line.find(
">", n)) {
322 for(
int i =0; i < appearances;++i) {
323 int n = line.find(
">", 0);
324 pieces.push_back(line.substr(0,n));
325 line = line.substr(n+1,line.size());
328 if (appearances == 1) pieces.push_back(line);
329 if (appearances > 1) {
330 pieces.push_back( line.substr(0,line.find(
">",0)) );
331 pieces.push_back( line.substr(line.find(
">",0)+1,line.size()) );
336 for(
int i=0; i < nIn; ++i) {
337 for(
int n = pieces[0].find(inParticleNamesMG[i], 0);
338 n != int(string::npos);
339 n = pieces[0].find(inParticleNamesMG[i], n)) {
340 incom.push_back(inParticleNumbers[i]);
341 pieces[0].erase(pieces[0].begin()+n,
342 pieces[0].begin()+n+inParticleNamesMG[i].size());
348 for(
int i =1; i < int(pieces.size()); ++i){
350 int k = pieces[i].find(
">", 0);
352 string intermediate = (pieces[i].find(
">", 0) != string::npos) ?
353 pieces[i].substr(0,k) :
"";
354 string outgoing = (pieces[i].find(
">", 0) != string::npos) ?
355 pieces[i].substr(k+1,pieces[i].size()) : pieces[i];
358 for(
int j=0; j < nInt; ++j) {
359 for(
int n = intermediate.find(interParticleNamesMG[j], 0);
360 n != int(string::npos);
361 n = intermediate.find(interParticleNamesMG[j], n)) {
362 inter.push_back(interParticleNumbers[j]);
363 intermediate.erase(intermediate.begin()+n,
364 intermediate.begin()+n+interParticleNamesMG[j].size());
370 for(
int j=0; j < nOut; ++j) {
371 for(
int n = outgoing.find(outParticleNamesMG[j], 0);
372 n != int(string::npos);
373 n = outgoing.find(outParticleNamesMG[j], n)) {
374 outgo.push_back(outParticleNumbers[j]);
375 outgoing.erase(outgoing.begin()+n,
376 outgoing.begin()+n+outParticleNamesMG[j].size());
388 for(
int l=0; l < int(outgo.size()); ++l)
389 if ( (abs(outgo[l]) > 20 && abs(outgo[l]) <= 25) || outgo[l] == 2400)
392 int nZeros = (outgo.size() - nBosons)/2;
393 for(
int l=0; l < nZeros; ++l)
399 for(
int l=0; l < int(outgo.size()); ++l)
400 if ( (abs(outgo[l]) > 20 && abs(outgo[l]) <= 25) || outgo[l] == 2400)
401 inter.push_back(outgo[l]);
407 cout <<
"Reading of tms and hard process information from LHEF currently"
408 <<
" only automated for MadEvent- or SHERPA-produced LHEF" << endl;
410 cout <<
"Use default process pp -> e+ve + jets? (0:no / 1:yes): ";
416 double tempDouble = 0.0;
417 cout <<
"Please specify merging scale (kT Durham, in GeV): ";
421 cout <<
"Please specify first incoming particle ";
422 cout <<
"(p+/p- = 2212, e- = 11, e+ = -11): ";
424 incom.push_back(tempInt);
427 cout <<
"Please specify second incoming particle ";
428 cout <<
"(p+/p- = 2212, e- = 11, e+ = -11): ";
430 incom.push_back(tempInt);
433 cout <<
"Please specify intermediate particle, if any ";
434 cout <<
"(0 for none, else PDG code): ";
436 inter.push_back(tempInt);
440 cout <<
"Please specify outgoing particle ";
441 cout <<
"(jet=2212, else PDG code, exit with 99): ";
443 if (tempInt != 99) outgo.push_back(tempInt);
444 }
while(tempInt != 99);
447 cout <<
"LHE file not produced by SHERPA or MG/ME - ";
448 cout <<
"Using default process and tms" << endl;
449 incom.push_back(2212);
450 incom.push_back(2212);
452 outgo.push_back(-11);
460 for(
int i=0; i < int(inter.size()); ++i)
461 hardIntermediate.push_back(inter[i]);
464 if (incom.size() != 2)
465 cout <<
"Only two incoming particles allowed" << endl;
467 hardIncoming1 = incom[0];
468 hardIncoming2 = incom[1];
473 for(
int i=0; i < int(outgo.size()); ++i)
474 if ( (abs(outgo[i]) > 20 && abs(outgo[i]) <= 25) || outgo[i] == 2400)
478 for(
int i=0; i < int(outgo.size()); ++i)
479 if ( outgo[i] == 5000)
483 for(
int i=0; i < int(outgo.size()); ++i)
484 if ( outgo[i] == 2212)
488 for(
int i=0; i < int(outgo.size()); ++i)
489 if ( outgo[i] == 1100)
493 for(
int i=0; i < int(outgo.size()); ++i)
494 if ( outgo[i] == 1200)
496 int nContainers = nLeptons + nNeutrinos + nJets + nBQuarks;
499 if ( (outgo.size() - nBosons - nContainers)%2 == 1) {
500 cout <<
"Only even number of outgoing particles allowed" << endl;
501 for(
int i=0; i < int(outgo.size()); ++i)
502 cout << outgo[i] << endl;
506 for(
int i=0; i < int(outgo.size()); ++i)
513 && outgo[i] != 1000022)
514 hardOutgoing2.push_back( outgo[i]);
515 else if (outgo[i] < 0)
516 hardOutgoing1.push_back( outgo[i]);
519 for(
int i=0; i < int(outgo.size()); ++i)
520 if ( outgo[i] == 2400)
521 hardOutgoing2.push_back( outgo[i]);
526 for(
int i=0; i < int(outgo.size()); ++i)
527 if ( (outgo[i] == 2212
530 || outgo[i] == 1000022)
532 hardOutgoing2.push_back( outgo[i]);
534 }
else if ( (outgo[i] == 2212
537 || outgo[i] == 1000022)
539 hardOutgoing1.push_back( outgo[i]);
553 void HardProcess::translateProcessString(
string process){
560 int inParticleNumbers[] = {
562 -11,11,-12,12,-13,13,-14,14,-15,15,-16,16,
566 -1,1,-2,2,-3,3,-4,4,-5,5,-6,6};
567 string inParticleNamesMG[] = {
569 "e+",
"e-",
"ve~",
"ve",
"mu+",
"mu-",
"vm~",
"vm",
"ta+",
"ta-",
"vt~",
"vt",
571 "p~",
"p",
"l+",
"l-",
"vl~",
"vl",
573 "d~",
"d",
"u~",
"u",
"s~",
"s",
"c~",
"c",
"b~",
"b",
"t~",
"t"};
576 int interParticleNumbers[] = {
578 22,23,-24,24,25,2400,
584 -1000001,1000001,-1000002,1000002,-1000003,1000003,-1000004,1000004,
585 -1000005,1000005,-1000006,1000006,-2000001,2000001,-2000002,2000002,
586 -2000003,2000003,-2000004,2000004,-2000005,2000005,-2000006,2000006};
588 string interParticleNamesMG[] = {
590 "a",
"z",
"w-",
"w+",
"h",
"W",
596 "dl~",
"dl",
"ul~",
"ul",
"sl~",
"sl",
"cl~",
"cl",
"b1~",
"b1",
"t1~",
"t1",
597 "dr~",
"dr",
"ur~",
"ur",
"sr~",
"sr",
"cr~",
"cr",
"b2~",
"b2",
"t2~",
"t2"};
600 int outParticleNumbers[] = {
602 -11,11,-12,12,-13,13,-14,14,-15,15,-16,16,
604 2212,2212,0,0,0,0,1200,1100,5000,
606 -1,1,-2,2,-3,3,-4,4,-5,5,-6,6,
608 22,23,-24,24,25,2400,
612 -1000001,1000001,-1000002,1000002,-1000003,1000003,-1000004,1000004,
613 -1000005,1000005,-1000006,1000006,-2000001,2000001,-2000002,2000002,
614 -2000003,2000003,-2000004,2000004,-2000005,2000005,-2000006,2000006};
616 string outParticleNamesMG[] = {
618 "e+",
"e-",
"ve~",
"ve",
"mu+",
"mu-",
"vm~",
"vm",
"ta+",
"ta-",
"vt~",
"vt",
620 "j~",
"j",
"l+",
"l-",
"vl~",
"vl",
"NEUTRINOS",
"LEPTONS",
"BQUARKS",
622 "d~",
"d",
"u~",
"u",
"s~",
"s",
"c~",
"c",
"b~",
"b",
"t~",
"t",
624 "a",
"z",
"w-",
"w+",
"h",
"W",
628 "dl~",
"dl",
"ul~",
"ul",
"sl~",
"sl",
"cl~",
"cl",
"b1~",
"b1",
"t1~",
"t1",
629 "dr~",
"dr",
"ur~",
"ur",
"sr~",
"sr",
"cr~",
"cr",
"b2~",
"b2",
"t2~",
"t2"};
638 string fullProc = process;
642 int nUserParticles = 0;
643 for(
int n = fullProc.find(
"{", 0); n != int(string::npos);
644 n = fullProc.find(
"{", n)) {
649 vector <string> userParticleStrings;
650 for(
int i =0; i < nUserParticles;++i) {
651 int n = fullProc.find(
"{", 0);
652 userParticleStrings.push_back(fullProc.substr(0,n));
653 fullProc = fullProc.substr(n+1,fullProc.size());
656 if (nUserParticles > 0)
657 userParticleStrings.push_back(
658 fullProc.substr( 0, fullProc.find(
"}",0) ) );
660 for(
int i =0; i < int(userParticleStrings.size());++i) {
661 while(userParticleStrings[i].find(
"{", 0) != string::npos)
662 userParticleStrings[i].erase(userParticleStrings[i].begin()
663 +userParticleStrings[i].find(
"{", 0));
664 while(userParticleStrings[i].find(
"}", 0) != string::npos)
665 userParticleStrings[i].erase(userParticleStrings[i].begin()
666 +userParticleStrings[i].find(
"}", 0));
667 while(userParticleStrings[i].find(
" ", 0) != string::npos)
668 userParticleStrings[i].erase(userParticleStrings[i].begin()
669 +userParticleStrings[i].find(
" ", 0));
672 vector<int>userParticleNumbers;
673 if (
int(userParticleStrings.size()) > 1) {
674 for(
int i = 1; i < int(userParticleStrings.size()); ++i) {
675 userParticleNumbers.push_back(
676 atoi((
char*)userParticleStrings[i].substr(
677 userParticleStrings[i].find(
",",0)+1,
678 userParticleStrings[i].size()).c_str() ) );
682 if (nUserParticles > 0)
683 userParticleStrings.push_back(
685 fullProc.find(
"}",0)+1, fullProc.size() ) );
687 for(
int i = 0; i < int(userParticleStrings.size()); ++i) {
688 while(userParticleStrings[i].find(
"{", 0) != string::npos)
689 userParticleStrings[i].erase(userParticleStrings[i].begin()
690 +userParticleStrings[i].find(
"{", 0));
691 while(userParticleStrings[i].find(
"}", 0) != string::npos)
692 userParticleStrings[i].erase(userParticleStrings[i].begin()
693 +userParticleStrings[i].find(
"}", 0));
694 while(userParticleStrings[i].find(
" ", 0) != string::npos)
695 userParticleStrings[i].erase(userParticleStrings[i].begin()
696 +userParticleStrings[i].find(
" ", 0));
702 if (
int(userParticleStrings.size()) > 1 )
703 residualProc = userParticleStrings.front() + userParticleStrings.back();
705 residualProc = fullProc;
708 while(residualProc.find(
",", 0) != string::npos)
709 residualProc.erase(residualProc.begin()+residualProc.find(
",",0));
713 for(
int n = residualProc.find(
"(", 0); n != int(string::npos);
714 n = residualProc.find(
"(", n)) {
720 vector <string> pieces;
721 for(
int i =0; i < appearances;++i) {
722 int n = residualProc.find(
"(", 0);
723 pieces.push_back(residualProc.substr(0,n));
724 residualProc = residualProc.substr(n+1,residualProc.size());
727 if (appearances > 0) {
728 pieces.push_back( residualProc.substr(0,residualProc.find(
")",0)) );
729 pieces.push_back( residualProc.substr(
730 residualProc.find(
")",0)+1, residualProc.size()) );
735 if (pieces.empty() ){
737 for(
int n = residualProc.find(
">", 0); n != int(string::npos);
738 n = residualProc.find(
">", n)) {
744 for(
int i =0; i < appearances;++i) {
745 int n = residualProc.find(
">", 0);
746 pieces.push_back(residualProc.substr(0,n));
747 residualProc = residualProc.substr(n+1,residualProc.size());
750 if (appearances == 1) pieces.push_back(residualProc);
751 if (appearances > 1) {
752 pieces.push_back( residualProc.substr(0,residualProc.find(
">",0)) );
753 pieces.push_back( residualProc.substr(
754 residualProc.find(
">",0)+1, residualProc.size()) );
759 for(
int i=0; i < nIn; ++i) {
760 for(
int n = pieces[0].find(inParticleNamesMG[i], 0);
761 n != int(string::npos);
762 n = pieces[0].find(inParticleNamesMG[i], n)) {
763 incom.push_back(inParticleNumbers[i]);
764 pieces[0].erase(pieces[0].begin()+n,
765 pieces[0].begin()+n+inParticleNamesMG[i].size());
771 for(
int i =1; i < int(pieces.size()); ++i){
773 int k = pieces[i].find(
">", 0);
775 string intermediate = (pieces[i].find(
">", 0) != string::npos) ?
776 pieces[i].substr(0,k) :
"";
777 string outgoing = (pieces[i].find(
">", 0) != string::npos) ?
778 pieces[i].substr(k+1,pieces[i].size()) : pieces[i];
781 for(
int j=0; j < nInt; ++j) {
782 for(
int n = intermediate.find(interParticleNamesMG[j], 0);
783 n != int(string::npos);
784 n = intermediate.find(interParticleNamesMG[j], n)) {
785 inter.push_back(interParticleNumbers[j]);
786 intermediate.erase(intermediate.begin()+n,
787 intermediate.begin()+n+interParticleNamesMG[j].size());
793 for(
int j=0; j < nOut; ++j) {
794 for(
int n = outgoing.find(outParticleNamesMG[j], 0);
795 n != int(string::npos);
796 n = outgoing.find(outParticleNamesMG[j], n)) {
797 outgo.push_back(outParticleNumbers[j]);
798 outgoing.erase(outgoing.begin()+n,
799 outgoing.begin()+n+outParticleNamesMG[j].size());
811 for(
int l=0; l < int(outgo.size()); ++l)
812 if ( (abs(outgo[l]) > 20 && abs(outgo[l]) <= 25) || outgo[l] == 2400)
815 int nZeros = (outgo.size() - nBosons)/2;
816 for(
int l=0; l < nZeros; ++l)
822 for(
int l=0; l < int(outgo.size()); ++l)
823 if ( (abs(outgo[l]) > 20 && abs(outgo[l]) <= 25) || outgo[l] == 2400)
824 inter.push_back(outgo[l]);
830 for(
int i=0; i < int(inter.size()); ++i)
831 hardIntermediate.push_back(inter[i]);
834 if (incom.size() != 2)
835 cout <<
"Only two incoming particles allowed" << endl;
837 hardIncoming1 = incom[0];
838 hardIncoming2 = incom[1];
843 for(
int i = 0; i < int(userParticleNumbers.size()); ++i)
844 if (userParticleNumbers[i] > 0) {
845 hardOutgoing2.push_back( userParticleNumbers[i]);
846 hardIntermediate.push_back(0);
848 }
else if (userParticleNumbers[i] < 0) {
849 hardOutgoing1.push_back( userParticleNumbers[i]);
851 hardIntermediate.push_back(0);
855 for(
int i=0; i < int(outgo.size()); ++i)
862 && outgo[i] != 1000022)
863 hardOutgoing2.push_back( outgo[i]);
864 else if (outgo[i] < 0)
865 hardOutgoing1.push_back( outgo[i]);
868 for(
int i=0; i < int(outgo.size()); ++i)
869 if ( outgo[i] == 2400)
870 hardOutgoing2.push_back( outgo[i]);
875 for(
int i=0; i < int(outgo.size()); ++i)
876 if ( (outgo[i] == 2212
879 || outgo[i] == 1000022)
881 hardOutgoing2.push_back( outgo[i]);
883 }
else if ( (outgo[i] == 2212
886 || outgo[i] == 1000022)
888 hardOutgoing1.push_back( outgo[i]);
900 bool HardProcess::allowCandidates(
int iPos, vector<int> Pos1,
901 vector<int> Pos2,
const Event& event){
906 int type = (
event[iPos].col() > 0) ? 1 : (event[iPos].acol() > 0) ? -1 : 0;
908 if (type == 0)
return true;
911 int col =
event[iPos].col();
913 for(
int i=0; i < int(event.size()); ++i)
915 && (( event[i].isFinal() && event[i].acol() == col)
916 ||(
event[i].status() == -21 &&
event[i].col() == col) ))
919 vector<int> partners;
920 for(
int i=0; i < int(event.size()); ++i)
921 for(
int j=0; j < int(Pos1.size()); ++j)
922 if ( Pos1[j] != 0 && i != Pos1[j] && event[Pos1[j]].colType() != 0
923 && ((
event[i].isFinal() &&
event[i].col() ==
event[Pos1[j]].acol())
924 ||( event[i].status() == -21
925 &&
event[i].acol() ==
event[Pos1[j]].acol()) ))
926 partners.push_back(i);
929 if (event[iPartner].status() == -21){
930 for(
int i=0; i < int(partners.size()); ++i)
931 if ( partners[i] == iPartner)
936 int col =
event[iPos].acol();
938 for(
int i=0; i < int(event.size()); ++i)
940 && (( event[i].isFinal() && event[i].col() == col)
941 ||(!
event[i].isFinal() &&
event[i].acol() == col) ))
944 vector<int> partners;
945 for(
int i=0; i < int(event.size()); ++i)
946 for(
int j=0; j < int(Pos2.size()); ++j)
947 if ( Pos2[j] != 0 && i != Pos2[j] && event[Pos2[j]].colType() != 0
948 && ((
event[i].isFinal() &&
event[i].acol() ==
event[Pos2[j]].col())
949 ||( event[i].status() == -21
950 &&
event[i].col() ==
event[Pos2[j]].col()) ))
951 partners.push_back(i);
954 if (event[iPartner].status() == -21){
955 for(
int i=0; i < int(partners.size()); ++i){
956 if ( partners[i] == iPartner)
971 void HardProcess::storeCandidates(
const Event& event,
string process){
978 vector<int> intermediates;
979 for(
int i =0; i < int(hardIntermediate.size());++i)
980 intermediates.push_back( hardIntermediate[i]);
983 vector<int> outgoing1;
984 for(
int i =0; i < int(hardOutgoing1.size());++i)
985 outgoing1.push_back( hardOutgoing1[i]);
986 vector<int> outgoing2;
987 for(
int i =0; i < int(hardOutgoing2.size());++i)
988 outgoing2.push_back( hardOutgoing2[i]);
991 PosIntermediate.resize(0);
992 PosOutgoing1.resize(0);
993 PosOutgoing2.resize(0);
994 for(
int i =0; i < int(hardIntermediate.size());++i)
995 PosIntermediate.push_back(0);
996 for(
int i =0; i < int(hardOutgoing1.size());++i)
997 PosOutgoing1.push_back(0);
998 for(
int i =0; i < int(hardOutgoing2.size());++i)
999 PosOutgoing2.push_back(0);
1003 if ( process.compare(
"pp>jj") == 0
1004 || process.compare(
"e+e->jj") == 0
1005 || process.compare(
"e+e->(z>jj)") == 0 ){
1006 for(
int i =0; i < int(hardOutgoing1.size());++i)
1007 PosOutgoing1[i] = 0;
1008 for(
int i =0; i < int(hardOutgoing2.size());++i)
1009 PosOutgoing2[i] = 0;
1016 vector<int> iPosChecked;
1020 bool hasOnlyContainers =
true;
1021 for(
int i =0; i < int(hardOutgoing1.size());++i)
1022 if ( hardOutgoing1[i] != 1100
1023 && hardOutgoing1[i] != 1200
1024 && hardOutgoing1[i] != 5000)
1025 hasOnlyContainers =
false;
1026 for(
int i =0; i < int(hardOutgoing2.size());++i)
1027 if ( hardOutgoing2[i] != 1100
1028 && hardOutgoing2[i] != 1200
1029 && hardOutgoing2[i] != 5000)
1030 hasOnlyContainers =
false;
1032 if (hasOnlyContainers){
1034 PosOutgoing1.resize(0);
1035 PosOutgoing2.resize(0);
1039 for(
int i=0; i < int(event.size()); ++i){
1042 if ( !event[i].isFinal() )
continue;
1046 for(
int k=0; k < int(iPosChecked.size()); ++k){
1047 if (i == iPosChecked[k])
1052 for(
int j=0; j < int(outgoing2.size()); ++j){
1055 if ( outgoing2[j] == 1100
1056 && ( event[i].idAbs() == 11
1057 ||
event[i].idAbs() == 13
1058 ||
event[i].idAbs() == 15) ){
1059 PosOutgoing2.push_back(i);
1060 iPosChecked.push_back(i);
1064 if ( outgoing2[j] == 1200
1065 && ( event[i].idAbs() == 12
1066 || event[i].idAbs() == 14
1067 || event[i].idAbs() == 16) ){
1068 PosOutgoing2.push_back(i);
1069 iPosChecked.push_back(i);
1073 if ( outgoing2[j] == 5000 && event[i].idAbs() == 5 ){
1074 PosOutgoing2.push_back(i);
1075 iPosChecked.push_back(i);
1082 for(
int k=0; k < int(iPosChecked.size()); ++k){
1083 if (i == iPosChecked[k])
1088 for(
int j=0; j < int(outgoing1.size()); ++j){
1091 if ( outgoing1[j] == 1100
1092 && ( event[i].idAbs() == 11
1093 ||
event[i].idAbs() == 13
1094 ||
event[i].idAbs() == 15) ){
1095 PosOutgoing1.push_back(i);
1096 iPosChecked.push_back(i);
1100 if ( outgoing1[j] == 1200
1101 && ( event[i].idAbs() == 12
1102 || event[i].idAbs() == 14
1103 || event[i].idAbs() == 16) ){
1104 PosOutgoing1.push_back(i);
1105 iPosChecked.push_back(i);
1109 if ( outgoing1[j] == 5000 && event[i].idAbs() == 5 ){
1110 PosOutgoing1.push_back(i);
1111 iPosChecked.push_back(i);
1124 for(
int i=0; i < int(intermediates.size()); ++i){
1127 if (intermediates[i] == 0)
continue;
1130 bool matchesFinalBoson =
false;
1131 for(
int j =0; j< int(outgoing1.size()); ++j){
1132 if ( intermediates[i] == outgoing1[j] )
1133 matchesFinalBoson =
true;
1135 for(
int j =0; j< int(outgoing2.size()); ++j){
1136 if ( intermediates[i] == outgoing2[j] )
1137 matchesFinalBoson =
true;
1139 if (!matchesFinalBoson)
continue;
1142 for(
int j=0; j < int(event.size()); ++j) {
1146 for(
int m=0; m < int(iPosChecked.size()); ++m)
1147 if (j == iPosChecked[m]) skip =
true;
1152 if ( (event[j].
id() == intermediates[i])
1153 ||(event[j].idAbs() == 24 && intermediates[i] == 2400) ) {
1155 PosIntermediate[i] = j;
1156 intermediates[i] = 0;
1158 bool indexSet =
false;
1160 for(
int k=0; k < int(outgoing1.size()); ++k) {
1161 if (event[j].
id() == outgoing1[k] && !indexSet){
1162 PosOutgoing1[k] = j;
1168 for(
int k=0; k < int(outgoing2.size()); ++k) {
1169 if (event[j].
id() == outgoing2[k] && !indexSet){
1170 PosOutgoing2[k] = j;
1177 for(
int k=0; k < int(outgoing2.size()); ++k) {
1178 if (event[j].idAbs() == 24 && outgoing2[k] == 2400 && !indexSet ){
1179 PosOutgoing2[k] = j;
1185 iPosChecked.push_back(j);
1192 for(
int i=0; i < int(intermediates.size()); ++i){
1195 if (intermediates[i] == 0)
continue;
1198 for(
int j=0; j < int(event.size()); ++j) {
1201 if ( (event[j].
id() == intermediates[i])
1202 ||(event[j].idAbs() == 24 && intermediates[i] == 2400) ) {
1204 PosIntermediate[i] = j;
1205 intermediates[i] = 0;
1207 int iPos1 =
event[j].daughter1();
1208 int iPos2 =
event[j].daughter2();
1212 for(
int k=iPos1; k <= iPos2; ++k){
1213 int id =
event[k].id();
1217 for(
int m=0; m < int(iPosChecked.size()); ++m)
1218 if (k == iPosChecked[m]) skip =
true;
1222 for(
int l=0; l < int(outgoing2.size()); ++l)
1223 if ( outgoing2[l] != 99 ){
1225 if (
id == outgoing2[l]
1227 || (
id > 0 && abs(
id) < 10 && outgoing2[l] == 2212) ){
1229 PosOutgoing2[l] = k;
1232 iPosChecked.push_back(k);
1239 for(
int l=0; l < int(outgoing1.size()); ++l)
1240 if ( outgoing1[l] != 99 ){
1242 if (
id == outgoing1[l]
1244 || (
id < 0 && abs(
id) < 10 && outgoing1[l] == 2212) ){
1246 PosOutgoing1[l] = k;
1249 iPosChecked.push_back(k);
1262 for(
int i=0; i < int(outgoing1.size()); ++i)
1263 if (outgoing1[i] != 99)
1265 for(
int i=0; i < int(outgoing2.size()); ++i)
1266 if (outgoing2[i] != 99)
1274 for(
int i=0; i < int(event.size()); ++i){
1276 if ( !event[i].isFinal() ||
event[i].colType() != 0)
1280 for(
int k=0; k < int(iPosChecked.size()); ++k){
1281 if (i == iPosChecked[k])
1287 for(
int j=0; j < int(outgoing2.size()); ++j){
1290 if ( outgoing2[j] == 99
1291 || outgoing2[j] == 2212
1292 || abs(outgoing2[j]) < 10)
1296 if ( event[i].
id() == outgoing2[j] ){
1297 PosOutgoing2[j] = i;
1299 iPosChecked.push_back(i);
1304 for(
int j=0; j < int(outgoing1.size()); ++j){
1307 if ( outgoing1[j] == 99
1308 || outgoing1[j] == 2212
1309 || abs(outgoing1[j]) < 10)
1313 if (event[i].
id() == outgoing1[j] ){
1314 PosOutgoing1[j] = i;
1316 iPosChecked.push_back(i);
1321 multimap<int,int> out2copy;
1322 for(
int i=0; i < int(event.size()); ++i)
1323 for(
int j=0; j < int(outgoing2.size()); ++j)
1326 if ( outgoing2[j] != 99
1327 && outgoing2[j] != 2212
1328 && ( abs(outgoing2[j]) < 10
1329 || (abs(outgoing2[j]) > 1000000 && abs(outgoing2[j]) < 1000010)
1330 || (abs(outgoing2[j]) > 2000000 && abs(outgoing2[j]) < 2000010)
1331 || abs(outgoing2[j]) == 1000021 )
1332 && event[i].isFinal()
1333 &&
event[i].id() == outgoing2[j] ){
1334 out2copy.insert(make_pair(j, i));
1337 multimap<int,int> out1copy;
1338 for(
int i=0; i < int(event.size()); ++i)
1339 for(
int j=0; j < int(outgoing1.size()); ++j)
1342 if ( outgoing1[j] != 99
1343 && outgoing1[j] != 2212
1344 && ( abs(outgoing1[j]) < 10
1345 || (abs(outgoing1[j]) > 1000000 && abs(outgoing1[j]) < 1000010)
1346 || (abs(outgoing1[j]) > 2000000 && abs(outgoing1[j]) < 2000010)
1347 || abs(outgoing2[j]) == 1000021 )
1348 && event[i].isFinal()
1349 &&
event[i].id() == outgoing1[j] ){
1350 out1copy.insert(make_pair(j, i));
1353 if ( out1copy.size() > out2copy.size()){
1357 vector<int> indexWasSet;
1358 for ( multimap<int, int>::iterator it = out2copy.begin();
1359 it != out2copy.end(); ++it ) {
1360 if ( allowCandidates(it->second, PosOutgoing1, PosOutgoing2, event) ){
1364 for(
int k=0; k < int(iPosChecked.size()); ++k)
1365 if (it->second == iPosChecked[k]) skip =
true;
1367 for(
int k=0; k < int(indexWasSet.size()); ++k)
1368 if (it->first == indexWasSet[k]) skip =
true;
1372 PosOutgoing2[it->first] = it->second;
1374 outgoing2[it->first] = 99;
1375 iPosChecked.push_back(it->second);
1376 indexWasSet.push_back(it->first);
1380 indexWasSet.resize(0);
1381 for ( multimap<int, int>::iterator it = out1copy.begin();
1382 it != out1copy.end(); ++it ) {
1383 if ( allowCandidates(it->second, PosOutgoing1, PosOutgoing2, event) ){
1387 for(
int k=0; k < int(iPosChecked.size()); ++k)
1388 if (it->second == iPosChecked[k]) skip =
true;
1390 for(
int k=0; k < int(indexWasSet.size()); ++k)
1391 if (it->first == indexWasSet[k]) skip =
true;
1395 PosOutgoing1[it->first] = it->second;
1397 outgoing1[it->first] = 99;
1398 iPosChecked.push_back(it->second);
1399 indexWasSet.push_back(it->first);
1407 vector<int> indexWasSet;
1408 for ( multimap<int, int>::iterator it = out1copy.begin();
1409 it != out1copy.end(); ++it ) {
1410 if ( allowCandidates(it->second, PosOutgoing1, PosOutgoing2, event) ){
1414 for(
int k=0; k < int(iPosChecked.size()); ++k)
1415 if (it->second == iPosChecked[k]) skip =
true;
1417 for(
int k=0; k < int(indexWasSet.size()); ++k)
1418 if (it->first == indexWasSet[k]) skip =
true;
1422 PosOutgoing1[it->first] = it->second;
1424 outgoing1[it->first] = 99;
1425 iPosChecked.push_back(it->second);
1426 indexWasSet.push_back(it->first);
1430 indexWasSet.resize(0);
1431 for ( multimap<int, int>::iterator it = out2copy.begin();
1432 it != out2copy.end(); ++it ) {
1433 if ( allowCandidates(it->second, PosOutgoing1, PosOutgoing2, event) ){
1437 for(
int k=0; k < int(iPosChecked.size()); ++k)
1438 if (it->second == iPosChecked[k]) skip =
true;
1440 for(
int k=0; k < int(indexWasSet.size()); ++k)
1441 if (it->first == indexWasSet[k]) skip =
true;
1445 PosOutgoing2[it->first] = it->second;
1447 outgoing2[it->first] = 99;
1448 iPosChecked.push_back(it->second);
1449 indexWasSet.push_back(it->first);
1459 for(
int i=0; i < int(event.size()); ++i){
1462 if ( !event[i].isFinal() ||
event[i].colType() == 0)
1467 for(
int k=0; k < int(iPosChecked.size()); ++k){
1468 if (i == iPosChecked[k])
1474 for(
int j=0; j < int(outgoing2.size()); ++j){
1477 if ( outgoing2[j] == 99
1478 || outgoing2[j] == 2212
1479 || abs(outgoing2[j]) > 10)
1482 if (event[i].
id() == outgoing2[j]){
1484 PosOutgoing2[j] = i;
1487 iPosChecked.push_back(i);
1492 for(
int j=0; j < int(outgoing1.size()); ++j){
1495 if ( outgoing1[j] == 99
1496 || outgoing1[j] == 2212
1497 || abs(outgoing1[j]) > 10)
1500 if (event[i].
id() == outgoing1[j]){
1502 PosOutgoing1[j] = i;
1505 iPosChecked.push_back(i);
1518 bool HardProcess::matchesAnyOutgoing(
int iPos,
const Event& event){
1521 bool matchQN1 =
false;
1523 bool matchQN2 =
false;
1527 bool matchHP =
false;
1530 for(
int i=0; i < int(PosOutgoing1.size()); ++i)
1532 if ( event[iPos].
id() == state[PosOutgoing1[i]].id()
1533 &&
event[iPos].colType() == state[PosOutgoing1[i]].colType()
1534 &&
event[iPos].chargeType() == state[PosOutgoing1[i]].chargeType()
1535 && ( (
event[iPos].col() > 0
1536 &&
event[iPos].col() == state[PosOutgoing1[i]].col())
1537 || ( event[iPos].acol() > 0
1538 &&
event[iPos].acol() == state[PosOutgoing1[i]].acol()))
1539 &&
event[iPos].charge() == state[PosOutgoing1[i]].charge() )
1543 for(
int i=0; i < int(PosOutgoing2.size()); ++i)
1545 if ( event[iPos].
id() == state[PosOutgoing2[i]].id()
1546 &&
event[iPos].colType() == state[PosOutgoing2[i]].colType()
1547 &&
event[iPos].chargeType() == state[PosOutgoing2[i]].chargeType()
1548 && ( (
event[iPos].col() > 0
1549 &&
event[iPos].col() == state[PosOutgoing2[i]].col())
1550 || ( event[iPos].acol() > 0
1551 &&
event[iPos].acol() == state[PosOutgoing2[i]].acol()))
1552 &&
event[iPos].charge() == state[PosOutgoing2[i]].charge() )
1557 if ( event[iPos].mother1()*
event[iPos].mother2() == 12
1559 || (
event[iPos].status() == 44
1560 &&
event[
event[iPos].mother1()].mother1()
1561 *
event[
event[iPos].mother1()].mother2() == 12 )
1563 || ( event[iPos].status() == 23
1564 &&
event[
event[iPos].mother1()].mother1()
1565 *
event[
event[iPos].mother1()].mother2() == 12 )
1568 || ( event[iPos].status() == 23
1569 &&
event[
event[iPos].mother1()].status() == -22
1570 &&
event[
event[
event[iPos].mother1()].mother1()].status() == -22
1571 &&
event[
event[
event[iPos].mother1()].mother1()].mother1()
1572 *
event[
event[
event[iPos].mother1()].mother1()].mother2() == 12 ) )
1576 return ( matchHP && (matchQN1 || matchQN2) );
1587 bool HardProcess::findOtherCandidates(
int iPos,
const Event& event,
1591 bool foundCopy =
false;
1594 int id =
event[iPos].id();
1595 int col =
event[iPos].col();
1596 int acl =
event[iPos].acol();
1600 int iMoth1 =
event[iPos].mother1();
1601 int iMoth2 =
event[iPos].mother2();
1602 if ( iMoth1 > 0 && iMoth2 == 0 ) {
1603 bool hasIdentifiedMother =
false;
1604 for(
int i=0; i < int(PosIntermediate.size()); ++i)
1606 if ( event[iMoth1].
id() == state[PosIntermediate[i]].id()
1607 &&
event[iMoth1].colType() == state[PosIntermediate[i]].colType()
1608 &&
event[iMoth1].chargeType() == state[PosIntermediate[i]].chargeType()
1609 &&
event[iMoth1].col() == state[PosIntermediate[i]].col()
1610 &&
event[iMoth1].acol() == state[PosIntermediate[i]].acol()
1611 &&
event[iMoth1].charge() == state[PosIntermediate[i]].charge() )
1612 hasIdentifiedMother =
true;
1613 if(hasIdentifiedMother && event[iMoth1].
id() != id)
return false;
1617 vector<int> candidates1;
1618 vector<int> candidates2;
1620 for(
int i=0; i < int(PosOutgoing1.size()); ++i)
1622 if (
id == state[PosOutgoing1[i]].
id()
1623 && col == state[PosOutgoing1[i]].col()
1624 && acl == state[PosOutgoing1[i]].acol() )
1625 candidates1.push_back(i);
1627 for(
int i=0; i < int(PosOutgoing2.size()); ++i)
1629 if (
id == state[PosOutgoing2[i]].
id()
1630 && col == state[PosOutgoing2[i]].col()
1631 && acl == state[PosOutgoing2[i]].acol() )
1632 candidates2.push_back(i);
1635 if ( candidates1.size() + candidates2.size() != 1 )
return false;
1638 map<int,int> further1;
1639 for(
int i=0; i < int(state.size()); ++i)
1640 for(
int j=0; j < int(PosOutgoing1.size()); ++j)
1643 if ( state[i].isFinal()
1644 && i != PosOutgoing1[j]
1645 && state[PosOutgoing1[j]].id() ==
id
1646 && state[i].id() == id ){
1648 vector<int> newPosOutgoing1;
1649 for(
int k=0; k < int(PosOutgoing1.size()); ++k)
1650 if ( k != j ) newPosOutgoing1.push_back( PosOutgoing1[k] );
1652 if ( allowCandidates(i, newPosOutgoing1, PosOutgoing2, state) )
1653 further1.insert(make_pair(j, i));
1657 map<int,int> further2;
1658 for(
int i=0; i < int(state.size()); ++i)
1659 for(
int j=0; j < int(PosOutgoing2.size()); ++j)
1662 if ( state[i].isFinal()
1663 && i != PosOutgoing2[j]
1664 && state[PosOutgoing2[j]].id() ==
id
1665 && state[i].id() == id ){
1667 vector<int> newPosOutgoing2;
1668 for(
int k=0; k < int(PosOutgoing2.size()); ++k)
1669 if ( k != j ) newPosOutgoing2.push_back( PosOutgoing2[k] );
1671 if ( allowCandidates(i, PosOutgoing1, newPosOutgoing2, state) )
1672 further2.insert(make_pair(j, i));
1676 foundCopy = (doReplace)
1677 ? exchangeCandidates(candidates1, candidates2, further1, further2)
1678 : (further1.size() + further2.size() > 0);
1689 bool HardProcess::exchangeCandidates( vector<int> candidates1,
1690 vector<int> candidates2, map<int,int> further1, map<int,int> further2) {
1692 int nOld1 = candidates1.size();
1693 int nOld2 = candidates2.size();
1694 int nNew1 = further1.size();
1695 int nNew2 = further2.size();
1696 bool exchanged =
false;
1698 if ( nOld1 == 1 && nOld2 == 0 && nNew1 == 1 && nNew2 == 0){
1699 PosOutgoing1[further1.begin()->first] = further1.begin()->second;
1701 }
else if ( nOld1 == 0 && nOld2 == 1 && nNew1 == 0 && nNew2 == 1){
1702 PosOutgoing2[further2.begin()->first] = further2.begin()->second;
1705 }
else if ( nNew1 > 1 && nNew2 == 0 ) {
1706 PosOutgoing1[further1.begin()->first] = further1.begin()->second;
1708 }
else if ( nNew1 == 0 && nNew2 > 0 ) {
1709 PosOutgoing2[further2.begin()->first] = further2.begin()->second;
1723 int HardProcess::nQuarksOut(){
1725 for(
int i =0; i< int(hardOutgoing1.size()); ++i){
1726 if (hardOutgoing1[i] == 2212 || abs(hardOutgoing1[i]) < 10) nFin++;
1728 for(
int i =0; i< int(hardOutgoing2.size()); ++i){
1729 if (hardOutgoing2[i] == 2212 || abs(hardOutgoing2[i]) < 10) nFin++;
1733 for(
int i =0; i< int(hardOutgoing1.size()); ++i)
1734 if (hardOutgoing1[i] == 5000)
1735 for(
int j =0; j< int(PosOutgoing1.size()); ++j)
1736 if (state[PosOutgoing1[j]].idAbs() == 5)
1738 for(
int i =0; i< int(hardOutgoing2.size()); ++i)
1739 if (hardOutgoing2[i] == 5000)
1740 for(
int j =0; j< int(PosOutgoing2.size()); ++j)
1741 if (state[PosOutgoing2[j]].idAbs() == 5)
1751 int HardProcess::nLeptonOut(){
1753 for(
int i =0; i< int(hardOutgoing1.size()); ++i){
1754 if (abs(hardOutgoing1[i]) > 10 && abs(hardOutgoing1[i]) < 20) nFin++;
1756 if (abs(hardOutgoing1[i]) == 1000022) nFin++;
1758 if ( abs(hardOutgoing1[i]) == 1000011 || abs(hardOutgoing1[i]) == 2000011
1759 || abs(hardOutgoing1[i]) == 1000013 || abs(hardOutgoing1[i]) == 2000013
1760 || abs(hardOutgoing1[i]) == 1000015 || abs(hardOutgoing1[i]) == 2000015)
1763 for(
int i =0; i< int(hardOutgoing2.size()); ++i){
1764 if (abs(hardOutgoing2[i]) > 10 && abs(hardOutgoing2[i]) < 20) nFin++;
1766 if (abs(hardOutgoing2[i]) == 1000022) nFin++;
1768 if ( abs(hardOutgoing2[i]) == 1000011 || abs(hardOutgoing2[i]) == 2000011
1769 || abs(hardOutgoing2[i]) == 1000013 || abs(hardOutgoing2[i]) == 2000013
1770 || abs(hardOutgoing2[i]) == 1000015 || abs(hardOutgoing2[i]) == 2000015)
1777 for(
int i =0; i< int(hardOutgoing1.size()); ++i)
1778 if (hardOutgoing1[i] == 1100)
1779 for(
int j =0; j< int(PosOutgoing1.size()); ++j)
1780 if ( abs(state[PosOutgoing1[j]].
id()) == 11
1781 || abs(state[PosOutgoing1[j]].
id()) == 13
1782 || abs(state[PosOutgoing1[j]].
id()) == 15 )
1784 for(
int i =0; i< int(hardOutgoing2.size()); ++i)
1785 if (hardOutgoing2[i] == 1200)
1786 for(
int j =0; j< int(PosOutgoing2.size()); ++j)
1787 if ( abs(state[PosOutgoing2[j]].
id()) == 12
1788 || abs(state[PosOutgoing2[j]].
id()) == 14
1789 || abs(state[PosOutgoing2[j]].
id()) == 16 )
1799 int HardProcess::nBosonsOut(){
1801 for(
int i =0; i< int(hardOutgoing1.size()); ++i){
1802 if (abs(hardOutgoing1[i]) > 20 && abs(hardOutgoing1[i]) <= 25) nFin++;
1804 for(
int i =0; i< int(hardOutgoing2.size()); ++i){
1805 if (abs(hardOutgoing2[i]) > 20 && abs(hardOutgoing2[i]) <= 25) nFin++;
1806 if ( hardOutgoing2[i] == 2400) nFin++;
1816 int HardProcess::nQuarksIn(){
1818 if (hardIncoming1 == 2212 || abs(hardIncoming1) < 10) nIn++;
1819 if (hardIncoming2 == 2212 || abs(hardIncoming2) < 10) nIn++;
1828 int HardProcess::nLeptonIn(){
1830 if (abs(hardIncoming1) > 10 && abs(hardIncoming1) < 20) nIn++;
1831 if (abs(hardIncoming2) > 10 && abs(hardIncoming2) < 20) nIn++;
1840 int HardProcess::hasResInCurrent(){
1841 for(
int i =0; i< int(PosIntermediate.size()); ++i)
1842 if (PosIntermediate[i] == 0)
return 0;
1844 for(
int i =0; i< int(PosIntermediate.size()); ++i){
1845 for(
int j =0; j< int(PosOutgoing1.size()); ++j){
1846 if ( PosIntermediate[i] == PosOutgoing1[j] )
1849 for(
int j =0; j< int(PosOutgoing2.size()); ++j){
1850 if ( PosIntermediate[i] == PosOutgoing2[j] )
1862 int HardProcess::nResInCurrent(){
1864 for(
int i =0; i< int(PosIntermediate.size()); ++i){
1865 if (PosIntermediate[i] != 0) {
1866 bool matchesFinalBoson =
false;
1867 for(
int j =0; j< int(PosOutgoing1.size()); ++j){
1868 if ( PosIntermediate[i] == PosOutgoing1[j] )
1869 matchesFinalBoson =
true;
1871 for(
int j =0; j< int(PosOutgoing2.size()); ++j){
1872 if ( PosIntermediate[i] == PosOutgoing2[j] )
1873 matchesFinalBoson =
true;
1875 if (!matchesFinalBoson) nRes++;
1886 bool HardProcess::hasResInProc(){
1888 for(
int i =0; i< int(hardIntermediate.size()); ++i)
1889 if (hardIntermediate[i] == 0)
return false;
1891 for(
int i =0; i< int(hardIntermediate.size()); ++i){
1892 for(
int j =0; j< int(hardOutgoing1.size()); ++j){
1893 if ( hardIntermediate[i] == hardOutgoing1[j] )
1896 for(
int j =0; j< int(hardOutgoing2.size()); ++j){
1897 if ( hardIntermediate[i] == hardOutgoing2[j] )
1908 void HardProcess::list()
const {
1909 cout <<
" Hard Process: ";
1910 cout <<
" \t " << hardIncoming1 <<
" + " << hardIncoming2;
1911 cout <<
" \t -----> \t ";
1912 for(
int i =0; i < int(hardIntermediate.size());++i)
1913 cout << hardIntermediate[i] <<
" ";
1914 cout <<
" \t -----> \t ";
1915 for(
int i =0; i < int(hardOutgoing1.size());++i)
1916 cout << hardOutgoing1[i] <<
" ";
1917 for(
int i =0; i < int(hardOutgoing2.size());++i)
1918 cout << hardOutgoing2[i] <<
" ";
1927 void HardProcess::listCandidates()
const {
1928 cout <<
" Hard Process candidates: ";
1929 cout <<
" \t " << hardIncoming1 <<
" + " << hardIncoming2;
1930 cout <<
" \t -----> \t ";
1931 for(
int i =0; i < int(PosIntermediate.size());++i)
1932 cout << PosIntermediate[i] <<
" ";
1933 cout <<
" \t -----> \t ";
1934 for(
int i =0; i < int(PosOutgoing1.size());++i)
1935 cout << PosOutgoing1[i] <<
" ";
1936 for(
int i =0; i < int(PosOutgoing2.size());++i)
1937 cout << PosOutgoing2[i] <<
" ";
1945 void HardProcess::clear() {
1948 hardIncoming1 = hardIncoming2 = 0;
1950 hardOutgoing1.resize(0);
1951 hardOutgoing2.resize(0);
1953 hardIntermediate.resize(0);
1959 PosOutgoing1.resize(0);
1960 PosOutgoing2.resize(0);
1962 PosIntermediate.resize(0);
1977 void MergingHooks::init( Settings settings, Info* infoPtrIn,
1978 ParticleData* particleDataPtrIn, PartonSystems* partonSystemsPtrIn,
1982 infoPtr = infoPtrIn;
1983 particleDataPtr = particleDataPtrIn;
1984 partonSystemsPtr = partonSystemsPtrIn;
1987 double alphaSvalueFSR = settings.parm(
"TimeShower:alphaSvalue");
1988 int alphaSorderFSR = settings.mode(
"TimeShower:alphaSorder");
1989 int alphaSnfmax = settings.mode(
"StandardModel:alphaSnfmax");
1990 int alphaSuseCMWFSR= settings.flag(
"TimeShower:alphaSuseCMW");
1991 AlphaS_FSRSave.init(alphaSvalueFSR, alphaSorderFSR, alphaSnfmax,
1993 double alphaSvalueISR = settings.parm(
"SpaceShower:alphaSvalue");
1994 int alphaSorderISR = settings.mode(
"SpaceShower:alphaSorder");
1995 int alphaSuseCMWISR= settings.flag(
"SpaceShower:alphaSuseCMW");
1996 AlphaS_ISRSave.init(alphaSvalueISR, alphaSorderISR, alphaSnfmax,
2000 int alphaEMFSRorder = settings.mode(
"TimeShower:alphaEMorder");
2001 AlphaEM_FSRSave.init(alphaEMFSRorder, &settings);
2004 doUserMergingSave = settings.flag(
"Merging:doUserMerging");
2006 doMGMergingSave = settings.flag(
"Merging:doMGMerging");
2008 doKTMergingSave = settings.flag(
"Merging:doKTMerging");
2010 doPTLundMergingSave = settings.flag(
"Merging:doPTLundMerging");
2012 doCutBasedMergingSave = settings.flag(
"Merging:doCutBasedMerging");
2014 ktTypeSave = settings.mode(
"Merging:ktType");
2017 doNL3TreeSave = settings.flag(
"Merging:doNL3Tree");
2018 doNL3LoopSave = settings.flag(
"Merging:doNL3Loop");
2019 doNL3SubtSave = settings.flag(
"Merging:doNL3Subt");
2020 bool doNL3 = doNL3TreeSave || doNL3LoopSave || doNL3SubtSave;
2023 doUNLOPSTreeSave = settings.flag(
"Merging:doUNLOPSTree");
2024 doUNLOPSLoopSave = settings.flag(
"Merging:doUNLOPSLoop");
2025 doUNLOPSSubtSave = settings.flag(
"Merging:doUNLOPSSubt");
2026 doUNLOPSSubtNLOSave = settings.flag(
"Merging:doUNLOPSSubtNLO");
2027 bool doUNLOPS = doUNLOPSTreeSave || doUNLOPSLoopSave
2028 || doUNLOPSSubtSave || doUNLOPSSubtNLOSave;
2031 doUMEPSTreeSave = settings.flag(
"Merging:doUMEPSTree");
2032 doUMEPSSubtSave = settings.flag(
"Merging:doUMEPSSubt");
2033 nReclusterSave = settings.mode(
"Merging:nRecluster");
2034 nQuarksMergeSave = settings.mode(
"Merging:nQuarksMerge");
2035 bool doUMEPS = doUMEPSTreeSave || doUMEPSSubtSave;
2038 doEstimateXSection = settings.flag(
"Merging:doXSectionEstimate");
2041 processSave = settings.word(
"Merging:Process");
2044 hardProcess.clear();
2047 inputEvent.init(
"(hard process)", particleDataPtr);
2048 doRemoveDecayProducts = settings.flag(
"Merging:mayRemoveDecayProducts");
2051 if ( doMGMergingSave )
2052 hardProcess.initOnLHEF(lheInputFile, particleDataPtr);
2054 hardProcess.initOnProcess(processSave, particleDataPtr);
2057 includeMassiveSave = settings.flag(
"Merging:includeMassive");
2058 enforceStrongOrderingSave = settings.flag(
"Merging:enforceStrongOrdering");
2059 scaleSeparationFactorSave = settings.parm(
"Merging:scaleSeparationFactor");
2060 orderInRapiditySave = settings.flag(
"Merging:orderInRapidity");
2063 nonJoinedNormSave = settings.parm(
"Merging:nonJoinedNorm");
2064 fsrInRecNormSave = settings.parm(
"Merging:fsrInRecNorm");
2065 pickByFullPSave = settings.flag(
"Merging:pickByFullP");
2066 pickByPoPT2Save = settings.flag(
"Merging:pickByPoPT2");
2067 includeRedundantSave = settings.flag(
"Merging:includeRedundant");
2070 unorderedScalePrescipSave =
2071 settings.mode(
"Merging:unorderedScalePrescrip");
2072 unorderedASscalePrescipSave =
2073 settings.mode(
"Merging:unorderedASscalePrescrip");
2074 unorderedPDFscalePrescipSave =
2075 settings.mode(
"Merging:unorderedPDFscalePrescrip");
2076 incompleteScalePrescipSave =
2077 settings.mode(
"Merging:incompleteScalePrescrip");
2080 allowColourShufflingSave =
2081 settings.flag(
"Merging:allowColourShuffling");
2085 resetHardQRenSave = settings.flag(
"Merging:usePythiaQRenHard");
2086 resetHardQFacSave = settings.flag(
"Merging:usePythiaQFacHard");
2089 pickBySumPTSave = settings.flag(
"Merging:pickBySumPT");
2090 herwigAcollFSRSave = settings.parm(
"Merging:aCollFSR");
2091 herwigAcollISRSave = settings.parm(
"Merging:aCollISR");
2094 pT0ISRSave = settings.parm(
"SpaceShower:pT0Ref");
2095 pTcutSave = settings.parm(
"SpaceShower:pTmin");
2096 pTcutSave = max(pTcutSave,pT0ISRSave);
2099 weightCKKWLSave = 1.;
2100 weightFIRSTSave = 0.;
2106 tmsListSave.resize(0);
2108 kFactor0jSave = settings.parm(
"Merging:kFactor0j");
2109 kFactor1jSave = settings.parm(
"Merging:kFactor1j");
2110 kFactor2jSave = settings.parm(
"Merging:kFactor2j");
2112 muFSave = settings.parm(
"Merging:muFac");
2113 muRSave = settings.parm(
"Merging:muRen");
2114 muFinMESave = settings.parm(
"Merging:muFacInME");
2115 muRinMESave = settings.parm(
"Merging:muRenInME");
2117 doWClusteringSave = settings.flag(
"Merging:allowWClustering");
2118 doSQCDClusteringSave = settings.flag(
"Merging:allowSQCDClustering");
2119 DparameterSave = settings.parm(
"Merging:Dparameter");
2122 if ( doKTMergingSave || doUserMergingSave || doPTLundMergingSave
2125 tmsValueSave = settings.parm(
"Merging:TMS");
2126 nJetMaxSave = settings.mode(
"Merging:nJetMax");
2127 nJetMaxNLOSave = -1;
2128 }
else if (doMGMergingSave) {
2130 tmsValueSave = hardProcess.tms;
2131 nJetMaxSave = settings.mode(
"Merging:nJetMax");
2132 nJetMaxNLOSave = -1;
2133 }
else if (doCutBasedMergingSave) {
2136 nJetMaxSave = settings.mode(
"Merging:nJetMax");
2137 nJetMaxNLOSave = -1;
2140 tmsListSave.resize(0);
2141 double drms = settings.parm(
"Merging:dRijMS");
2142 double ptms = settings.parm(
"Merging:pTiMS");
2143 double qms = settings.parm(
"Merging:QijMS");
2144 tmsListSave.push_back(drms);
2145 tmsListSave.push_back(ptms);
2146 tmsListSave.push_back(qms);
2150 if ( doNL3 || doUNLOPS || doEstimateXSection ) {
2151 tmsValueSave = settings.parm(
"Merging:TMS");
2152 nJetMaxSave = settings.mode(
"Merging:nJetMax");
2153 nJetMaxNLOSave = settings.mode(
"Merging:nJetMaxNLO");
2156 bool writeBanner = doKTMergingSave || doMGMergingSave
2157 || doUserMergingSave
2158 || doNL3 || doUNLOPS || doUMEPS
2159 || doPTLundMergingSave || doCutBasedMergingSave;
2161 if (!writeBanner)
return;
2164 os <<
"\n *------------------ MEPS Merging Initialization ---------------"
2168 if ( doKTMergingSave || doMGMergingSave || doUserMergingSave
2169 || doPTLundMergingSave || doCutBasedMergingSave )
2170 os <<
" | CKKW-L merge "
2172 <<
" |"<< setw(34) << processSave <<
" with up to"
2173 << setw(3) << nJetMaxSave <<
" additional jets |\n";
2175 os <<
" | NL3 merge "
2177 <<
" |" << setw(31) << processSave <<
" with jets up to"
2178 << setw(3) << nJetMaxNLOSave <<
" correct to NLO |\n"
2179 <<
" | and up to" << setw(3) << nJetMaxSave
2180 <<
" additional jets included by CKKW-L merging at LO |\n";
2181 else if ( doUNLOPS )
2182 os <<
" | UNLOPS merge "
2184 <<
" |" << setw(31) << processSave <<
" with jets up to"
2185 << setw(3)<< nJetMaxNLOSave <<
" correct to NLO |\n"
2186 <<
" | and up to" << setw(3) << nJetMaxSave
2187 <<
" additional jets included by UMEPS merging at LO |\n";
2189 os <<
" | UMEPS merge "
2191 <<
" |" << setw(34) << processSave <<
" with up to"
2192 << setw(3) << nJetMaxSave <<
" additional jets |\n";
2194 if ( doKTMergingSave )
2195 os <<
" | Merging scale is defined in kT, with value ktMS = "
2196 << tmsValueSave <<
" GeV";
2197 else if ( doMGMergingSave )
2198 os <<
" | Perform automanted MG/ME merging \n"
2199 <<
" | Merging scale is defined in kT, with value ktMS = "
2200 << setw(6) << fixed << setprecision(1) << tmsValueSave <<
" GeV |";
2201 else if ( doUserMergingSave )
2202 os <<
" | Merging scale is defined by the user, with value tMS = "
2203 << setw(6) << fixed << setprecision(1) << tmsValueSave <<
" |";
2204 else if ( doPTLundMergingSave )
2205 os <<
" | Merging scale is defined by Lund pT, with value tMS = "
2206 << setw(6) << fixed << setprecision(1) << tmsValueSave <<
" GeV |";
2207 else if ( doCutBasedMergingSave )
2208 os <<
" | Merging scale is defined by combination of Delta R_{ij}, pT_i "
2210 <<
" | and Q_{ij} cut, with values "
2212 <<
" | Delta R_{ij,min} = "
2213 << setw(7) << scientific << setprecision(2) << tmsListSave[0]
2215 <<
" | pT_{i,min} = "
2216 << setw(6) << fixed << setprecision(1) << tmsListSave[1]
2218 <<
" | Q_{ij,min} = "
2219 << setw(6) << fixed << setprecision(1) << tmsListSave[2]
2221 else if ( doNL3TreeSave )
2222 os <<
" | Generate tree-level O(alpha_s)-subtracted events "
2224 <<
" | Merging scale is defined by Lund pT, with value tMS = "
2225 << setw(6) << fixed << setprecision(1) << tmsValueSave <<
" GeV |";
2226 else if ( doNL3LoopSave )
2227 os <<
" | Generate virtual correction unit-weight events "
2229 <<
" | Merging scale is defined by Lund pT, with value tMS = "
2230 << setw(6) << fixed << setprecision(1) << tmsValueSave <<
" GeV |";
2231 else if ( doNL3SubtSave )
2232 os <<
" | Generate reclustered tree-level events "
2234 <<
" | Merging scale is defined by Lund pT, with value tMS = "
2235 << setw(6) << fixed << setprecision(1) << tmsValueSave <<
" GeV |";
2236 else if ( doUNLOPSTreeSave )
2237 os <<
" | Generate tree-level O(alpha_s)-subtracted events "
2239 <<
" | Merging scale is defined by Lund pT, with value tMS = "
2240 << setw(6) << fixed << setprecision(1) << tmsValueSave <<
" GeV |";
2241 else if ( doUNLOPSLoopSave )
2242 os <<
" | Generate virtual correction unit-weight events "
2244 <<
" | Merging scale is defined by Lund pT, with value tMS = "
2245 << setw(6) << fixed << setprecision(1) << tmsValueSave <<
" GeV |";
2246 else if ( doUNLOPSSubtSave )
2247 os <<
" | Generate reclustered tree-level events "
2249 <<
" | Merging scale is defined by Lund pT, with value tMS = "
2250 << setw(6) << fixed << setprecision(1) << tmsValueSave <<
" GeV |";
2251 else if ( doUNLOPSSubtNLOSave )
2252 os <<
" | Generate reclustered loop-level events "
2254 <<
" | Merging scale is defined by Lund pT, with value tMS = "
2255 << setw(6) << fixed << setprecision(1) << tmsValueSave <<
" GeV |";
2256 else if ( doUMEPSTreeSave )
2257 os <<
" | Generate tree-level events "
2259 <<
" | Merging scale is defined by Lund pT, with value tMS = "
2260 << setw(6) << fixed << setprecision(1) << tmsValueSave <<
" GeV |";
2261 else if ( doUMEPSSubtSave )
2262 os <<
" | Generate reclustered tree-level events "
2264 <<
" | Merging scale is defined by Lund pT, with value tMS = "
2265 << setw(6) << fixed << setprecision(1) << tmsValueSave <<
" GeV |";
2269 os <<
"\n *-------------- END MEPS Merging Initialization ---------------"
2278 bool MergingHooks::doVetoEmission(
const Event& event) {
2281 if ( doIgnoreEmissionsSave )
return false;
2284 if ( doUserMerging() || doMGMerging() || doKTMerging()
2285 || doPTLundMerging() || doCutBasedMerging() )
2291 int nSteps = getNumberOfClusteringSteps(event);
2293 double tnow = rhoms( event,
false);
2296 int nJetMax = nMaxJets();
2299 if ( nRecluster() > 0 ) nSteps = max(1, min(nJetMax-2, 1));
2301 if ( nSteps - 1 < nJetMax && nSteps >= 1 && tnow > tms() ) veto =
true;
2304 if ( infoPtr->nMPI() > 1 ) veto =
false;
2308 if ( veto && doNL3Tree() ) setWeightCKKWL(0.);
2311 if ( !veto ) doIgnoreEmissionsSave =
true;
2322 bool MergingHooks::doVetoStep(
const Event& process,
const Event& event,
2323 bool doResonance ) {
2326 if ( doIgnoreStepSave && !doResonance )
return false;
2329 if ( doUMEPSTree() || doUMEPSSubt() || doUMEPSMerging() || doUNLOPSTree()
2330 || doUNLOPSLoop() || doUNLOPSSubt() || doUNLOPSSubtNLO()
2331 || doUNLOPSMerging() )
2336 int nSteps = (doResonance) ? getNumberOfClusteringSteps(process)
2337 : getNumberOfClusteringSteps( bareEvent( process,
false) );
2339 int nJetMax = nMaxJets();
2341 double tnow = tmsNow( event );
2346 if ( !doResonance ) {
2349 pTsave = infoPtr->pTnow();
2350 if ( nRecluster() == 1) nSteps--;
2354 if ( nSteps > nMaxJetsNLO() && nSteps < nJetMax && tnow > tms() ) {
2356 weightCKKWL1Save = 0.;
2358 weightCKKWL2Save = getWeightCKKWL();
2375 bool revokeVeto =
false;
2381 bool check = (nHardInLeptons() == 0)&& (nHardOutLeptons() == 2)
2382 && (nHardOutPartons() == 2);
2390 if ( pTsave > 0. && check ) {
2393 int nResNow = nResInCurrent();
2400 int sysSize = partonSystemsPtr->sizeSys();
2401 for (
int i=0; i < nResNow; ++i ) {
2402 if ( partonSystemsPtr->sizeOut(sysSize - 1 - i) == 3 )
2403 goodSys.push_back(sysSize - 1 - i);
2407 for (
int i=0; i < int(goodSys.size()); ++i ) {
2410 int iMem1 = partonSystemsPtr->getOut(goodSys[i],0);
2411 int iMem2 = partonSystemsPtr->getOut(goodSys[i],1);
2412 int iMem3 = partonSystemsPtr->getOut(goodSys[i],2);
2415 int iEmtGlue = ((
event[iMem1].id() == 21) ? iMem1
2416 : ((event[iMem2].
id() == 21) ? iMem2
2417 : ((
event[iMem3].id() == 21) ? iMem3: 0)));
2418 int iEmtGamm = ((
event[iMem1].id() == 22) ? iMem1
2419 : ((event[iMem2].
id() == 22) ? iMem2
2420 : ((
event[iMem3].id() == 22) ? iMem3: 0)));
2422 int iEmt = (iEmtGlue != 0) ? iEmtGlue : iEmtGamm;
2426 if ( iEmt == iMem1 ) {
2427 iRad = (
event[iMem2].mother1() !=
event[iMem2].mother2())
2429 iRec = (
event[iMem3].mother1() ==
event[iMem3].mother2())
2431 }
else if ( iEmt == iMem2 ) {
2432 iRad = (
event[iMem1].mother1() !=
event[iMem1].mother2())
2434 iRec = (
event[iMem3].mother1() ==
event[iMem3].mother2())
2437 iRad = (
event[iMem1].mother1() !=
event[iMem1].mother2())
2439 iRec = (
event[iMem2].mother1() ==
event[iMem2].mother2())
2443 double pTres = rhoPythia(event[iRad], event[iEmt], event[iRec], 1);
2448 if ( pTres > pTsave ) {
2462 if ( revokeVeto && check ) {
2463 setWeightCKKWL(weightCKKWL2Save);
2464 }
else if ( check ) {
2465 setWeightCKKWL(weightCKKWL1Save);
2466 if ( weightCKKWL1Save == 0. ) veto =
true;
2470 if ( !check && nSteps > nMaxJetsNLO() && nSteps < nJetMax && tnow > tms()){
2478 if ( !veto || !doIgnoreStepSave ) doIgnoreStepSave =
true;
2494 Event MergingHooks::bareEvent(
const Event& inputEventIn,
2495 bool storeInputEvent ) {
2499 newProcess.init(
"(hard process-modified)", particleDataPtr);
2502 if ( storeInputEvent ) {
2503 resonances.resize(0);
2505 for (
int i = 0; i < inputEventIn.size(); ++i)
2506 inputEvent.append( inputEventIn[i] );
2507 for (
int i = 0; i < inputEventIn.sizeJunction(); ++i)
2508 inputEvent.appendJunction( inputEventIn.getJunction(i) );
2509 inputEvent.saveSize();
2510 inputEvent.saveJunctionSize();
2514 if ( doRemoveDecayProducts ) {
2517 for (
int i = 0; i < inputEventIn.size(); ++ i) {
2518 if ( inputEventIn[i].mother1() > 4
2519 || inputEventIn[i].statusAbs() == 22
2520 || inputEventIn[i].statusAbs() == 23)
2522 newProcess.append(inputEventIn[i]);
2526 for (
int i = 0; i < inputEventIn.size(); ++ i) {
2527 if (inputEventIn[i].mother1() > 4)
break;
2528 if ( inputEventIn[i].status() == -22) {
2529 int j = newProcess.append(inputEventIn[i]);
2530 newProcess[j].statusPos();
2531 if ( storeInputEvent ) resonances.push_back( make_pair(j, i) );
2532 newProcess[j].daughters(0, 0);
2537 for (
int i = 0; i < inputEventIn.size(); ++ i) {
2538 if (inputEventIn[i].mother1() > 4)
break;
2539 if ( inputEventIn[i].statusAbs() != 11
2540 && inputEventIn[i].statusAbs() != 12
2541 && inputEventIn[i].statusAbs() != 21
2542 && inputEventIn[i].statusAbs() != 22)
2543 newProcess.append(inputEventIn[i]);
2548 for (
int i = 0; i < inputEventIn.size(); ++ i) {
2549 if ( inputEventIn[i].col() > maxColTag )
2550 maxColTag = inputEventIn[i].col();
2551 if ( inputEventIn[i].acol() > maxColTag )
2552 maxColTag = inputEventIn[i].acol();
2554 newProcess.initColTag(maxColTag);
2557 for (
int i = 0; i < inputEventIn.sizeJunction(); ++i)
2558 newProcess.appendJunction( inputEventIn.getJunction(i));
2560 newProcess.saveSize();
2561 newProcess.saveJunctionSize();
2564 newProcess = inputEventIn;
2568 newProcess.scale( inputEventIn.scale() );
2580 bool MergingHooks::reattachResonanceDecays(
Event& process ) {
2583 if ( doRemoveDecayProducts && inputEvent.size() > 0 ) {
2585 int sizeBef = process.size();
2587 vector<int> iAftChecked;
2589 for (
int i = 0; i < int(resonances.size()); ++i ) {
2590 for (
int j = 0; j < sizeBef; ++j ) {
2591 if ( j != resonances[i].first )
continue;
2593 int iOldDaughter1 = inputEvent[resonances[i].second].daughter1();
2594 int iOldDaughter2 = inputEvent[resonances[i].second].daughter2();
2597 int iHardMother = resonances[i].second;
2598 Particle& hardMother = inputEvent[iHardMother];
2601 for (
int k = 0; k < process.size(); ++k )
2602 if ( process[k].
id() == inputEvent[resonances[i].second].id() ) {
2604 bool checked =
false;
2605 for (
int l = 0; l < int(iAftChecked.size()); ++l )
2606 if ( k == iAftChecked[l] )
2609 iAftChecked.push_back(k);
2615 Particle& aftMother = process[iAftMother];
2619 int colBef = hardMother.col();
2620 int acolBef = hardMother.acol();
2621 int colAft = aftMother.col();
2622 int acolAft = aftMother.acol();
2624 M.bst( hardMother.p(), aftMother.p());
2627 int iNewDaughter1 = 0;
2628 int iNewDaughter2 = 0;
2629 for (
int k = iOldDaughter1; k <= iOldDaughter2; ++k ) {
2630 if ( k == iOldDaughter1 )
2631 iNewDaughter1 = process.append(inputEvent[k] );
2633 iNewDaughter2 = process.append(inputEvent[k] );
2634 process.back().statusPos();
2635 Particle& now = process.back();
2637 if (now.col() != 0 && now.col() == colBef ) now.col(colAft);
2638 if (now.acol() != 0 && now.acol() == acolBef) now.acol(acolAft);
2641 if (now.hasVertex()) now.vProd( aftMother.vDec() );
2643 now.mothers(iAftMother,0);
2646 process[iAftMother].daughters( iNewDaughter1, iNewDaughter2 );
2647 process[iAftMother].statusNeg();
2652 if ( process[iDec].isFinal() && process[iDec].canDecay()
2653 && process[iDec].mayDecay() && process[iDec].isResonance() ) {
2655 int iD1 = process[iDec].daughter1();
2656 int iD2 = process[iDec].daughter2();
2659 if ( iD1 == 0 || iD2 == 0 )
continue;
2662 int iNewDaughter12 = 0;
2663 int iNewDaughter22 = 0;
2664 for (
int k = iD1; k <= iD2; ++k ) {
2666 iNewDaughter12 = process.append(inputEvent[k] );
2668 iNewDaughter22 = process.append(inputEvent[k] );
2669 process.back().statusPos();
2670 Particle& now = process.back();
2672 if (now.col() != 0 && now.col() == colBef ) now.col(colAft);
2673 if (now.acol()!= 0 && now.acol()== acolBef) now.acol(acolAft);
2676 if (now.hasVertex()) now.vProd( process[iDec].vDec() );
2678 now.mothers(iDec,0);
2682 process[iDec].status(-22);
2683 process[iDec].daughters(iNewDaughter12, iNewDaughter22);
2687 }
while (++iDec < process.size());
2693 for (
int i = 0; i < process.size(); ++ i) {
2694 if (process[i].col() > maxColTag) maxColTag = process[i].col();
2695 if (process[i].acol() > maxColTag) maxColTag = process[i].acol();
2697 process.initColTag(maxColTag);
2702 return (doRemoveDecayProducts) ? inputEvent.size() > 0 :
true;
2708 bool MergingHooks::isInHard(
int iPos,
const Event& event){
2711 if ( event[iPos].statusAbs() > 30 && event[iPos].statusAbs() < 40 )
2714 if ( event[iPos].statusAbs() > 60 )
2719 vector<int> mpiParticlePos;
2720 mpiParticlePos.clear();
2721 for (
int i=0; i <
event.size(); ++i )
2722 if ( event[i].statusAbs() > 30
2723 &&
event[i].statusAbs() < 40 )
2724 mpiParticlePos.push_back(i);
2726 for (
int i=0; i < int(mpiParticlePos.size()); ++i)
2727 if ( event.isAncestor(iPos, mpiParticlePos[i]) )
2732 int iSys = partonSystemsPtr->getSystemOf(iPos, !event[iPos].isFinal() );
2737 int sysSize = partonSystemsPtr->sizeAll(iSys);
2738 for (
int i = 0; i < sysSize; ++i ) {
2739 int iPosNow = partonSystemsPtr->getAll( iSys, i );
2741 if ( event[iPosNow].statusAbs() > 30
2742 && event[iPosNow].statusAbs() < 40 )
2745 for (
int j=0; j < int(mpiParticlePos.size()); ++j)
2746 if ( event.isAncestor(iPosNow, mpiParticlePos[j]) )
2749 if ( event[iPosNow].statusAbs() > 60 )
2756 bool containsInitialParton =
false;
2760 if (iUp <= 0 || iUp > event.size())
break;
2762 if ( iUp == 3 || iUp == 4 ) {
2763 containsInitialParton =
true;
2766 if ( event[iUp].mother1() == 1
2767 && (
event[iUp].daughter1() == 3 ||
event[iUp].daughter2() == 3) ) {
2768 containsInitialParton =
true;
2771 if ( event[iUp].mother1() == 2
2772 && (
event[iUp].daughter1() == 4 ||
event[iUp].daughter2() == 4) ) {
2773 containsInitialParton =
true;
2777 iUp =
event[iUp].mother1();
2780 if ( !containsInitialParton )
return false;
2791 int MergingHooks::getNumberOfClusteringSteps(
const Event& event){
2794 int nFinalPartons = 0;
2795 for (
int i=0; i <
event.size(); ++i)
2796 if ( event[i].isFinal()
2797 && isInHard( i, event)
2798 && (
event[i].isQuark() ||
event[i].isGluon()) )
2802 int nFinalLeptons = 0;
2803 for(
int i=0; i <
event.size(); ++i)
2804 if ( event[i].isFinal() && isInHard( i, event) &&
event[i].isLepton())
2808 for(
int i=0; i <
event.size(); ++i)
2809 if ( event[i].isFinal() && isInHard( i, event)
2810 &&
event[i].idAbs() == 1000022)
2814 for(
int i=0; i <
event.size(); ++i)
2815 if ( event[i].isFinal() && isInHard( i, event)
2816 && (
event[i].idAbs() == 1000011
2817 ||
event[i].idAbs() == 2000011
2818 ||
event[i].idAbs() == 1000013
2819 ||
event[i].idAbs() == 2000013
2820 ||
event[i].idAbs() == 1000015
2821 ||
event[i].idAbs() == 2000015) )
2825 int nFinalBosons = 0;
2826 for(
int i=0; i <
event.size(); ++i)
2827 if ( event[i].isFinal() && isInHard( i, event)
2828 && (
event[i].idAbs() == 22
2829 ||
event[i].idAbs() == 23
2830 ||
event[i].idAbs() == 24
2831 ||
event[i].idAbs() == 25 ) )
2835 int nFinal = nFinalPartons + nFinalLeptons
2836 + 2*(nFinalBosons - nHardOutBosons() );
2839 return (nFinal - nHardOutPartons() - nHardOutLeptons() );
2848 bool MergingHooks::isFirstEmission(
const Event& event ) {
2852 for (
int i=0; i <
event.size(); ++i)
2853 if ( event[i].statusAbs() > 60 )
return false;
2856 int nFinalQuarks = 0;
2857 int nFinalGluons = 0;
2858 int nFinalLeptons = 0;
2859 int nFinalBosons = 0;
2860 int nFinalPhotons = 0;
2862 for(
int i=0; i <
event.size(); ++i) {
2863 if (event[i].isFinal() && isInHard(i, event) ){
2864 if ( event[i].spinType() == 2 &&
event[i].colType() == 0)
2866 if ( event[i].
id() == 23
2867 ||
event[i].idAbs() == 24
2868 ||
event[i].id() == 25)
2870 if ( event[i].
id() == 22)
2872 if ( event[i].isQuark())
2874 if ( event[i].isGluon())
2876 if ( !event[i].isDiquark() )
2883 if (nFinalQuarks + nFinalGluons == 0)
return false;
2886 int nLeptons = nHardOutLeptons();
2890 if (nFinalLeptons > nLeptons)
return false;
2895 for(
int i =0; i< int(hardProcess.hardOutgoing1.size()); ++i)
2896 if (hardProcess.hardOutgoing1[i] == 22)
2898 for(
int i =0; i< int(hardProcess.hardOutgoing2.size()); ++i)
2899 if (hardProcess.hardOutgoing2[i] == 22)
2901 if (nFinalPhotons > nPhotons)
return false;
2912 bool MergingHooks::setShowerStartingScales(
bool isTrial,
2913 bool doMergeFirstEmm,
double& pTscaleIn,
const Event& event,
2914 double& pTmaxFSRIn,
bool& limitPTmaxFSRIn,
2915 double& pTmaxISRIn,
bool& limitPTmaxISRIn,
2916 double& pTmaxMPIIn,
bool& limitPTmaxMPIIn ) {
2920 bool isPureQCD = ( getProcessString().compare(
"pp>jj") == 0 );
2921 int nSteps = getNumberOfClusteringSteps( bareEvent(event,
false) );
2922 double scale =
event.scale();
2924 bool doRecluster = doUMEPSSubt() || doNL3Subt() || doUNLOPSSubt()
2925 || doUNLOPSSubtNLO();
2930 pTmaxISRIn = pTmaxFSRIn = scale;
2931 if ( limitPTmaxISRIn ) pTmaxISRIn = min(scale,muF());
2932 if ( limitPTmaxFSRIn ) pTmaxFSRIn = min(scale,muF());
2934 if ( !isPureQCD ) pTmaxMPIIn = scale;
2935 else pTmaxMPIIn = infoPtr->eCM();
2937 if ( pTscaleIn < infoPtr->eCM() ) {
2938 limitPTmaxISRIn = limitPTmaxFSRIn =
true;
2939 if ( !isPureQCD ) limitPTmaxMPIIn =
true;
2940 else limitPTmaxMPIIn =
false;
2945 if ( isPureQCD && doMergeFirstEmm ) {
2947 if ( nSteps == 0 && !doRecluster && pTscaleIn < infoPtr->eCM() ) {
2948 pTmaxMPIIn = infoPtr->eCM();
2949 limitPTmaxMPIIn =
false;
2954 if ( !isPureQCD && doMergeFirstEmm ) {
2956 if ( nSteps == 0 && !doRecluster ) {
2957 pTscaleIn = infoPtr->eCM();
2958 limitPTmaxMPIIn =
false;
2960 if ( limitPTmaxISRIn ) pTscaleIn = min(scale,muF());
2961 if ( limitPTmaxFSRIn ) pTscaleIn = min(scale,muF());
2962 pTmaxISRIn = pTmaxFSRIn = pTscaleIn;
2964 if ( pTscaleIn < infoPtr->eCM()
2965 && !(nSteps == 0 && !doRecluster
2966 && (limitPTmaxISRIn || limitPTmaxFSRIn)) ) {
2967 pTmaxMPIIn = pTscaleIn;
2968 limitPTmaxMPIIn =
true;
2971 pTmaxMPIIn = muMI();
2972 limitPTmaxMPIIn =
true;
2986 double MergingHooks::tmsNow(
const Event& event ) {
2991 if ( doKTMerging() || doMGMerging() )
2994 else if ( doPTLundMerging() )
2995 tnow = rhoms(event,
false);
2997 else if ( doCutBasedMerging() )
2998 tnow = cutbasedms(event);
3000 else if ( doNL3Merging() )
3001 tnow = rhoms(event,
false);
3003 else if ( doUNLOPSMerging() )
3004 tnow = rhoms(event,
false);
3006 else if ( doUMEPSMerging() )
3007 tnow = rhoms(event,
false);
3010 tnow = tmsDefinition(event);
3020 bool MergingHooks::checkAgainstCut(
const Particle& particle){
3023 if (particle.colType() == 0)
return false;
3025 if ( particle.idAbs() != 21 && particle.idAbs() > nQuarksMergeSave )
3037 double MergingHooks::kTms(
const Event& event) {
3040 if (!isFirstEmission(event))
return 0.;
3043 vector<int> ewResonancePos;
3044 ewResonancePos.clear();
3045 for (
int i=0; i <
event.size(); ++i)
3046 if ( abs(event[i].status()) == 22
3047 && (
event[i].idAbs() == 22
3048 ||
event[i].idAbs() == 23
3049 ||
event[i].idAbs() == 24
3050 ||
event[i].idAbs() == 25
3051 ||
event[i].idAbs() == 6 ) )
3052 ewResonancePos.push_back(i);
3055 vector <int> FinalPartPos;
3056 FinalPartPos.clear();
3059 for (
int i=0; i <
event.size(); ++i){
3060 if ( event[i].isFinal()
3061 && isInHard( i, event )
3062 &&
event[i].colType() != 0
3063 && checkAgainstCut(event[i]) ){
3064 bool isDecayProduct =
false;
3065 for(
int j=0; j < int(ewResonancePos.size()); ++j)
3066 if ( event.isAncestor(i, ewResonancePos[j]) )
3067 isDecayProduct =
true;
3069 if ( !isDecayProduct
3070 || getProcessString().compare(
"e+e->jj") == 0
3071 || getProcessString().compare(
"e+e->(z>jj)") == 0 )
3072 FinalPartPos.push_back(i);
3078 int type = (
event[3].colType() == 0
3079 &&
event[4].colType() == 0) ? -1 : ktTypeSave;
3081 double ktmin =
event[0].e();
3082 for(
int i=0; i < int(FinalPartPos.size()); ++i){
3083 double kt12 = ktmin;
3085 if (type == 1 || type == 2) {
3086 double temp =
event[FinalPartPos[i]].pT();
3087 kt12 = min(kt12, temp);
3090 for(
int j=i+1; j < int(FinalPartPos.size()); ++j) {
3091 double temp = kTdurham( event[FinalPartPos[i]], event[FinalPartPos[j]],
3092 type, DparameterSave);
3093 kt12 = min(kt12, temp);
3096 ktmin = min(ktmin,kt12);
3108 double MergingHooks::kTdurham(
const Particle& RadAfterBranch,
3109 const Particle& EmtAfterBranch,
int Type,
double D ){
3114 Vec4 jet1 = RadAfterBranch.p();
3115 Vec4 jet2 = EmtAfterBranch.p();
3121 if (jet1.pAbs()*jet2.pAbs() <=0.) costh = 1.;
3123 costh = costheta(jet1,jet2);
3126 ktdur = 2.0*min( pow(jet1.e(),2) , (pow(jet2.e(),2)) )*(1.0 - costh);
3127 }
else if ( Type == 1 ){
3130 double mT1sq = jet1.m2Calc() + jet1.pT2();
3132 if (mT1sq < 0) mT1 = - sqrt(-mT1sq);
3133 else mT1 = sqrt(mT1sq);
3135 double mT2sq = jet2.m2Calc() + jet2.pT2();
3137 if (mT2sq < 0) mT2 = - sqrt(-mT2sq);
3138 else mT2 = sqrt(mT2sq);
3140 double y1 = log( ( jet1.e() + abs(jet1.pz()) ) / mT1 );
3141 if (jet1.pz() < 0) y1 *= -1.;
3143 double y2 = log( ( jet2.e() + abs(jet2.pz()) ) / mT2 );
3144 if (jet2.pz() < 0) y2 *= -1.;
3146 double pt1 = sqrt( pow(jet1.px(),2) + pow(jet1.py(),2) );
3147 double pt2 = sqrt( pow(jet2.px(),2) + pow(jet2.py(),2) );
3148 double cosdPhi = ( jet1.px()*jet2.px() + jet1.py()*jet2.py() ) / (pt1*pt2);
3149 double dPhi = acos( cosdPhi );
3152 ktdur = min( pow(pt1,2),pow(pt2,2) )
3153 * ( pow(y1-y2,2) + pow(dPhi,2) ) / pow(D,2);
3154 }
else if ( Type == 2 ){
3157 double mT1sq = jet1.m2Calc() + jet1.pT2();
3159 if (mT1sq < 0) mT1 = - sqrt(-mT1sq);
3160 else mT1 = sqrt(mT1sq);
3162 double mT2sq = jet2.m2Calc() + jet2.pT2();
3164 if (mT2sq < 0) mT2 = - sqrt(-mT2sq);
3165 else mT2 = sqrt(mT2sq);
3167 double eta1 = log( ( sqrt(jet1.px()*jet1.px() + jet1.py()*jet1.py()
3168 + jet1.pz()*jet1.pz()) + abs(jet1.pz()) ) / mT1);
3169 if (jet1.pz() < 0) eta1 *= -1.;
3171 double eta2 = log( ( sqrt(jet2.px()*jet2.px() + jet2.py()*jet2.py()
3172 + jet2.pz()*jet2.pz()) + abs(jet2.pz()) ) / mT2);
3173 if (jet2.pz() < 0) eta2 *= -1.;
3176 double pt1 = sqrt( pow(jet1.px(),2) + pow(jet1.py(),2) );
3177 double pt2 = sqrt( pow(jet2.px(),2) + pow(jet2.py(),2) );
3178 double cosdPhi = ( jet1.px()*jet2.px() + jet1.py()*jet2.py() ) / (pt1*pt2);
3179 double dPhi = acos( cosdPhi );
3181 ktdur = min( pow(pt1,2),pow(pt2,2) )
3182 * ( pow(eta1-eta2,2) + pow(dPhi,2) ) / pow(D,2);
3183 }
else if ( Type == 3 ){
3185 double eta1 = 0.5*log( (jet1.e() + jet1.pz()) / (jet1.e() - jet1.pz()) );
3186 double eta2 = 0.5*log( (jet2.e() + jet2.pz()) / (jet2.e() - jet2.pz()) );
3187 double coshdEta = cosh( eta1 - eta2 );
3189 double pt1 = sqrt( pow(jet1.px(),2) + pow(jet1.py(),2) );
3190 double pt2 = sqrt( pow(jet2.px(),2) + pow(jet2.py(),2) );
3191 double cosdPhi = ( jet1.px()*jet2.px() + jet1.py()*jet2.py() ) / (pt1*pt2);
3193 ktdur = 2.0*min( pow(pt1,2),pow(pt2,2) )
3194 * ( coshdEta - cosdPhi ) / pow(D,2);
3208 double MergingHooks::rhoms(
const Event& event,
bool withColour){
3211 if (!isFirstEmission(event))
return 0.;
3214 vector<int> ewResonancePos;
3215 ewResonancePos.clear();
3216 for (
int i=0; i <
event.size(); ++i)
3217 if ( abs(event[i].status()) == 22
3218 && (
event[i].idAbs() == 22
3219 ||
event[i].idAbs() == 23
3220 ||
event[i].idAbs() == 24
3221 ||
event[i].idAbs() == 25
3222 ||
event[i].idAbs() == 6 ) )
3223 ewResonancePos.push_back(i);
3226 vector <int> FinalPartPos;
3227 FinalPartPos.clear();
3230 for (
int i=0; i <
event.size(); ++i){
3232 if ( event[i].isFinal()
3233 && isInHard( i, event )
3234 &&
event[i].colType() != 0
3235 && checkAgainstCut(event[i]) ){
3236 bool isDecayProduct =
false;
3237 for(
int j=0; j < int(ewResonancePos.size()); ++j)
3238 if ( event.isAncestor(i, ewResonancePos[j]) )
3239 isDecayProduct =
true;
3241 if ( !isDecayProduct
3242 || getProcessString().compare(
"e+e->jj") == 0
3243 || getProcessString().compare(
"e+e->(z>jj)") == 0 )
3244 FinalPartPos.push_back(i);
3250 for (
int i=0; i <
event.size(); ++i)
3251 if (abs(event[i].status()) == 41 ){
3258 for (
int i=0; i <
event.size(); ++i)
3259 if (abs(event[i].status()) == 42 ){
3265 if (in1 == 0 || in2 == 0){
3267 for(
int i=3; i < int(event.size()); ++i){
3268 if ( !isInHard( i, event ) )
continue;
3269 if (event[i].mother1() == 1) in1 = i;
3270 if (event[i].mother1() == 2) in2 = i;
3275 double ptmin =
event[0].e();
3276 for(
int i=0; i < int(FinalPartPos.size()); ++i){
3277 double pt12 = ptmin;
3279 if (event[in1].colType() != 0) {
3280 double temp = rhoPythia( event[in1],
3281 event[FinalPartPos[i]], event[in2], -1 );
3282 pt12 = min(pt12, temp);
3286 if ( event[in2].colType() != 0) {
3287 double temp = rhoPythia( event[in2],
3288 event[FinalPartPos[i]], event[in1], -1 );
3289 pt12 = min(pt12, temp);
3295 for(
int j=0; j < int(FinalPartPos.size()); ++j) {
3299 bool isHard =
false;
3300 int radAcl =
event[FinalPartPos[i]].acol();
3301 int radCol =
event[FinalPartPos[i]].col();
3302 int emtAcl =
event[FinalPartPos[j]].acol();
3303 int emtCol =
event[FinalPartPos[j]].col();
3306 if (iRec <= 0 && radAcl > 0 && radAcl != emtCol)
3307 iRec = findColour(radAcl, FinalPartPos[i], FinalPartPos[j],
3309 if (iRec <= 0 && radCol > 0 && radCol != emtAcl)
3310 iRec = findColour(radCol, FinalPartPos[i], FinalPartPos[j],
3312 if (iRec <= 0 && emtAcl > 0 && emtAcl != radCol)
3313 iRec = findColour(emtAcl, FinalPartPos[i], FinalPartPos[j],
3315 if (iRec <= 0 && emtCol > 0 && emtCol != radAcl)
3316 iRec = findColour(emtCol, FinalPartPos[i], FinalPartPos[j],
3320 if (iRec <= 0 && radAcl > 0 && radAcl != emtCol)
3321 iRec = findColour(radAcl, FinalPartPos[i], FinalPartPos[j],
3323 if (iRec <= 0 && radCol > 0 && radCol != emtAcl)
3324 iRec = findColour(radCol, FinalPartPos[i], FinalPartPos[j],
3326 if (iRec <= 0 && emtAcl > 0 && emtAcl != radCol)
3327 iRec = findColour(emtAcl, FinalPartPos[i], FinalPartPos[j],
3329 if (iRec <= 0 && emtCol > 0 && emtCol != radAcl)
3330 iRec = findColour(emtCol, FinalPartPos[i], FinalPartPos[j],
3334 double temp = rhoPythia( event[FinalPartPos[i]],
3335 event[FinalPartPos[j]],
3337 pt12 = min(pt12, temp);
3345 for(
int j=0; j < int(FinalPartPos.size()); ++j) {
3346 for(
int k=0; k < int(FinalPartPos.size()); ++k) {
3348 if ( (i != j) && (i != k) && (j != k) ){
3353 temp = rhoPythia( event[FinalPartPos[i]],
3354 event[FinalPartPos[j]],
3355 event[FinalPartPos[k]], 1 );
3356 pt12 = min(pt12, temp);
3363 if ( event[in1].colType() != 0 && event[in2].colType() != 0) {
3364 for(
int j=0; j < int(FinalPartPos.size()); ++j) {
3368 double temp = rhoPythia( event[FinalPartPos[i]],
3369 event[FinalPartPos[j]],
3371 pt12 = min(pt12, temp);
3373 temp = rhoPythia( event[FinalPartPos[i]],
3374 event[FinalPartPos[j]],
3376 pt12 = min(pt12, temp);
3383 ptmin = min(ptmin,pt12);
3395 double MergingHooks::rhoPythia(
const Particle& RadAfterBranch,
3396 const Particle& EmtAfterBranch,
3397 const Particle& RecAfterBranch,
int ShowerType){
3400 int Type = ShowerType;
3402 int sign = (Type==1) ? 1 : -1;
3403 Vec4 Q(RadAfterBranch.p() + sign*EmtAfterBranch.p());
3404 double Qsq = sign * Q.m2Calc();
3406 double m2Rad = ( includeMassive()
3407 && abs(RadAfterBranch.id()) >= 4
3408 && abs(RadAfterBranch.id()) < 7)
3409 ? pow(particleDataPtr->m0(RadAfterBranch.id()), 2)
3412 Vec4 sum = RadAfterBranch.p() + RecAfterBranch.p()
3413 + EmtAfterBranch.p();
3414 double m2Dip = sum.m2Calc();
3415 double x1 = 2. * (sum * RadAfterBranch.p()) / m2Dip;
3416 double x3 = 2. * (sum * EmtAfterBranch.p()) / m2Dip;
3418 Vec4 qBR(RadAfterBranch.p() - EmtAfterBranch.p() + RecAfterBranch.p());
3419 Vec4 qAR(RadAfterBranch.p() + RecAfterBranch.p());
3421 double z = (Type==1) ? x1/(x1+x3)
3422 : (qBR.m2Calc())/( qAR.m2Calc());
3424 double pTpyth = (Type==1) ? z*(1.-z) : (1.-z);
3426 pTpyth *= (Qsq - sign*m2Rad);
3427 if (pTpyth < 0.) pTpyth = 0.;
3429 return sqrt(pTpyth);
3450 int MergingHooks::findColour(
int col,
int iExclude1,
int iExclude2,
3451 const Event& event,
int type,
bool isHardIn){
3453 bool isHard = isHardIn;
3458 for(
int n = 0; n <
event.size(); ++n) {
3459 if ( n != iExclude1 && n != iExclude2
3460 && event[n].colType() != 0
3461 &&(
event[n].status() > 0
3462 ||
event[n].status() == -21) ) {
3463 if ( event[n].acol() == col ) {
3467 if ( event[n].col() == col ){
3476 for(
int n = 0; n <
event.size(); ++n) {
3477 if ( n != iExclude1 && n != iExclude2
3478 && event[n].colType() != 0
3479 &&(
event[n].status() == 43
3480 ||
event[n].status() == 51
3481 ||
event[n].status() == 52
3482 ||
event[n].status() == -41
3483 ||
event[n].status() == -42) ) {
3484 if ( event[n].acol() == col ) {
3488 if ( event[n].col() == col ){
3496 if ( type == 1 && index < 0)
return abs(index);
3497 if ( type == 2 && index > 0)
return abs(index);
3507 double MergingHooks::cutbasedms(
const Event& event ){
3510 if (!isFirstEmission(event))
return -1.;
3513 vector<int> partons;
3514 for(
int i=0; i <
event.size(); ++i) {
3515 if ( event[i].isFinal()
3516 && isInHard( i, event )
3517 && checkAgainstCut(event[i]) )
3518 partons.push_back(i);
3522 bool doVeto =
false;
3524 bool vetoPT =
false;
3525 bool vetoRjj =
false;
3526 bool vetoMjj =
false;
3528 double pTjmin = pTiMS();
3529 double mjjmin = QijMS();
3530 double rjjmin = dRijMS();
3533 double minPT =
event[0].e();
3534 double minRJJ = 10.;
3535 double minMJJ =
event[0].e();
3538 for(
int i=0; i < int(partons.size()); ++i){
3540 minPT = min(minPT,event[partons[i]].pT());
3543 for(
int j=0; j < int(partons.size()); ++j){
3547 minRJJ = min(minRJJ, deltaRij( event[partons[i]].p(),
3548 event[partons[j]].p()) );
3550 minMJJ = min(minMJJ, ( event[partons[i]].p()
3551 +event[partons[j]].p() ).mCalc() );
3559 if (minPT > pTjmin) vetoPT =
true;
3560 if (minRJJ > rjjmin) vetoRjj =
true;
3561 if (minMJJ > mjjmin) vetoMjj =
true;
3568 if (
int(partons.size() == 1))
3572 doVeto = vetoPT && vetoRjj && vetoMjj;
3575 if (doVeto)
return 1.;
3586 double MergingHooks::deltaRij(Vec4 jet1, Vec4 jet2){
3591 double eta1 = 0.5*log( (jet1.e() + jet1.pz()) / (jet1.e() - jet1.pz()) );
3592 double eta2 = 0.5*log( (jet2.e() + jet2.pz()) / (jet2.e() - jet2.pz()) );
3594 double pt1 = sqrt( pow(jet1.px(),2) + pow(jet1.py(),2) );
3595 double pt2 = sqrt( pow(jet2.px(),2) + pow(jet2.py(),2) );
3596 double cosdPhi = ( jet1.px()*jet2.px() + jet1.py()*jet2.py() ) / (pt1*pt2);
3597 double dPhi = acos( cosdPhi );
3599 deltaR = sqrt(pow(eta1-eta2,2) + pow(dPhi,2));