10 #include "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(
"MadGraph", 0) == string::npos){
66 getline(infile,lineGenerator);
75 int inParticleNumbers[] = {
77 -11,11,-12,12,-13,13,-14,14,-15,15,-16,16,
81 -1,1,-2,2,-3,3,-4,4,-5,5,-6,6};
83 string inParticleNamesSH[] = {
85 "-11",
"11",
"-12",
"12",
"-13",
"13",
"-14",
"14",
"-15",
"15",
"-16",
"16",
87 "-93",
"93",
"-90",
"90",
"-91",
"91",
89 "-1",
"1",
"-2",
"2",
"-3",
"3",
"-4",
"4",
"-5",
"5",
"-6",
"6"};
90 string inParticleNamesMG[] = {
92 "e+",
"e-",
"ve~",
"ve",
"mu+",
"mu-",
"vm~",
"vm",
"ta+",
"ta-",
"vt~",
"vt",
94 "p~",
"p",
"l+",
"l-",
"vl~",
"vl",
96 "d~",
"d",
"u~",
"u",
"s~",
"s",
"c~",
"c",
"b~",
"b",
"t~",
"t"};
99 int interParticleNumbers[] = {
107 -1000001,1000001,-1000002,1000002,-1000003,1000003,-1000004,1000004,
108 -1000005,1000005,-1000006,1000006,-2000001,2000001,-2000002,2000002,
109 -2000003,2000003,-2000004,2000004,-2000005,2000005,-2000006,2000006};
111 string interParticleNamesMG[] = {
119 "dl~",
"dl",
"ul~",
"ul",
"sl~",
"sl",
"cl~",
"cl",
"b1~",
"b1",
"t1~",
"t1",
120 "dr~",
"dr",
"ur~",
"ur",
"sr~",
"sr",
"cr~",
"cr",
"b2~",
"b2",
"t2~",
"t2"};
123 int outParticleNumbers[] = {
125 -11,11,-12,12,-13,13,-14,14,-15,15,-16,16,
129 -1,1,-2,2,-3,3,-4,4,-5,5,-6,6,
133 -1000001,1000001,-1000002,1000002,-1000003,1000003,-1000004,1000004,
134 -1000005,1000005,-1000006,1000006,-2000001,2000001,-2000002,2000002,
135 -2000003,2000003,-2000004,2000004,-2000005,2000005,-2000006,2000006};
137 string outParticleNamesMG[] = {
139 "e+",
"e-",
"ve~",
"ve",
"mu+",
"mu-",
"vm~",
"vm",
"ta+",
"ta-",
"vt~",
"vt",
141 "j~",
"j",
"l+",
"l-",
"vl~",
"vl",
143 "d~",
"d",
"u~",
"u",
"s~",
"s",
"c~",
"c",
"b~",
"b",
"t~",
"t",
147 "dl~",
"dl",
"ul~",
"ul",
"sl~",
"sl",
"cl~",
"cl",
"b1~",
"b1",
"t1~",
"t1",
148 "dr~",
"dr",
"ur~",
"ur",
"sr~",
"sr",
"cr~",
"cr",
"b2~",
"b2",
"t2~",
"t2"};
150 string outParticleNamesSH[] = {
152 "-11",
"11",
"-12",
"12",
"-13",
"13",
"-14",
"14",
"-15",
"15",
"-16",
"16",
154 "-93",
"93",
"-90",
"90",
"-91",
"91",
156 "-1",
"1",
"-2",
"2",
"-3",
"3",
"-4",
"4",
"-5",
"5",
"-6",
"6",
160 "-1000001",
"1000001",
"-1000002",
"1000002",
"-1000003",
"1000003",
161 "-1000004",
"1000004",
162 "-1000005",
"1000005",
"-1000006",
"1000006",
"-2000001",
"2000001",
163 "-2000002",
"2000002",
164 "-2000003",
"2000003",
"-2000004",
"2000004",
"-2000005",
"2000005",
165 "-2000006",
"2000006"};
174 meGenType = (lineGenerator.find(
"MadGraph", 0) != string::npos) ? -1
175 : (lineGenerator.find(
"SHERPA", 0) != string::npos) ? -2 : 0;
180 infile.open( (
char*)( LHEpath +
"_1.lhe").c_str());
182 while(lineTMS.find(
"NJetFinder ", 0) == string::npos){
184 getline(infile,lineTMS);
187 lineTMS = lineTMS.substr(0,lineTMS.find(
" 0.0 ",0));
188 lineTMS = lineTMS.substr(lineTMS.find(
" ", 0)+3,lineTMS.size());
190 while(lineTMS.find(
" ", 0) != string::npos)
191 lineTMS.erase(lineTMS.begin()+lineTMS.find(
" ",0));
193 if( lineTMS.find(
"d", 0) != string::npos)
194 lineTMS.replace(lineTMS.find(
"d", 0),1,1,
'e');
195 tms = atof((
char*)lineTMS.c_str());
199 infile.open( (
char*)( LHEpath +
"_0.lhe").c_str());
201 while(line.find(
"Process", 0) == string::npos){
203 getline(infile,line);
206 line = line.substr(line.find(
" ",0),line.size());
209 vector <string> pieces;
210 pieces.push_back( line.substr(0,line.find(
"->", 0)) );
212 int end = (line.find(
"{", 0) != string::npos) ? line.find(
"{", 0)-2
214 pieces.push_back( line.substr(line.find(
"->", 0)+2, end) );
217 for(
int i=0; i < nIn; ++i) {
218 for(
int n = pieces[0].find(inParticleNamesSH[i], 0);
219 n != int(string::npos);
220 n = pieces[0].find(inParticleNamesSH[i], n)) {
221 incom.push_back(inParticleNumbers[i]);
222 pieces[0].erase(pieces[0].begin()+n,
223 pieces[0].begin()+n+inParticleNamesSH[i].size());
231 for(
int i=0; i < nOut; ++i) {
232 for(
int n = pieces[1].find(outParticleNamesSH[i], 0);
233 n != int(string::npos);
234 n = pieces[1].find(outParticleNamesSH[i], n)) {
235 outgo.push_back(outParticleNumbers[i]);
236 pieces[1].erase(pieces[1].begin()+n,
237 pieces[1].begin()+n+outParticleNamesSH[i].size());
242 }
else if(meGenType == -1){
245 infile.open( (
char*)( LHEpath +
"_1.lhe").c_str());
247 while(lineTMS.find(
"ktdurham", 0) == string::npos){
249 getline(infile,lineTMS);
251 lineTMS = lineTMS.substr(0,lineTMS.find(
"=",0));
254 while(lineTMS.find(
" ", 0) != string::npos)
255 lineTMS.erase(lineTMS.begin()+lineTMS.find(
" ",0));
257 if( lineTMS.find(
"d", 0) != string::npos)
258 lineTMS.replace(lineTMS.find(
"d", 0),1,1,
'e');
259 tms = atof((
char*)lineTMS.c_str());
263 infile.open( (
char*)( LHEpath +
"_0.lhe").c_str());
265 while(line.find(
"@1", 0) == string::npos){
267 getline(infile,line);
270 line = line.substr(0,line.find(
"@",0));
274 for(
int n = line.find(
"(", 0); n != int(string::npos);
275 n = line.find(
"(", n)) {
281 vector <string> pieces;
282 for(
int i =0; i < appearances;++i) {
283 int n = line.find(
"(", 0);
284 pieces.push_back(line.substr(0,n));
285 line = line.substr(n+1,line.size());
288 if(appearances > 0) {
289 pieces.push_back( line.substr(0,line.find(
")",0)) );
290 pieces.push_back( line.substr(line.find(
")",0)+1,line.size()) );
297 for(
int n = line.find(
">", 0); n != int(string::npos);
298 n = line.find(
">", n)) {
304 for(
int i =0; i < appearances;++i) {
305 int n = line.find(
">", 0);
306 pieces.push_back(line.substr(0,n));
307 line = line.substr(n+1,line.size());
310 if(appearances == 1) pieces.push_back(line);
311 if(appearances > 1) {
312 pieces.push_back( line.substr(0,line.find(
">",0)) );
313 pieces.push_back( line.substr(line.find(
">",0)+1,line.size()) );
318 for(
int i=0; i < nIn; ++i) {
319 for(
int n = pieces[0].find(inParticleNamesMG[i], 0);
320 n != int(string::npos);
321 n = pieces[0].find(inParticleNamesMG[i], n)) {
322 incom.push_back(inParticleNumbers[i]);
323 pieces[0].erase(pieces[0].begin()+n,
324 pieces[0].begin()+n+inParticleNamesMG[i].size());
330 for(
int i =1; i < int(pieces.size()); ++i){
332 int k = pieces[i].find(
">", 0);
334 string intermediate = (pieces[i].find(
">", 0) != string::npos) ?
335 pieces[i].substr(0,k) :
"";
336 string outgoing = (pieces[i].find(
">", 0) != string::npos) ?
337 pieces[i].substr(k+1,pieces[i].size()) : pieces[i];
340 for(
int j=0; j < nInt; ++j) {
341 for(
int n = intermediate.find(interParticleNamesMG[j], 0);
342 n != int(string::npos);
343 n = intermediate.find(interParticleNamesMG[j], n)) {
344 inter.push_back(interParticleNumbers[j]);
345 intermediate.erase(intermediate.begin()+n,
346 intermediate.begin()+n+interParticleNamesMG[j].size());
352 for(
int j=0; j < nOut; ++j) {
353 for(
int n = outgoing.find(outParticleNamesMG[j], 0);
354 n != int(string::npos);
355 n = outgoing.find(outParticleNamesMG[j], n)) {
356 outgo.push_back(outParticleNumbers[j]);
357 outgoing.erase(outgoing.begin()+n,
358 outgoing.begin()+n+outParticleNamesMG[j].size());
366 int nZeros = outgo.size()/2;
367 for(
int l=0; l < nZeros; ++l)
375 cout <<
"Reading of tms and hard process information from LHEF currently"
376 <<
" only automated for MadEvent- or SHERPA-produced LHEF" << endl;
378 cout <<
"Use default process pp -> e+ve + jets? (0:no / 1:yes): ";
384 double tempDouble = 0.0;
385 cout <<
"Please specify merging scale (kT Durham, in GeV): ";
390 cout <<
"Please specify first incoming particle ";
391 cout <<
"(p+/p- = 2212, e- = 11, e+ = -11): ";
393 incom.push_back(tempInt);
396 cout <<
"Please specify second incoming particle ";
397 cout <<
"(p+/p- = 2212, e- = 11, e+ = -11): ";
399 incom.push_back(tempInt);
402 cout <<
"Please specify intermediate particle, if any ";
403 cout <<
"(0 for none, else PDG code): ";
405 inter.push_back(tempInt);
409 cout <<
"Please specify outgoing particle ";
410 cout <<
"(jet=2212, else PDG code, exit with 99): ";
412 if(tempInt != 99) outgo.push_back(tempInt);
413 }
while(tempInt != 99);
416 cout <<
"LHE file not produced by SHERPA or MG/ME - ";
417 cout <<
"Using default process and tms" << endl;
418 incom.push_back(2212);
419 incom.push_back(2212);
421 outgo.push_back(-11);
430 for(
int i=0; i < int(inter.size()); ++i)
431 hardIntermediate.push_back(inter[i]);
434 if(incom.size() != 2)
435 cout <<
"Only two incoming particles allowed" << endl;
437 hardIncoming1 = incom[0];
438 hardIncoming2 = incom[1];
442 if(outgo.size()%2 == 1) {
443 cout <<
"Only even number of outgoing particles allowed" << endl;
444 for(
int i=0; i < int(outgo.size()); ++i)
445 cout << outgo[i] << endl;
449 for(
int i=0; i < int(outgo.size()); ++i)
452 && outgo[i] != 1000022)
453 hardOutgoing2.push_back( outgo[i]);
454 else if (outgo[i] < 0)
455 hardOutgoing1.push_back( outgo[i]);
460 for(
int i=0; i < int(outgo.size()); ++i)
461 if( (outgo[i] == 2212
462 || outgo[i] == 1000022)
464 hardOutgoing2.push_back( outgo[i]);
466 }
else if( (outgo[i] == 2212
467 || outgo[i] == 1000022)
469 hardOutgoing1.push_back( outgo[i]);
483 void HardProcess::translateProcessString(
string process){
490 int inParticleNumbers[] = {
492 -11,11,-12,12,-13,13,-14,14,-15,15,-16,16,
496 -1,1,-2,2,-3,3,-4,4,-5,5,-6,6};
497 string inParticleNamesMG[] = {
499 "e+",
"e-",
"ve~",
"ve",
"mu+",
"mu-",
"vm~",
"vm",
"ta+",
"ta-",
"vt~",
"vt",
501 "p~",
"p",
"l+",
"l-",
"vl~",
"vl",
503 "d~",
"d",
"u~",
"u",
"s~",
"s",
"c~",
"c",
"b~",
"b",
"t~",
"t"};
506 int interParticleNumbers[] = {
514 -1000001,1000001,-1000002,1000002,-1000003,1000003,-1000004,1000004,
515 -1000005,1000005,-1000006,1000006,-2000001,2000001,-2000002,2000002,
516 -2000003,2000003,-2000004,2000004,-2000005,2000005,-2000006,2000006};
518 string interParticleNamesMG[] = {
526 "dl~",
"dl",
"ul~",
"ul",
"sl~",
"sl",
"cl~",
"cl",
"b1~",
"b1",
"t1~",
"t1",
527 "dr~",
"dr",
"ur~",
"ur",
"sr~",
"sr",
"cr~",
"cr",
"b2~",
"b2",
"t2~",
"t2"};
530 int outParticleNumbers[] = {
532 -11,11,-12,12,-13,13,-14,14,-15,15,-16,16,
536 -1,1,-2,2,-3,3,-4,4,-5,5,-6,6,
540 -1000001,1000001,-1000002,1000002,-1000003,1000003,-1000004,1000004,
541 -1000005,1000005,-1000006,1000006,-2000001,2000001,-2000002,2000002,
542 -2000003,2000003,-2000004,2000004,-2000005,2000005,-2000006,2000006};
544 string outParticleNamesMG[] = {
546 "e+",
"e-",
"ve~",
"ve",
"mu+",
"mu-",
"vm~",
"vm",
"ta+",
"ta-",
"vt~",
"vt",
548 "j~",
"j",
"l+",
"l-",
"vl~",
"vl",
550 "d~",
"d",
"u~",
"u",
"s~",
"s",
"c~",
"c",
"b~",
"b",
"t~",
"t",
554 "dl~",
"dl",
"ul~",
"ul",
"sl~",
"sl",
"cl~",
"cl",
"b1~",
"b1",
"t1~",
"t1",
555 "dr~",
"dr",
"ur~",
"ur",
"sr~",
"sr",
"cr~",
"cr",
"b2~",
"b2",
"t2~",
"t2"};
562 string line = process;
566 for(
int n = line.find(
"(", 0); n != int(string::npos);
567 n = line.find(
"(", n)) {
573 vector <string> pieces;
574 for(
int i =0; i < appearances;++i) {
575 int n = line.find(
"(", 0);
576 pieces.push_back(line.substr(0,n));
577 line = line.substr(n+1,line.size());
580 if(appearances > 0) {
581 pieces.push_back( line.substr(0,line.find(
")",0)) );
582 pieces.push_back( line.substr(line.find(
")",0)+1,line.size()) );
589 for(
int n = line.find(
">", 0); n != int(string::npos);
590 n = line.find(
">", n)) {
596 for(
int i =0; i < appearances;++i) {
597 int n = line.find(
">", 0);
598 pieces.push_back(line.substr(0,n));
599 line = line.substr(n+1,line.size());
602 if(appearances == 1) pieces.push_back(line);
603 if(appearances > 1) {
604 pieces.push_back( line.substr(0,line.find(
">",0)) );
605 pieces.push_back( line.substr(line.find(
">",0)+1,line.size()) );
610 for(
int i=0; i < nIn; ++i) {
611 for(
int n = pieces[0].find(inParticleNamesMG[i], 0);
612 n != int(string::npos);
613 n = pieces[0].find(inParticleNamesMG[i], n)) {
614 incom.push_back(inParticleNumbers[i]);
615 pieces[0].erase(pieces[0].begin()+n,
616 pieces[0].begin()+n+inParticleNamesMG[i].size());
622 for(
int i =1; i < int(pieces.size()); ++i){
624 int k = pieces[i].find(
">", 0);
626 string intermediate = (pieces[i].find(
">", 0) != string::npos) ?
627 pieces[i].substr(0,k) :
"";
628 string outgoing = (pieces[i].find(
">", 0) != string::npos) ?
629 pieces[i].substr(k+1,pieces[i].size()) : pieces[i];
632 for(
int j=0; j < nInt; ++j) {
633 for(
int n = intermediate.find(interParticleNamesMG[j], 0);
634 n != int(string::npos);
635 n = intermediate.find(interParticleNamesMG[j], n)) {
636 inter.push_back(interParticleNumbers[j]);
637 intermediate.erase(intermediate.begin()+n,
638 intermediate.begin()+n+interParticleNamesMG[j].size());
644 for(
int j=0; j < nOut; ++j) {
645 for(
int n = outgoing.find(outParticleNamesMG[j], 0);
646 n != int(string::npos);
647 n = outgoing.find(outParticleNamesMG[j], n)) {
648 outgo.push_back(outParticleNumbers[j]);
649 outgoing.erase(outgoing.begin()+n,
650 outgoing.begin()+n+outParticleNamesMG[j].size());
658 int nZeros = outgo.size()/2;
659 for(
int l=0; l < nZeros; ++l)
667 for(
int i=0; i < int(inter.size()); ++i)
668 hardIntermediate.push_back(inter[i]);
671 if(incom.size() != 2)
672 cout <<
"Only two incoming particles allowed" << endl;
674 hardIncoming1 = incom[0];
675 hardIncoming2 = incom[1];
679 if(outgo.size()%2 == 1) {
680 cout <<
"Only even number of outgoing particles allowed" << endl;
681 for(
int i=0; i < int(outgo.size()); ++i)
682 cout << outgo[i] << endl;
686 for(
int i=0; i < int(outgo.size()); ++i)
689 && outgo[i] != 1000022)
690 hardOutgoing2.push_back( outgo[i]);
691 else if (outgo[i] < 0)
692 hardOutgoing1.push_back( outgo[i]);
697 for(
int i=0; i < int(outgo.size()); ++i)
698 if( (outgo[i] == 2212
699 || outgo[i] == 1000022)
701 hardOutgoing2.push_back( outgo[i]);
703 }
else if( (outgo[i] == 2212
704 || outgo[i] == 1000022)
706 hardOutgoing1.push_back( outgo[i]);
718 void HardProcess::storeCandidates(
const Event& event){
725 vector<int> intermediates;
726 for(
int i =0; i < int(hardIntermediate.size());++i)
727 intermediates.push_back( hardIntermediate[i]);
730 vector<int> outgoing1;
731 for(
int i =0; i < int(hardOutgoing1.size());++i)
732 outgoing1.push_back( hardOutgoing1[i]);
733 vector<int> outgoing2;
734 for(
int i =0; i < int(hardOutgoing2.size());++i)
735 outgoing2.push_back( hardOutgoing2[i]);
738 PosIntermediate.resize(0);
739 PosOutgoing1.resize(0);
740 PosOutgoing2.resize(0);
741 for(
int i =0; i < int(hardIntermediate.size());++i)
742 PosIntermediate.push_back(0);
743 for(
int i =0; i < int(hardOutgoing1.size());++i)
744 PosOutgoing1.push_back(0);
745 for(
int i =0; i < int(hardOutgoing2.size());++i)
746 PosOutgoing2.push_back(0);
752 bool hasOnlyJets =
true;
753 for(
int i =0; i < int(hardOutgoing1.size());++i)
754 if(hardOutgoing1[i] != 2212)
756 for(
int i =0; i < int(hardOutgoing2.size());++i)
757 if(hardOutgoing2[i] != 2212)
764 for(
int i =0; i < int(hardOutgoing1.size());++i)
766 for(
int i =0; i < int(hardOutgoing2.size());++i)
774 vector<int> iPosChecked;
777 for(
int i=0; i < int(intermediates.size()); ++i){
780 if(intermediates[i] == 0)
continue;
783 for(
int j=0; j < int(event.size()); ++j) {
786 if(event[j].
id() == intermediates[i]) {
788 PosIntermediate[i] = j;
789 intermediates[i] = 0;
791 int iPos1 =
event[j].daughter1();
792 int iPos2 =
event[j].daughter2();
796 for(
int k=iPos1; k <= iPos2; ++k){
797 int id =
event[k].id();
800 for(
int l=0; l < int(outgoing2.size()); ++l)
801 if( outgoing2[l] != 99 ){
803 if(
id == outgoing2[l]
805 || (
id > 0 && abs(
id) < 10 && outgoing2[l] == 2212) ){
810 iPosChecked.push_back(k);
816 for(
int l=0; l < int(outgoing1.size()); ++l)
817 if( outgoing1[l] != 99 ){
819 if(
id == outgoing1[l]
821 || (
id < 0 && abs(
id) < 10 && outgoing1[l] == 2212) ){
826 iPosChecked.push_back(k);
838 for(
int i=0; i < int(outgoing1.size()); ++i)
839 if(outgoing1[i] != 99)
841 for(
int i=0; i < int(outgoing2.size()); ++i)
842 if(outgoing2[i] != 99)
850 for(
int i=0; i < int(event.size()); ++i){
852 if( !event[i].isFinal() ||
event[i].colType() != 0)
856 for(
int k=0; k < int(iPosChecked.size()); ++k){
857 if(i == iPosChecked[k])
863 for(
int j=0; j < int(outgoing2.size()); ++j){
866 if( outgoing2[j] == 99
867 || outgoing2[j] == 2212
868 || abs(outgoing2[j]) < 10)
872 if(event[i].
id() == outgoing2[j]){
875 iPosChecked.push_back(i);
880 for(
int j=0; j < int(outgoing1.size()); ++j){
883 if( outgoing1[j] == 99
884 || outgoing1[j] == 2212
885 || abs(outgoing1[j]) < 10)
889 if(event[i].
id() == outgoing1[j]){
892 iPosChecked.push_back(i);
902 for(
int i=0; i < int(event.size()); ++i){
905 if( !event[i].isFinal() ||
event[i].colType() == 0)
910 for(
int k=0; k < int(iPosChecked.size()); ++k){
911 if(i == iPosChecked[k])
917 for(
int j=0; j < int(outgoing2.size()); ++j){
920 if( outgoing2[j] == 99
921 || outgoing2[j] == 2212
922 || abs(outgoing2[j]) > 10)
925 if(event[i].
id() == outgoing2[j]){
930 iPosChecked.push_back(i);
935 for(
int j=0; j < int(outgoing1.size()); ++j){
938 if( outgoing1[j] == 99
939 || outgoing1[j] == 2212
940 || abs(outgoing1[j]) > 10)
943 if(event[i].
id() == outgoing1[j]){
948 iPosChecked.push_back(i);
961 bool HardProcess::matchesAnyOutgoing(
int iPos,
const Event& event){
964 bool matchQN1 =
false;
966 bool matchQN2 =
false;
970 bool matchHP =
false;
973 for(
int i=0; i < int(PosOutgoing1.size()); ++i)
975 if( event[iPos].
id() == state[PosOutgoing1[i]].id()
976 &&
event[iPos].colType() == state[PosOutgoing1[i]].colType()
977 &&
event[iPos].chargeType() == state[PosOutgoing1[i]].chargeType()
978 &&
event[iPos].col() == state[PosOutgoing1[i]].col()
979 &&
event[iPos].acol() == state[PosOutgoing1[i]].acol()
980 &&
event[iPos].charge() == state[PosOutgoing1[i]].charge() )
984 for(
int i=0; i < int(PosOutgoing2.size()); ++i)
986 if( event[iPos].
id() == state[PosOutgoing2[i]].id()
987 &&
event[iPos].colType() == state[PosOutgoing2[i]].colType()
988 &&
event[iPos].chargeType() == state[PosOutgoing2[i]].chargeType()
989 &&
event[iPos].col() == state[PosOutgoing2[i]].col()
990 &&
event[iPos].acol() == state[PosOutgoing2[i]].acol()
991 &&
event[iPos].charge() == state[PosOutgoing2[i]].charge() )
996 if( event[iPos].mother1()*
event[iPos].mother2() == 12
998 || (
event[iPos].status() == 44
999 &&
event[
event[iPos].mother1()].mother1()
1000 *
event[
event[iPos].mother1()].mother2() == 12 )
1002 || ( event[iPos].status() == 23
1003 &&
event[
event[iPos].mother1()].mother1()
1004 *
event[
event[iPos].mother1()].mother2() == 12 )
1007 || ( event[iPos].status() == 23
1008 &&
event[
event[iPos].mother1()].status() == -22
1009 &&
event[
event[
event[iPos].mother1()].mother1()].status() == -22
1010 &&
event[
event[
event[iPos].mother1()].mother1()].mother1()
1011 *
event[
event[
event[iPos].mother1()].mother1()].mother2() == 12 ) )
1015 return matchHP && ( matchQN1 || matchQN2 );
1024 int HardProcess::MEgenType(){
return meGenType;}
1031 int HardProcess::nQuarksOut(){
1033 for(
int i =0; i< int(hardOutgoing1.size()); ++i){
1034 if(hardOutgoing1[i] == 2212 || abs(hardOutgoing1[i]) < 10) nFin++;
1035 if(hardOutgoing2[i] == 2212 || abs(hardOutgoing2[i]) < 10) nFin++;
1045 int HardProcess::nLeptonOut(){
1047 for(
int i =0; i< int(hardOutgoing1.size()); ++i){
1048 if(abs(hardOutgoing1[i]) > 10 && abs(hardOutgoing1[i]) < 20) nFin++;
1049 if(abs(hardOutgoing2[i]) > 10 && abs(hardOutgoing2[i]) < 20) nFin++;
1051 if(abs(hardOutgoing1[i]) == 1000022) nFin++;
1052 if(abs(hardOutgoing2[i]) == 1000022) nFin++;
1062 int HardProcess::nQuarksIn(){
1064 if(hardIncoming1 == 2212 || abs(hardIncoming1) < 10) nIn++;
1065 if(hardIncoming2 == 2212 || abs(hardIncoming2) < 10) nIn++;
1074 int HardProcess::nLeptonIn(){
1076 if(abs(hardIncoming1) > 10 && abs(hardIncoming1) < 20) nIn++;
1077 if(abs(hardIncoming2) > 10 && abs(hardIncoming2) < 20) nIn++;
1086 int HardProcess::hasResInCurrent(){
1087 for(
int i =0; i< int(PosIntermediate.size()); ++i)
1088 if(PosIntermediate[i] == 0)
return 0;
1097 int HardProcess::nResInCurrent(){
1099 for(
int i =0; i< int(PosIntermediate.size()); ++i){
1100 if(PosIntermediate[i] != 0) nRes++;
1110 bool HardProcess::hasResInProc(){
1111 for(
int i =0; i< int(hardIntermediate.size()); ++i)
1112 if(hardIntermediate[i] == 0)
return false;
1120 void HardProcess::list()
const {
1121 cout <<
" Hard Process: ";
1122 cout <<
" \t " << hardIncoming1 <<
" + " << hardIncoming2;
1123 cout <<
" \t -----> \t ";
1124 for(
int i =0; i < int(hardIntermediate.size());++i)
1125 cout << hardIntermediate[i] <<
" ";
1126 cout <<
" \t -----> \t ";
1127 for(
int i =0; i < int(hardOutgoing1.size());++i) {
1128 cout << hardOutgoing1[i] <<
" ";
1129 cout << hardOutgoing2[i] <<
" ";
1139 void HardProcess::listCandidates()
const {
1140 cout <<
" Hard Process candidates: ";
1141 cout <<
" \t " << hardIncoming1 <<
" + " << hardIncoming2;
1142 cout <<
" \t -----> \t ";
1143 for(
int i =0; i < int(PosIntermediate.size());++i)
1144 cout << PosIntermediate[i] <<
" ";
1145 cout <<
" \t -----> \t ";
1146 for(
int i =0; i < int(PosOutgoing1.size());++i) {
1147 cout << PosOutgoing1[i] <<
" ";
1148 cout << PosOutgoing2[i] <<
" ";
1157 void HardProcess::clear() {
1160 hardIncoming1 = hardIncoming2 = 0;
1162 hardOutgoing1.resize(0);
1163 hardOutgoing2.resize(0);
1165 hardIntermediate.resize(0);
1171 PosOutgoing1.resize(0);
1172 PosOutgoing2.resize(0);
1174 PosIntermediate.resize(0);
1192 void MergingHooks::init( Settings& settings, Info* infoPtrIn,
1193 ParticleData* particleDataPtrIn, ostream& os){
1196 infoPtr = infoPtrIn;
1197 particleDataPtr = particleDataPtrIn;
1200 double alphaSvalueFSR = settings.parm(
"TimeShower:alphaSvalue");
1201 int alphaSorderFSR = settings.mode(
"TimeShower:alphaSorder");
1202 AlphaS_FSRSave.init(alphaSvalueFSR,alphaSorderFSR);
1203 double alphaSvalueISR = settings.parm(
"SpaceShower:alphaSvalue");
1204 int alphaSorderISR = settings.mode(
"SpaceShower:alphaSorder");
1205 AlphaS_ISRSave.init(alphaSvalueISR,alphaSorderISR);
1208 doUserMergingSave = settings.flag(
"Merging:doUserMerging");
1211 doMGMergingSave = settings.flag(
"Merging:doMGMerging");
1214 doKTMergingSave = settings.flag(
"Merging:doKTMerging");
1217 ktTypeSave = settings.mode(
"Merging:ktType");
1220 processSave = settings.word(
"Merging:Process");
1223 hardProcess.clear();
1226 if(doUserMergingSave || doKTMergingSave)
1227 hardProcess.initOnProcess(processSave, particleDataPtr);
1229 hardProcess.initOnLHEF(lheInputFile, particleDataPtr);
1232 includeMassiveSave = settings.flag(
"Merging:includeMassive");
1233 enforceStrongOrderingSave = settings.flag(
"Merging:enforceStrongOrdering");
1234 scaleSeparationFactorSave = settings.parm(
"Merging:scaleSeparationFactor");
1235 orderInRapiditySave = settings.flag(
"Merging:orderInRapidity");
1238 nonJoinedNormSave = settings.parm(
"Merging:nonJoinedNorm");
1239 fsrInRecNormSave = settings.parm(
"Merging:fsrInRecNorm");
1240 pickByFullPSave = settings.flag(
"Merging:pickByFullP");
1241 pickByPoPT2Save = settings.flag(
"Merging:pickByPoPT2");
1242 includeRedundantSave = settings.flag(
"Merging:includeRedundant");
1245 unorderedScalePrescipSave =
1246 settings.mode(
"Merging:unorderedScalePrescrip");
1247 unorderedASscalePrescipSave =
1248 settings.mode(
"Merging:unorderedASscalePrescrip");
1249 incompleteScalePrescipSave =
1250 settings.mode(
"Merging:incompleteScalePrescrip");
1253 allowColourShufflingSave =
1254 settings.flag(
"Merging:allowColourShuffling");
1257 pickBySumPTSave = settings.flag(
"Merging:pickBySumPT");
1258 herwigAcollFSRSave = settings.parm(
"Merging:aCollFSR");
1259 herwigAcollISRSave = settings.parm(
"Merging:aCollISR");
1262 pT0ISRSave = settings.parm(
"SpaceShower:pT0Ref");
1263 pTcutSave = settings.parm(
"SpaceShower:pTmin");
1264 pTcutSave = max(pTcutSave,pT0ISRSave);
1271 if(doKTMergingSave) {
1272 tmsValueSave = settings.parm(
"Merging:TMS");
1273 nJetMaxSave = settings.mode(
"Merging:nJetMax");
1274 }
else if (doMGMergingSave) {
1275 tmsValueSave = hardProcess.tms;
1276 nJetMaxSave = settings.mode(
"Merging:nJetMax");
1278 tmsValueSave = settings.parm(
"Merging:TMS");
1279 nJetMaxSave = settings.mode(
"Merging:nJetMax");
1284 <<
" *---------- MEPS Merging Initialization -----------------------*"
1286 <<
" | We merge " << processSave <<
" with up to " << nJetMaxSave
1287 <<
" additional jets \n";
1289 os <<
" | Merging scale is defined in kT with the value ktMS = "
1290 << tmsValueSave <<
" GeV";
1291 else if(doMGMergingSave)
1292 os <<
" | Perform automanted MG/ME merging \n"
1293 <<
" | Merging scale is defined in kT with the value ktMS = "
1294 << tmsValueSave <<
" GeV";
1296 os <<
" | Merging scale is defined by the user, with the value tMS = "
1298 os <<
"\n *---------- END MEPS Merging Initialization -------------------*"
1307 int MergingHooks::getNumberOfClusteringSteps(
const Event& event){
1310 int nFinalPartons = 0;
1311 for(
int i=0; i <
event.size(); ++i)
1312 if( event[i].isFinal() &&
event[i].isParton())
1316 for(
int i=0; i <
event.size(); ++i)
1317 if( event[i].isFinal() &&
event[i].idAbs() == 6)
1321 int nFinalLeptons = 0;
1322 for(
int i=0; i <
event.size(); ++i)
1323 if( event[i].isFinal() &&
event[i].isLepton())
1327 for(
int i=0; i <
event.size(); ++i)
1328 if( event[i].isFinal()
1329 &&
event[i].idAbs() == 1000022)
1333 int nFinalBosons = 0;
1334 for(
int i=0; i <
event.size(); ++i)
1335 if( event[i].isFinal()
1336 && (
event[i].idAbs() == 24
1337 ||
event[i].idAbs() == 23 ) )
1341 int nFinal = nFinalPartons + nFinalLeptons + 2*nFinalBosons;
1344 return (nFinal - nHardOutPartons() - nHardOutLeptons());
1350 double MergingHooks::kTms(
const Event& event) {
1354 int nFinalColoured = 0;
1356 for(
int i=0; i <
event.size(); ++i) {
1357 if(event[i].isFinal()){
1358 if(event[i].
id() != 23 && abs(event[i].
id()) != 24)
1360 if( event[i].colType() != 0)
1367 int nLeptons = nHardOutLeptons();
1368 int nQuarks = nHardOutPartons();
1369 int nResNow = nResInCurrent();
1372 if(nFinalNow - ( (nLeptons+nQuarks)/2 - nResNow)*2 != nFinalColoured){
1376 if(nFinalNow != nFinalColoured)
return 0.;
1380 int nMPI = infoPtr->nMPI();
1381 if(nMPI > 1)
return 0.;
1384 double Dparam = 0.4;
1386 vector <int> FinalPartPos;
1387 FinalPartPos.clear();
1389 for (
int i=0; i <
event.size(); ++i)
1390 if(event[i].isFinal() &&
event[i].colType() != 0)
1391 FinalPartPos.push_back(i);
1395 int type = (
event[3].colType() == 0
1396 &&
event[4].colType() == 0) ? -1 : ktTypeSave;
1398 double ktmin =
event[0].e();
1399 for(
int i=0; i < int(FinalPartPos.size()); ++i){
1400 double kt12 = ktmin;
1402 if(type == 1 || type == 2) {
1403 double temp =
event[FinalPartPos[i]].pT();
1404 kt12 = min(kt12, temp);
1407 for(
int j=i+1; j < int(FinalPartPos.size()); ++j) {
1408 double temp = kTdurham( event[FinalPartPos[i]], event[FinalPartPos[j]],
1410 kt12 = min(kt12, temp);
1413 ktmin = min(ktmin,kt12);
1425 double MergingHooks::kTdurham(
const Particle& RadAfterBranch,
1426 const Particle& EmtAfterBranch,
int Type,
double D ){
1431 Vec4 jet1 = RadAfterBranch.p();
1432 Vec4 jet2 = EmtAfterBranch.p();
1438 if (jet1.pAbs()*jet2.pAbs() <=0.) costh = 1.;
1440 costh = costheta(jet1,jet2);
1443 ktdur = 2.0*min( pow(jet1.e(),2) , (pow(jet2.e(),2)) )*(1.0 - costh);
1444 }
else if( Type == 1 ){
1447 double mT1sq = jet1.m2Calc() + jet1.pT2();
1449 if(mT1sq < 0) mT1 = - sqrt(-mT1sq);
1450 else mT1 = sqrt(mT1sq);
1452 double mT2sq = jet2.m2Calc() + jet2.pT2();
1454 if(mT2sq < 0) mT2 = - sqrt(-mT2sq);
1455 else mT2 = sqrt(mT2sq);
1457 double y1 = log( ( jet1.e() + abs(jet1.pz()) ) / mT1 );
1458 if(jet1.pz() < 0) y1 *= -1.;
1460 double y2 = log( ( jet2.e() + abs(jet2.pz()) ) / mT2 );
1461 if(jet2.pz() < 0) y2 *= -1.;
1463 double pt1 = sqrt( pow(jet1.px(),2) + pow(jet1.py(),2) );
1464 double pt2 = sqrt( pow(jet2.px(),2) + pow(jet2.py(),2) );
1465 double cosdPhi = ( jet1.px()*jet2.px() + jet1.py()*jet2.py() ) / (pt1*pt2);
1466 double dPhi = acos( cosdPhi );
1469 ktdur = min( pow(pt1,2),pow(pt2,2) )
1470 * ( pow(y1-y2,2) + pow(dPhi,2) ) / pow(D,2);
1471 }
else if( Type == 2 ){
1473 double eta1 = 0.5*log( (jet1.e() + jet1.pz()) / (jet1.e() - jet1.pz()) );
1474 double eta2 = 0.5*log( (jet2.e() + jet2.pz()) / (jet2.e() - jet2.pz()) );
1476 double pt1 = sqrt( pow(jet1.px(),2) + pow(jet1.py(),2) );
1477 double pt2 = sqrt( pow(jet2.px(),2) + pow(jet2.py(),2) );
1478 double cosdPhi = ( jet1.px()*jet2.px() + jet1.py()*jet2.py() ) / (pt1*pt2);
1479 double dPhi = acos( cosdPhi );
1481 ktdur = min( pow(pt1,2),pow(pt2,2) )
1482 * ( pow(eta1-eta2,2) + pow(dPhi,2) ) / pow(D,2);
1483 }
else if( Type == 3 ){
1485 double eta1 = 0.5*log( (jet1.e() + jet1.pz()) / (jet1.e() - jet1.pz()) );
1486 double eta2 = 0.5*log( (jet2.e() + jet2.pz()) / (jet2.e() - jet2.pz()) );
1487 double coshdEta = cosh( eta1 - eta2 );
1489 double pt1 = sqrt( pow(jet1.px(),2) + pow(jet1.py(),2) );
1490 double pt2 = sqrt( pow(jet2.px(),2) + pow(jet2.py(),2) );
1491 double cosdPhi = ( jet1.px()*jet2.px() + jet1.py()*jet2.py() ) / (pt1*pt2);
1493 ktdur = 2.0*min( pow(pt1,2),pow(pt2,2) )
1494 * ( coshdEta - cosdPhi ) / pow(D,2);
1507 void MergingHooks::setLHEInputFile(
string lheFile){
1512 lheInputFile = lheFile.substr(0,lheFile.size()-6);