8 #include "Pythia8/PartonLevel.h"
9 #include "Pythia8/DireMergingHooks.h"
25 void DireHardProcess::initOnProcess(
string process,
26 ParticleData* particleData) {
27 state.init(
"(hard process)", particleData);
28 translateProcessString(process);
37 void DireHardProcess::translateProcessString(
string process){
44 int inParticleNumbers[] = {
46 -11,11,-12,12,-13,13,-14,14,-15,15,-16,16,
50 -1,1,-2,2,-3,3,-4,4,-5,5,-6,6};
51 string inParticleNamesMG[] = {
53 "e+",
"e-",
"ve~",
"ve",
"mu+",
"mu-",
"vm~",
"vm",
"ta+",
"ta-",
"vt~",
"vt",
55 "p~",
"p",
"l+",
"l-",
"vl~",
"vl",
57 "d~",
"d",
"u~",
"u",
"s~",
"s",
"c~",
"c",
"b~",
"b",
"t~",
"t"};
60 int interParticleNumbers[] = {
64 -1000001,1000001,-1000002,1000002,-1000003,1000003,-1000004,1000004,
65 -1000005,1000005,-1000006,1000006,-2000001,2000001,-2000002,2000002,
66 -2000003,2000003,-2000004,2000004,-2000005,2000005,-2000006,2000006,
72 string interParticleNamesMG[] = {
74 "a",
"z",
"w-",
"w+",
"h",
"W",
76 "dl~",
"dl",
"ul~",
"ul",
"sl~",
"sl",
"cl~",
"cl",
"b1~",
"b1",
"t1~",
"t1",
77 "dr~",
"dr",
"ur~",
"ur",
"sr~",
"sr",
"cr~",
"cr",
"b2~",
"b2",
"t2~",
"t2",
84 int outParticleNumbers[] = {
86 -11,11,-12,12,-13,13,-14,14,-15,15,-16,16,
88 2212,2212,0,0,0,0,1200,1100,5000,
90 10000022,10000023,10000024,10000025,10002212,
92 -1000001,1000001,-1000002,1000002,-1000003,1000003,-1000004,1000004,
93 -1000005,1000005,-1000006,1000006,-2000001,2000001,-2000002,2000002,
94 -2000003,2000003,-2000004,2000004,-2000005,2000005,-2000006,2000006,
96 -1,1,-2,2,-3,3,-4,4,-5,5,-6,6,
102 string outParticleNamesMG[] = {
104 "e+",
"e-",
"ve~",
"ve",
"mu+",
"mu-",
"vm~",
"vm",
"ta+",
"ta-",
"vt~",
"vt",
106 "j~",
"j",
"l+",
"l-",
"vl~",
"vl",
"NEUTRINOS",
"LEPTONS",
"BQUARKS",
108 "Ainc",
"Zinc",
"Winc",
"Hinc",
"Jinc",
110 "dl~",
"dl",
"ul~",
"ul",
"sl~",
"sl",
"cl~",
"cl",
"b1~",
"b1",
"t1~",
"t1",
111 "dr~",
"dr",
"ur~",
"ur",
"sr~",
"sr",
"cr~",
"cr",
"b2~",
"b2",
"t2~",
"t2",
113 "d~",
"d",
"u~",
"u",
"s~",
"s",
"c~",
"c",
"b~",
"b",
"t~",
"t",
115 "a",
"z",
"w-",
"w+",
"h",
"W",
125 string fullProc = process;
129 int nUserParticles = 0;
130 for(
int n = fullProc.find(
"{", 0); n != int(string::npos);
131 n = fullProc.find(
"{", n)) {
136 vector <string> userParticleStrings;
137 for(
int i =0; i < nUserParticles;++i) {
138 int n = fullProc.find(
"{", 0);
139 userParticleStrings.push_back(fullProc.substr(0,n));
140 fullProc = fullProc.substr(n+1,fullProc.size());
143 if (nUserParticles > 0)
144 userParticleStrings.push_back(
145 fullProc.substr( 0, fullProc.find(
"}",0) ) );
147 for(
int i =0; i < int(userParticleStrings.size());++i) {
148 while(userParticleStrings[i].find(
"{", 0) != string::npos)
149 userParticleStrings[i].erase(userParticleStrings[i].begin()
150 +userParticleStrings[i].find(
"{", 0));
151 while(userParticleStrings[i].find(
"}", 0) != string::npos)
152 userParticleStrings[i].erase(userParticleStrings[i].begin()
153 +userParticleStrings[i].find(
"}", 0));
154 while(userParticleStrings[i].find(
" ", 0) != string::npos)
155 userParticleStrings[i].erase(userParticleStrings[i].begin()
156 +userParticleStrings[i].find(
" ", 0));
160 vector<int>userParticleNumbers;
161 if (
int(userParticleStrings.size()) > 1) {
162 for(
int i = 1; i < int(userParticleStrings.size()); ++i) {
163 userParticleNumbers.push_back(
164 atoi((
char*)userParticleStrings[i].substr(
165 userParticleStrings[i].find(
",",0)+1,
166 userParticleStrings[i].size()).c_str() ) );
170 if (nUserParticles > 0)
171 userParticleStrings.push_back(
173 fullProc.find(
"}",0)+1, fullProc.size() ) );
175 for(
int i = 0; i < int(userParticleStrings.size()); ++i) {
176 while(userParticleStrings[i].find(
"{", 0) != string::npos)
177 userParticleStrings[i].erase(userParticleStrings[i].begin()
178 +userParticleStrings[i].find(
"{", 0));
179 while(userParticleStrings[i].find(
"}", 0) != string::npos)
180 userParticleStrings[i].erase(userParticleStrings[i].begin()
181 +userParticleStrings[i].find(
"}", 0));
182 while(userParticleStrings[i].find(
" ", 0) != string::npos)
183 userParticleStrings[i].erase(userParticleStrings[i].begin()
184 +userParticleStrings[i].find(
" ", 0));
190 if (
int(userParticleStrings.size()) > 1 )
191 residualProc = userParticleStrings.front() + userParticleStrings.back();
193 residualProc = fullProc;
196 while(residualProc.find(
",", 0) != string::npos)
197 residualProc.erase(residualProc.begin()+residualProc.find(
",",0));
201 for(
int n = residualProc.find(
"(", 0); n != int(string::npos);
202 n = residualProc.find(
"(", n)) {
208 vector <string> pieces;
209 for(
int i =0; i < appearances;++i) {
210 int n = residualProc.find(
"(", 0);
211 pieces.push_back(residualProc.substr(0,n));
212 residualProc = residualProc.substr(n+1,residualProc.size());
215 if (appearances > 0) {
216 pieces.push_back( residualProc.substr(0,residualProc.find(
")",0)) );
217 pieces.push_back( residualProc.substr(
218 residualProc.find(
")",0)+1, residualProc.size()) );
223 if (pieces.empty() ){
225 for(
int n = residualProc.find(
">", 0); n != int(string::npos);
226 n = residualProc.find(
">", n)) {
232 for(
int i =0; i < appearances;++i) {
233 int n = residualProc.find(
">", 0);
234 pieces.push_back(residualProc.substr(0,n));
235 residualProc = residualProc.substr(n+1,residualProc.size());
238 if (appearances == 1) pieces.push_back(residualProc);
239 if (appearances > 1) {
240 pieces.push_back( residualProc.substr(0,residualProc.find(
">",0)) );
241 pieces.push_back( residualProc.substr(
242 residualProc.find(
">",0)+1, residualProc.size()) );
247 for(
int i=0; i < nIn; ++i) {
248 for(
int n = pieces[0].find(inParticleNamesMG[i], 0);
249 n != int(string::npos);
250 n = pieces[0].find(inParticleNamesMG[i], n)) {
251 incom.push_back(inParticleNumbers[i]);
252 pieces[0].erase(pieces[0].begin()+n,
253 pieces[0].begin()+n+inParticleNamesMG[i].size());
259 for(
int i =1; i < int(pieces.size()); ++i){
261 int k = pieces[i].find(
">", 0);
263 string intermediate = (pieces[i].find(
">", 0) != string::npos) ?
264 pieces[i].substr(0,k) :
"";
265 string outgoing = (pieces[i].find(
">", 0) != string::npos) ?
266 pieces[i].substr(k+1,pieces[i].size()) : pieces[i];
269 for(
int j=0; j < nInt; ++j) {
270 for(
int n = intermediate.find(interParticleNamesMG[j], 0);
271 n != int(string::npos);
272 n = intermediate.find(interParticleNamesMG[j], n)) {
273 inter.push_back(interParticleNumbers[j]);
274 intermediate.erase(intermediate.begin()+n,
275 intermediate.begin()+n+interParticleNamesMG[j].size());
281 for(
int j=0; j < nOut; ++j) {
282 for(
int n = outgoing.find(outParticleNamesMG[j], 0);
283 n != int(string::npos);
284 n = outgoing.find(outParticleNamesMG[j], n)) {
285 outgo.push_back(outParticleNumbers[j]);
286 outgoing.erase(outgoing.begin()+n,
287 outgoing.begin()+n+outParticleNamesMG[j].size());
299 for(
int l=0; l < int(outgo.size()); ++l)
300 if ( (abs(outgo[l]) > 20 && abs(outgo[l]) <= 25) || outgo[l] == 2400)
303 int nZeros = (outgo.size() - nBosons)/2;
304 for(
int l=0; l < nZeros; ++l)
310 for(
int l=0; l < int(outgo.size()); ++l)
311 if ( (abs(outgo[l]) > 20 && abs(outgo[l]) <= 25) || outgo[l] == 2400)
312 inter.push_back(outgo[l]);
318 for(
int i=0; i < int(inter.size()); ++i)
319 hardIntermediate.push_back(inter[i]);
322 if (incom.size() != 2)
323 cout <<
"Only two incoming particles allowed" << endl;
325 hardIncoming1 = incom[0];
326 hardIncoming2 = incom[1];
331 for(
int i = 0; i < int(userParticleNumbers.size()); ++i)
332 if (userParticleNumbers[i] > 0) {
333 hardOutgoing2.push_back( userParticleNumbers[i]);
334 hardIntermediate.push_back(0);
336 }
else if (userParticleNumbers[i] < 0) {
337 hardOutgoing1.push_back( userParticleNumbers[i]);
339 hardIntermediate.push_back(0);
343 for(
int i=0; i < int(outgo.size()); ++i)
350 && outgo[i] != 1000022
351 && outgo[i] < 10000000)
352 hardOutgoing2.push_back( outgo[i]);
353 else if (outgo[i] < 0)
354 hardOutgoing1.push_back( outgo[i]);
357 for(
int i=0; i < int(outgo.size()); ++i)
358 if ( outgo[i] == 2400)
359 hardOutgoing2.push_back( outgo[i]);
364 for(
int i=0; i < int(outgo.size()); ++i)
365 if ( (outgo[i] == 2212
368 || outgo[i] == 1000022
369 || outgo[i] > 10000000)
371 hardOutgoing2.push_back( outgo[i]);
373 }
else if ( (outgo[i] == 2212
376 || outgo[i] == 1000022
377 || outgo[i] > 10000000)
379 hardOutgoing1.push_back( outgo[i]);
391 bool DireHardProcess::allowCandidates(
int iPos, vector<int> Pos1,
392 vector<int> Pos2,
const Event& event){
397 int type = (
event[iPos].col() > 0) ? 1 : (event[iPos].acol() > 0) ? -1 : 0;
399 if (type == 0)
return true;
402 int col =
event[iPos].col();
404 for(
int i=0; i < int(event.size()); ++i)
406 && (( event[i].isFinal() && event[i].acol() == col)
407 ||(
event[i].status() == -21 &&
event[i].col() == col) ))
410 vector<int> partners;
411 for(
int i=0; i < int(event.size()); ++i)
412 for(
int j=0; j < int(Pos1.size()); ++j)
413 if ( Pos1[j] != 0 && i != Pos1[j] && event[Pos1[j]].colType() != 0
414 && ((
event[i].isFinal() &&
event[i].col() ==
event[Pos1[j]].acol())
415 ||( event[i].status() == -21
416 &&
event[i].acol() ==
event[Pos1[j]].acol()) ))
417 partners.push_back(i);
420 if (event[iPartner].status() == -21){
421 for(
int i=0; i < int(partners.size()); ++i)
422 if ( partners[i] == iPartner)
427 int col =
event[iPos].acol();
429 for(
int i=0; i < int(event.size()); ++i)
431 && (( event[i].isFinal() && event[i].col() == col)
432 ||(!
event[i].isFinal() &&
event[i].acol() == col) ))
435 vector<int> partners;
436 for(
int i=0; i < int(event.size()); ++i)
437 for(
int j=0; j < int(Pos2.size()); ++j)
438 if ( Pos2[j] != 0 && i != Pos2[j] && event[Pos2[j]].colType() != 0
439 && ((
event[i].isFinal() &&
event[i].acol() ==
event[Pos2[j]].col())
440 ||( event[i].status() == -21
441 &&
event[i].col() ==
event[Pos2[j]].col()) ))
442 partners.push_back(i);
445 if (event[iPartner].status() == -21){
446 for(
int i=0; i < int(partners.size()); ++i){
447 if ( partners[i] == iPartner)
462 void DireHardProcess::storeCandidates(
const Event& event,
string process){
469 vector<int> intermediates;
470 for(
int i =0; i < int(hardIntermediate.size());++i)
471 intermediates.push_back( hardIntermediate[i]);
474 vector<int> outgoing1;
475 for(
int i =0; i < int(hardOutgoing1.size());++i)
476 outgoing1.push_back( hardOutgoing1[i]);
477 vector<int> outgoing2;
478 for(
int i =0; i < int(hardOutgoing2.size());++i)
479 outgoing2.push_back( hardOutgoing2[i]);
482 PosIntermediate.resize(0);
483 PosOutgoing1.resize(0);
484 PosOutgoing2.resize(0);
485 for(
int i =0; i < int(hardIntermediate.size());++i)
486 PosIntermediate.push_back(0);
487 for(
int i =0; i < int(hardOutgoing1.size());++i)
488 PosOutgoing1.push_back(0);
489 for(
int i =0; i < int(hardOutgoing2.size());++i)
490 PosOutgoing2.push_back(0);
494 if ( process.compare(
"pp>jj") == 0
495 || process.compare(
"e+e->jj") == 0
496 || process.compare(
"e+e->(z>jj)") == 0 ){
497 for(
int i =0; i < int(hardOutgoing1.size());++i)
499 for(
int i =0; i < int(hardOutgoing2.size());++i)
507 bool isInclusive =
true;
508 for(
int i =0; i < int(hardOutgoing1.size());++i)
509 if (hardOutgoing1[i] < 10000000) isInclusive =
false;
510 for(
int i =0; i < int(hardOutgoing2.size());++i)
511 if (hardOutgoing2[i] < 10000000) isInclusive =
false;
513 for(
int i =0; i < int(hardOutgoing1.size());++i)
515 for(
int i =0; i < int(hardOutgoing2.size());++i)
523 vector<int> iPosChecked;
527 bool hasOnlyContainers =
true;
528 for(
int i =0; i < int(hardOutgoing1.size());++i)
529 if ( hardOutgoing1[i] != 1100
530 && hardOutgoing1[i] != 1200
531 && hardOutgoing1[i] != 5000)
532 hasOnlyContainers =
false;
533 for(
int i =0; i < int(hardOutgoing2.size());++i)
534 if ( hardOutgoing2[i] != 1100
535 && hardOutgoing2[i] != 1200
536 && hardOutgoing2[i] != 5000)
537 hasOnlyContainers =
false;
539 if (hasOnlyContainers){
541 PosOutgoing1.resize(0);
542 PosOutgoing2.resize(0);
546 for(
int i=0; i < int(event.size()); ++i){
549 if ( !event[i].isFinal() )
continue;
553 for(
int k=0; k < int(iPosChecked.size()); ++k){
554 if (i == iPosChecked[k])
559 for(
int j=0; j < int(outgoing2.size()); ++j){
562 if ( outgoing2[j] == 1100
563 && ( event[i].idAbs() == 11
564 ||
event[i].idAbs() == 13
565 ||
event[i].idAbs() == 15) ){
566 PosOutgoing2.push_back(i);
567 iPosChecked.push_back(i);
571 if ( outgoing2[j] == 1200
572 && ( event[i].idAbs() == 12
573 || event[i].idAbs() == 14
574 || event[i].idAbs() == 16) ){
575 PosOutgoing2.push_back(i);
576 iPosChecked.push_back(i);
580 if ( outgoing2[j] == 5000 && event[i].idAbs() == 5 ){
581 PosOutgoing2.push_back(i);
582 iPosChecked.push_back(i);
589 for(
int k=0; k < int(iPosChecked.size()); ++k){
590 if (i == iPosChecked[k])
595 for(
int j=0; j < int(outgoing1.size()); ++j){
598 if ( outgoing1[j] == 1100
599 && ( event[i].idAbs() == 11
600 ||
event[i].idAbs() == 13
601 ||
event[i].idAbs() == 15) ){
602 PosOutgoing1.push_back(i);
603 iPosChecked.push_back(i);
607 if ( outgoing1[j] == 1200
608 && ( event[i].idAbs() == 12
609 || event[i].idAbs() == 14
610 || event[i].idAbs() == 16) ){
611 PosOutgoing1.push_back(i);
612 iPosChecked.push_back(i);
616 if ( outgoing1[j] == 5000 && event[i].idAbs() == 5 ){
617 PosOutgoing1.push_back(i);
618 iPosChecked.push_back(i);
631 for(
int i=0; i < int(intermediates.size()); ++i){
634 if (intermediates[i] == 0)
continue;
637 bool matchesFinalBoson =
false;
638 for(
int j =0; j< int(outgoing1.size()); ++j){
639 if ( intermediates[i] == outgoing1[j] )
640 matchesFinalBoson =
true;
642 for(
int j =0; j< int(outgoing2.size()); ++j){
643 if ( intermediates[i] == outgoing2[j] )
644 matchesFinalBoson =
true;
646 if (!matchesFinalBoson)
continue;
649 for(
int j=0; j < int(event.size()); ++j) {
653 for(
int m=0; m < int(iPosChecked.size()); ++m)
654 if (j == iPosChecked[m]) skip =
true;
659 if ( (event[j].
id() == intermediates[i])
660 ||(event[j].idAbs() == 24 && intermediates[i] == 2400) ) {
662 PosIntermediate[i] = j;
663 intermediates[i] = 0;
665 bool indexSet =
false;
667 for(
int k=0; k < int(outgoing1.size()); ++k) {
668 if (event[j].
id() == outgoing1[k] && !indexSet){
675 for(
int k=0; k < int(outgoing2.size()); ++k) {
676 if (event[j].
id() == outgoing2[k] && !indexSet){
684 for(
int k=0; k < int(outgoing2.size()); ++k) {
685 if (event[j].idAbs() == 24 && outgoing2[k] == 2400 && !indexSet ){
692 iPosChecked.push_back(j);
699 for(
int i=0; i < int(intermediates.size()); ++i){
702 if (intermediates[i] == 0)
continue;
705 for(
int j=0; j < int(event.size()); ++j) {
708 if ( (event[j].
id() == intermediates[i])
709 ||(event[j].idAbs() == 24 && intermediates[i] == 2400) ) {
711 PosIntermediate[i] = j;
712 intermediates[i] = 0;
714 int iPos1 =
event[j].daughter1();
715 int iPos2 =
event[j].daughter2();
719 for(
int k=iPos1; k <= iPos2; ++k){
720 int id =
event[k].id();
724 for(
int m=0; m < int(iPosChecked.size()); ++m)
725 if (k == iPosChecked[m]) skip =
true;
729 for(
int l=0; l < int(outgoing2.size()); ++l)
730 if ( outgoing2[l] != 99 ){
732 if (
id == outgoing2[l]
734 || (
id > 0 && abs(
id) < 10 && outgoing2[l] == 2212) ){
739 iPosChecked.push_back(k);
746 for(
int l=0; l < int(outgoing1.size()); ++l)
747 if ( outgoing1[l] != 99 ){
749 if (
id == outgoing1[l]
751 || (
id < 0 && abs(
id) < 10 && outgoing1[l] == 2212) ){
756 iPosChecked.push_back(k);
769 for(
int i=0; i < int(outgoing1.size()); ++i)
770 if (outgoing1[i] != 99)
772 for(
int i=0; i < int(outgoing2.size()); ++i)
773 if (outgoing2[i] != 99)
781 for(
int i=0; i < int(event.size()); ++i){
783 if ( !event[i].isFinal() ||
event[i].colType() != 0)
787 for(
int k=0; k < int(iPosChecked.size()); ++k){
788 if (i == iPosChecked[k])
794 for(
int j=0; j < int(outgoing2.size()); ++j){
797 if ( outgoing2[j] == 99
798 || outgoing2[j] == 2212
799 || abs(outgoing2[j]) < 10)
803 if ( event[i].
id() == outgoing2[j] ){
806 iPosChecked.push_back(i);
811 for(
int j=0; j < int(outgoing1.size()); ++j){
814 if ( outgoing1[j] == 99
815 || outgoing1[j] == 2212
816 || abs(outgoing1[j]) < 10)
820 if (event[i].
id() == outgoing1[j] ){
823 iPosChecked.push_back(i);
828 multimap<int,int> out2copy;
829 for(
int i=0; i < int(event.size()); ++i)
830 for(
int j=0; j < int(outgoing2.size()); ++j)
833 if ( outgoing2[j] != 99
834 && outgoing2[j] != 2212
835 && ( abs(outgoing2[j]) < 10
836 || (abs(outgoing2[j]) > 1000000 && abs(outgoing2[j]) < 1000010)
837 || (abs(outgoing2[j]) > 2000000 && abs(outgoing2[j]) < 2000010)
838 || abs(outgoing2[j]) == 1000021 )
839 && event[i].isFinal()
840 &&
event[i].id() == outgoing2[j] ){
841 out2copy.insert(make_pair(j, i));
844 multimap<int,int> out1copy;
845 for(
int i=0; i < int(event.size()); ++i)
846 for(
int j=0; j < int(outgoing1.size()); ++j)
849 if ( outgoing1[j] != 99
850 && outgoing1[j] != 2212
851 && ( abs(outgoing1[j]) < 10
852 || (abs(outgoing1[j]) > 1000000 && abs(outgoing1[j]) < 1000010)
853 || (abs(outgoing1[j]) > 2000000 && abs(outgoing1[j]) < 2000010)
854 || abs(outgoing1[j]) == 1000021 )
855 && event[i].isFinal()
856 &&
event[i].id() == outgoing1[j] ){
857 out1copy.insert(make_pair(j, i));
860 if ( out1copy.size() > out2copy.size()){
864 vector<int> indexWasSet;
865 for ( multimap<int, int>::iterator it = out2copy.begin();
866 it != out2copy.end(); ++it ) {
867 if ( allowCandidates(it->second, PosOutgoing1, PosOutgoing2, event) ){
871 for(
int k=0; k < int(iPosChecked.size()); ++k)
872 if (it->second == iPosChecked[k]) skip =
true;
874 for(
int k=0; k < int(indexWasSet.size()); ++k)
875 if (it->first == indexWasSet[k]) skip =
true;
879 PosOutgoing2[it->first] = it->second;
881 outgoing2[it->first] = 99;
882 iPosChecked.push_back(it->second);
883 indexWasSet.push_back(it->first);
887 indexWasSet.resize(0);
888 for ( multimap<int, int>::iterator it = out1copy.begin();
889 it != out1copy.end(); ++it ) {
890 if ( allowCandidates(it->second, PosOutgoing1, PosOutgoing2, event) ){
894 for(
int k=0; k < int(iPosChecked.size()); ++k)
895 if (it->second == iPosChecked[k]) skip =
true;
897 for(
int k=0; k < int(indexWasSet.size()); ++k)
898 if (it->first == indexWasSet[k]) skip =
true;
902 PosOutgoing1[it->first] = it->second;
904 outgoing1[it->first] = 99;
905 iPosChecked.push_back(it->second);
906 indexWasSet.push_back(it->first);
914 vector<int> indexWasSet;
915 for ( multimap<int, int>::iterator it = out1copy.begin();
916 it != out1copy.end(); ++it ) {
917 if ( allowCandidates(it->second, PosOutgoing1, PosOutgoing2, event) ){
921 for(
int k=0; k < int(iPosChecked.size()); ++k)
922 if (it->second == iPosChecked[k]) skip =
true;
924 for(
int k=0; k < int(indexWasSet.size()); ++k)
925 if (it->first == indexWasSet[k]) skip =
true;
929 PosOutgoing1[it->first] = it->second;
931 outgoing1[it->first] = 99;
932 iPosChecked.push_back(it->second);
933 indexWasSet.push_back(it->first);
937 indexWasSet.resize(0);
938 for ( multimap<int, int>::iterator it = out2copy.begin();
939 it != out2copy.end(); ++it ) {
940 if ( allowCandidates(it->second, PosOutgoing1, PosOutgoing2, event) ){
944 for(
int k=0; k < int(iPosChecked.size()); ++k)
945 if (it->second == iPosChecked[k]) skip =
true;
947 for(
int k=0; k < int(indexWasSet.size()); ++k)
948 if (it->first == indexWasSet[k]) skip =
true;
952 PosOutgoing2[it->first] = it->second;
954 outgoing2[it->first] = 99;
955 iPosChecked.push_back(it->second);
956 indexWasSet.push_back(it->first);
966 for(
int i=0; i < int(event.size()); ++i){
969 if ( !event[i].isFinal() ||
event[i].colType() == 0)
974 for(
int k=0; k < int(iPosChecked.size()); ++k){
975 if (i == iPosChecked[k])
981 for(
int j=0; j < int(outgoing2.size()); ++j){
985 if ( outgoing2[j] == 99
986 || outgoing2[j] == 2212
987 || (abs(outgoing2[j]) > 10 && abs(outgoing2[j]) < 20)
988 || outgoing2[j] == 1100
989 || outgoing2[j] == 1200
990 || outgoing2[j] == 2400 )
994 if (event[i].
id() == outgoing2[j]){
999 iPosChecked.push_back(i);
1005 for(
int j=0; j < int(outgoing1.size()); ++j){
1008 if ( outgoing1[j] == 99
1009 || outgoing1[j] == 2212
1010 || (abs(outgoing1[j]) > 10 && abs(outgoing1[j]) < 20)
1011 || outgoing1[j] == 1100
1012 || outgoing1[j] == 1200
1013 || outgoing1[j] == 2400 )
1016 if (event[i].
id() == outgoing1[j]){
1018 PosOutgoing1[j] = i;
1021 iPosChecked.push_back(i);
1035 bool DireHardProcess::matchesAnyOutgoing(
int iPos,
const Event& event){
1038 bool matchQN1 =
false;
1040 bool matchQN2 =
false;
1044 bool matchHP =
false;
1047 for(
int i=0; i < int(PosOutgoing1.size()); ++i)
1049 if ( event[iPos].
id() == state[PosOutgoing1[i]].id()
1050 &&
event[iPos].colType() == state[PosOutgoing1[i]].colType()
1051 &&
event[iPos].chargeType() == state[PosOutgoing1[i]].chargeType()
1052 && ( (
event[iPos].col() > 0
1053 &&
event[iPos].col() == state[PosOutgoing1[i]].col())
1054 || ( event[iPos].acol() > 0
1055 &&
event[iPos].acol() == state[PosOutgoing1[i]].acol()))
1056 &&
event[iPos].charge() == state[PosOutgoing1[i]].charge() )
1060 for(
int i=0; i < int(PosOutgoing2.size()); ++i)
1062 if ( event[iPos].
id() == state[PosOutgoing2[i]].id()
1063 &&
event[iPos].colType() == state[PosOutgoing2[i]].colType()
1064 &&
event[iPos].chargeType() == state[PosOutgoing2[i]].chargeType()
1065 && ( (
event[iPos].col() > 0
1066 &&
event[iPos].col() == state[PosOutgoing2[i]].col())
1067 || ( event[iPos].acol() > 0
1068 &&
event[iPos].acol() == state[PosOutgoing2[i]].acol()))
1069 &&
event[iPos].charge() == state[PosOutgoing2[i]].charge() )
1074 if ( event[iPos].mother1()*
event[iPos].mother2() == 12
1076 || (
event[iPos].status() == 44
1077 &&
event[
event[iPos].mother1()].mother1()
1078 *
event[
event[iPos].mother1()].mother2() == 12 )
1079 || ( event[iPos].status() == 48
1080 &&
event[
event[iPos].mother1()].mother1()
1081 *
event[
event[iPos].mother1()].mother2() == 12 )
1083 || ( event[iPos].status() == 23
1084 &&
event[
event[iPos].mother1()].mother1()
1085 *
event[
event[iPos].mother1()].mother2() == 12 )
1088 || ( event[iPos].status() == 23
1089 &&
event[
event[iPos].mother1()].status() == -22
1090 &&
event[
event[
event[iPos].mother1()].mother1()].status() == -22
1091 &&
event[
event[
event[iPos].mother1()].mother1()].mother1()
1092 *
event[
event[
event[iPos].mother1()].mother1()].mother2() == 12 ) )
1096 return ( matchHP && (matchQN1 || matchQN2) );
1107 bool DireHardProcess::findOtherCandidates(
int iPos,
const Event& event,
1111 bool foundCopy =
false;
1114 int id =
event[iPos].id();
1115 int col =
event[iPos].col();
1116 int acl =
event[iPos].acol();
1120 int iMoth1 =
event[iPos].mother1();
1121 int iMoth2 =
event[iPos].mother2();
1122 if ( iMoth1 > 0 && iMoth2 == 0 ) {
1123 bool hasIdentifiedMother =
false;
1124 for(
int i=0; i < int(PosIntermediate.size()); ++i)
1126 if ( event[iMoth1].
id() == state[PosIntermediate[i]].id()
1127 &&
event[iMoth1].colType() == state[PosIntermediate[i]].colType()
1128 &&
event[iMoth1].chargeType() == state[PosIntermediate[i]].chargeType()
1129 &&
event[iMoth1].col() == state[PosIntermediate[i]].col()
1130 &&
event[iMoth1].acol() == state[PosIntermediate[i]].acol()
1131 &&
event[iMoth1].charge() == state[PosIntermediate[i]].charge() )
1132 hasIdentifiedMother =
true;
1133 if(hasIdentifiedMother && event[iMoth1].
id() != id)
return false;
1137 vector<int> candidates1;
1138 vector<int> candidates2;
1140 for(
int i=0; i < int(PosOutgoing1.size()); ++i)
1142 if (
id == state[PosOutgoing1[i]].
id()
1143 && col == state[PosOutgoing1[i]].col()
1144 && acl == state[PosOutgoing1[i]].acol() )
1145 candidates1.push_back(i);
1147 for(
int i=0; i < int(PosOutgoing2.size()); ++i)
1149 if (
id == state[PosOutgoing2[i]].
id()
1150 && col == state[PosOutgoing2[i]].col()
1151 && acl == state[PosOutgoing2[i]].acol() )
1152 candidates2.push_back(i);
1155 if ( candidates1.size() + candidates2.size() != 1 )
return false;
1158 unordered_map<int,int> further1;
1159 for(
int i=0; i < int(state.size()); ++i)
1160 for(
int j=0; j < int(PosOutgoing1.size()); ++j)
1163 if ( state[i].isFinal()
1164 && i != PosOutgoing1[j]
1165 && state[PosOutgoing1[j]].id() ==
id
1166 && state[i].id() == id ){
1168 vector<int> newPosOutgoing1;
1169 for(
int k=0; k < int(PosOutgoing1.size()); ++k)
1170 if ( k != j ) newPosOutgoing1.push_back( PosOutgoing1[k] );
1172 if ( allowCandidates(i, newPosOutgoing1, PosOutgoing2, state) )
1173 further1.insert(make_pair(j, i));
1177 unordered_map<int,int> further2;
1178 for(
int i=0; i < int(state.size()); ++i)
1179 for(
int j=0; j < int(PosOutgoing2.size()); ++j)
1182 if ( state[i].isFinal()
1183 && i != PosOutgoing2[j]
1184 && state[PosOutgoing2[j]].id() ==
id
1185 && state[i].id() == id ){
1187 vector<int> newPosOutgoing2;
1188 for(
int k=0; k < int(PosOutgoing2.size()); ++k)
1189 if ( k != j ) newPosOutgoing2.push_back( PosOutgoing2[k] );
1191 if ( allowCandidates(i, PosOutgoing1, newPosOutgoing2, state) )
1192 further2.insert(make_pair(j, i));
1196 unordered_map<int,int>::iterator it2 = further2.begin();
1197 while(it2 != further2.end()) {
1198 bool remove =
false;
1199 for(
int j=0; j < int(PosOutgoing2.size()); ++j)
1200 if (it2->second == PosOutgoing2[j] )
remove =
true;
1201 if (
remove ) further2.erase(it2++);
1204 unordered_map<int,int>::iterator it1 = further1.begin();
1205 while(it1 != further1.end()) {
1206 bool remove =
false;
1207 for(
int j=0; j < int(PosOutgoing1.size()); ++j)
1208 if (it1->second == PosOutgoing1[j] )
remove =
true;
1209 if (
remove ) further1.erase(it1++);
1214 foundCopy = (doReplace)
1215 ? exchangeCandidates(candidates1, candidates2, further1, further2)
1216 : (further1.size() + further2.size() > 0);
1227 bool DireHardProcess::exchangeCandidates( vector<int> candidates1,
1228 vector<int> candidates2, unordered_map<int,int> further1,
1229 unordered_map<int,int> further2) {
1231 int nOld1 = candidates1.size();
1232 int nOld2 = candidates2.size();
1233 int nNew1 = further1.size();
1234 int nNew2 = further2.size();
1235 bool exchanged =
false;
1237 if ( nOld1 == 1 && nOld2 == 0 && nNew1 == 1 && nNew2 == 0){
1238 PosOutgoing1[further1.begin()->first] = further1.begin()->second;
1240 }
else if ( nOld1 == 0 && nOld2 == 1 && nNew1 == 0 && nNew2 == 1){
1241 PosOutgoing2[further2.begin()->first] = further2.begin()->second;
1244 }
else if ( nNew1 > 1 && nNew2 == 0 ) {
1245 PosOutgoing1[further1.begin()->first] = further1.begin()->second;
1247 }
else if ( nNew1 == 0 && nNew2 > 0 ) {
1248 PosOutgoing2[further2.begin()->first] = further2.begin()->second;
1265 void DireMergingHooks::init(){
1268 if (isInit) { store(); isInit =
false; isStored =
true;
return;}
1269 if (isStored) { restore(); isInit =
true; isStored =
false;
return;}
1271 isInit = isStored =
false;
1274 processSave = settingsPtr->word(
"Merging:Process");
1275 if (processSave ==
"void")
return;
1281 double alphaSvalueFSR = settingsPtr->parm(
"TimeShower:alphaSvalue");
1282 int alphaSorderFSR = settingsPtr->mode(
"TimeShower:alphaSorder");
1283 int alphaSnfmax = settingsPtr->mode(
"StandardModel:alphaSnfmax");
1284 int alphaSuseCMWFSR= settingsPtr->flag(
"TimeShower:alphaSuseCMW");
1285 AlphaS_FSRSave.init(alphaSvalueFSR, alphaSorderFSR, alphaSnfmax,
1287 double alphaSvalueISR = settingsPtr->parm(
"SpaceShower:alphaSvalue");
1288 int alphaSorderISR = settingsPtr->mode(
"SpaceShower:alphaSorder");
1289 int alphaSuseCMWISR= settingsPtr->flag(
"SpaceShower:alphaSuseCMW");
1290 AlphaS_ISRSave.init(alphaSvalueISR, alphaSorderISR, alphaSnfmax,
1294 int alphaEMFSRorder = settingsPtr->mode(
"TimeShower:alphaEMorder");
1295 AlphaEM_FSRSave.init(alphaEMFSRorder, settingsPtr);
1296 int alphaEMISRorder = settingsPtr->mode(
"SpaceShower:alphaEMorder");
1297 AlphaEM_ISRSave.init(alphaEMISRorder, settingsPtr);
1300 doUserMergingSave = settingsPtr->flag(
"Merging:doUserMerging");
1302 doMGMergingSave = settingsPtr->flag(
"Merging:doMGMerging");
1304 doKTMergingSave = settingsPtr->flag(
"Merging:doKTMerging");
1306 doPTLundMergingSave = settingsPtr->flag(
"Merging:doPTLundMerging");
1308 doCutBasedMergingSave = settingsPtr->flag(
"Merging:doCutBasedMerging");
1310 ktTypeSave = settingsPtr->mode(
"Merging:ktType");
1313 doNL3TreeSave = settingsPtr->flag(
"Merging:doNL3Tree");
1314 doNL3LoopSave = settingsPtr->flag(
"Merging:doNL3Loop");
1315 doNL3SubtSave = settingsPtr->flag(
"Merging:doNL3Subt");
1316 bool doNL3 = doNL3TreeSave || doNL3LoopSave || doNL3SubtSave;
1319 doUNLOPSTreeSave = settingsPtr->flag(
"Merging:doUNLOPSTree");
1320 doUNLOPSLoopSave = settingsPtr->flag(
"Merging:doUNLOPSLoop");
1321 doUNLOPSSubtSave = settingsPtr->flag(
"Merging:doUNLOPSSubt");
1322 doUNLOPSSubtNLOSave = settingsPtr->flag(
"Merging:doUNLOPSSubtNLO");
1323 bool doUNLOPS = doUNLOPSTreeSave || doUNLOPSLoopSave
1324 || doUNLOPSSubtSave || doUNLOPSSubtNLOSave;
1327 doUMEPSTreeSave = settingsPtr->flag(
"Merging:doUMEPSTree");
1328 doUMEPSSubtSave = settingsPtr->flag(
"Merging:doUMEPSSubt");
1329 nReclusterSave = settingsPtr->mode(
"Merging:nRecluster");
1330 nQuarksMergeSave = settingsPtr->mode(
"Merging:nQuarksMerge");
1331 nRequestedSave = settingsPtr->mode(
"Merging:nRequested");
1332 bool doUMEPS = doUMEPSTreeSave || doUMEPSSubtSave;
1335 doEstimateXSection = settingsPtr->flag(
"Merging:doXSectionEstimate");
1337 doMOPSSave = settingsPtr->flag(
"Dire:doMOPS");
1338 doMEMSave = settingsPtr->flag(
"Dire:doMEM");
1342 includeWGTinXSECSave = settingsPtr->flag(
"Merging:includeWeightInXsection");
1345 applyVeto = settingsPtr->flag(
"Merging:applyVeto");
1348 hardProcess->clear();
1351 inputEvent.init(
"(hard process)", particleDataPtr);
1353 doRemoveDecayProducts = settingsPtr->flag(
"Merging:mayRemoveDecayProducts");
1356 if ( doMGMergingSave )
1357 hardProcess->initOnLHEF(lheInputFile, particleDataPtr);
1359 hardProcess->initOnProcess(processSave, particleDataPtr);
1362 includeMassiveSave = settingsPtr->flag(
"Merging:includeMassive");
1363 enforceStrongOrderingSave = settingsPtr->flag
1364 (
"Merging:enforceStrongOrdering");
1365 scaleSeparationFactorSave = settingsPtr->parm
1366 (
"Merging:scaleSeparationFactor");
1367 orderInRapiditySave = settingsPtr->flag(
"Merging:orderInRapidity");
1370 nonJoinedNormSave = settingsPtr->parm(
"Merging:nonJoinedNorm");
1371 fsrInRecNormSave = settingsPtr->parm(
"Merging:fsrInRecNorm");
1372 pickByFullPSave = settingsPtr->flag(
"Merging:pickByFullP");
1373 pickByPoPT2Save = settingsPtr->flag(
"Merging:pickByPoPT2");
1374 includeRedundantSave = settingsPtr->flag(
"Merging:includeRedundant");
1377 unorderedScalePrescipSave =
1378 settingsPtr->mode(
"Merging:unorderedScalePrescrip");
1379 unorderedASscalePrescipSave =
1380 settingsPtr->mode(
"Merging:unorderedASscalePrescrip");
1381 unorderedPDFscalePrescipSave =
1382 settingsPtr->mode(
"Merging:unorderedPDFscalePrescrip");
1383 incompleteScalePrescipSave =
1384 settingsPtr->mode(
"Merging:incompleteScalePrescrip");
1387 allowColourShufflingSave =
1388 settingsPtr->flag(
"Merging:allowColourShuffling");
1392 resetHardQRenSave = settingsPtr->flag(
"Merging:usePythiaQRenHard");
1393 resetHardQFacSave = settingsPtr->flag(
"Merging:usePythiaQFacHard");
1396 pickBySumPTSave = settingsPtr->flag(
"Merging:pickBySumPT");
1397 herwigAcollFSRSave = settingsPtr->parm(
"Merging:aCollFSR");
1398 herwigAcollISRSave = settingsPtr->parm(
"Merging:aCollISR");
1401 pT0ISRSave = settingsPtr->parm(
"SpaceShower:pT0Ref");
1402 pTcutSave = settingsPtr->parm(
"SpaceShower:pTmin");
1403 pTcutSave = max(pTcutSave,pT0ISRSave);
1406 weightCKKWLSave = {1.};
1407 weightFIRSTSave = {0.};
1413 tmsListSave.resize(0);
1415 kFactor0jSave = settingsPtr->parm(
"Merging:kFactor0j");
1416 kFactor1jSave = settingsPtr->parm(
"Merging:kFactor1j");
1417 kFactor2jSave = settingsPtr->parm(
"Merging:kFactor2j");
1419 muFSave = settingsPtr->parm(
"Merging:muFac");
1420 muRSave = settingsPtr->parm(
"Merging:muRen");
1421 muFinMESave = settingsPtr->parm(
"Merging:muFacInME");
1422 muRinMESave = settingsPtr->parm(
"Merging:muRenInME");
1424 doWeakClusteringSave = settingsPtr->flag(
"Merging:allowWeakClustering");
1425 doSQCDClusteringSave = settingsPtr->flag(
"Merging:allowSQCDClustering");
1426 DparameterSave = settingsPtr->parm(
"Merging:Dparameter");
1429 if ( doKTMergingSave || doUserMergingSave || doPTLundMergingSave
1432 tmsValueSave = settingsPtr->parm(
"Merging:TMS");
1433 nJetMaxSave = settingsPtr->mode(
"Merging:nJetMax");
1434 nJetMaxNLOSave = -1;
1435 }
else if (doMGMergingSave) {
1437 tmsValueSave = hardProcess->tms;
1438 nJetMaxSave = settingsPtr->mode(
"Merging:nJetMax");
1439 nJetMaxNLOSave = -1;
1440 }
else if (doCutBasedMergingSave) {
1443 nJetMaxSave = settingsPtr->mode(
"Merging:nJetMax");
1444 nJetMaxNLOSave = -1;
1447 tmsListSave.resize(0);
1448 double drms = settingsPtr->parm(
"Merging:dRijMS");
1449 double ptms = settingsPtr->parm(
"Merging:pTiMS");
1450 double qms = settingsPtr->parm(
"Merging:QijMS");
1451 tmsListSave.push_back(drms);
1452 tmsListSave.push_back(ptms);
1453 tmsListSave.push_back(qms);
1458 if ( doNL3 || doUNLOPS || doEstimateXSection ) {
1459 tmsValueSave = settingsPtr->parm(
"Merging:TMS");
1460 nJetMaxSave = settingsPtr->mode(
"Merging:nJetMax");
1461 nJetMaxNLOSave = settingsPtr->mode(
"Merging:nJetMaxNLO");
1465 if ( doNL3 || doUNLOPS ) includeWGTinXSECSave =
false;
1467 hasJetMaxLocal =
false;
1468 nJetMaxLocal = nJetMaxSave;
1469 nJetMaxNLOLocal = nJetMaxNLOSave;
1472 useShowerPluginSave = settingsPtr->flag(
"Merging:useShowerPlugin");
1474 bool writeBanner = doKTMergingSave || doMGMergingSave
1475 || doUserMergingSave
1476 || doNL3 || doUNLOPS || doUMEPS
1477 || doPTLundMergingSave || doCutBasedMergingSave;
1481 if (!writeBanner)
return;
1484 cout <<
"\n *------------------ MEPS Merging Initialization ---------------"
1488 if ( doKTMergingSave || doMGMergingSave || doUserMergingSave
1489 || doPTLundMergingSave || doCutBasedMergingSave )
1490 cout <<
" | CKKW-L merge "
1492 <<
" |"<< setw(34) << processSave <<
" with up to"
1493 << setw(3) << nJetMaxSave <<
" additional jets |\n";
1495 cout <<
" | NL3 merge "
1497 <<
" |" << setw(31) << processSave <<
" with jets up to"
1498 << setw(3) << nJetMaxNLOSave <<
" correct to NLO |\n"
1499 <<
" | and up to" << setw(3) << nJetMaxSave
1500 <<
" additional jets included by CKKW-L merging at LO |\n";
1501 else if ( doUNLOPS )
1502 cout <<
" | UNLOPS merge "
1504 <<
" |" << setw(31) << processSave <<
" with jets up to"
1505 << setw(3)<< nJetMaxNLOSave <<
" correct to NLO |\n"
1506 <<
" | and up to" << setw(3) << nJetMaxSave
1507 <<
" additional jets included by UMEPS merging at LO |\n";
1509 cout <<
" | UMEPS merge "
1511 <<
" |" << setw(34) << processSave <<
" with up to"
1512 << setw(3) << nJetMaxSave <<
" additional jets |\n";
1514 if ( doKTMergingSave )
1515 cout <<
" | Merging scale is defined in kT, with value ktMS = "
1516 << tmsValueSave <<
" GeV";
1517 else if ( doMGMergingSave )
1518 cout <<
" | Perform automanted MG/ME merging \n"
1519 <<
" | Merging scale is defined in kT, with value ktMS = "
1520 << setw(6) << fixed << setprecision(1) << tmsValueSave <<
" GeV |";
1521 else if ( doUserMergingSave )
1522 cout <<
" | Merging scale is defined by the user, with value tMS = "
1523 << setw(6) << fixed << setprecision(1) << tmsValueSave <<
" |";
1524 else if ( doPTLundMergingSave )
1525 cout <<
" | Merging scale is defined by Lund pT, with value tMS = "
1526 << setw(6) << fixed << setprecision(1) << tmsValueSave <<
" GeV |";
1527 else if ( doCutBasedMergingSave )
1528 cout <<
" | Merging scale is defined by combination of Delta R_{ij}, pT_i "
1530 <<
" | and Q_{ij} cut, with values "
1532 <<
" | Delta R_{ij,min} = "
1533 << setw(7) << scientific << setprecision(2) << tmsListSave[0]
1535 <<
" | pT_{i,min} = "
1536 << setw(6) << fixed << setprecision(1) << tmsListSave[1]
1538 <<
" | Q_{ij,min} = "
1539 << setw(6) << fixed << setprecision(1) << tmsListSave[2]
1541 else if ( doNL3TreeSave )
1542 cout <<
" | Generate tree-level O(alpha_s)-subtracted events "
1544 <<
" | Merging scale is defined by Lund pT, with value tMS = "
1545 << setw(6) << fixed << setprecision(1) << tmsValueSave <<
" GeV |";
1546 else if ( doNL3LoopSave )
1547 cout <<
" | Generate virtual correction unit-weight events "
1549 <<
" | Merging scale is defined by Lund pT, with value tMS = "
1550 << setw(6) << fixed << setprecision(1) << tmsValueSave <<
" GeV |";
1551 else if ( doNL3SubtSave )
1552 cout <<
" | Generate reclustered tree-level events "
1554 <<
" | Merging scale is defined by Lund pT, with value tMS = "
1555 << setw(6) << fixed << setprecision(1) << tmsValueSave <<
" GeV |";
1556 else if ( doUNLOPSTreeSave )
1557 cout <<
" | Generate tree-level O(alpha_s)-subtracted events "
1559 <<
" | Merging scale is defined by Lund pT, with value tMS = "
1560 << setw(6) << fixed << setprecision(1) << tmsValueSave <<
" GeV |";
1561 else if ( doUNLOPSLoopSave )
1562 cout <<
" | Generate virtual correction unit-weight events "
1564 <<
" | Merging scale is defined by Lund pT, with value tMS = "
1565 << setw(6) << fixed << setprecision(1) << tmsValueSave <<
" GeV |";
1566 else if ( doUNLOPSSubtSave )
1567 cout <<
" | Generate reclustered tree-level events "
1569 <<
" | Merging scale is defined by Lund pT, with value tMS = "
1570 << setw(6) << fixed << setprecision(1) << tmsValueSave <<
" GeV |";
1571 else if ( doUNLOPSSubtNLOSave )
1572 cout <<
" | Generate reclustered loop-level events "
1574 <<
" | Merging scale is defined by Lund pT, with value tMS = "
1575 << setw(6) << fixed << setprecision(1) << tmsValueSave <<
" GeV |";
1576 else if ( doUMEPSTreeSave )
1577 cout <<
" | Generate tree-level events "
1579 <<
" | Merging scale is defined by Lund pT, with value tMS = "
1580 << setw(6) << fixed << setprecision(1) << tmsValueSave <<
" GeV |";
1581 else if ( doUMEPSSubtSave )
1582 cout <<
" | Generate reclustered tree-level events "
1584 <<
" | Merging scale is defined by Lund pT, with value tMS = "
1585 << setw(6) << fixed << setprecision(1) << tmsValueSave <<
" GeV |";
1589 cout <<
"\n *-------------- END MEPS Merging Initialization ---------------"
1597 void DireMergingHooks::store() {
1599 hardProcessStore.hardIncoming1 = hardProcess->hardIncoming1;
1600 hardProcessStore.hardIncoming2 = hardProcess->hardIncoming2;
1601 hardProcessStore.hardOutgoing1 = hardProcess->hardOutgoing1;
1602 hardProcessStore.hardOutgoing2 = hardProcess->hardOutgoing2;
1603 hardProcessStore.hardIntermediate = hardProcess->hardIntermediate;
1604 hardProcessStore.state = hardProcess->state;
1605 hardProcessStore.PosOutgoing1 = hardProcess->PosOutgoing1;
1606 hardProcessStore.PosOutgoing2 = hardProcess->PosOutgoing2;
1607 hardProcessStore.PosIntermediate = hardProcess->PosIntermediate;
1608 hardProcessStore.tms = hardProcess->tms;
1610 nReclusterStore = nReclusterSave;
1611 nRequestedStore = nRequestedSave;
1612 pT0ISRStore = pT0ISRSave;
1613 pTcutStore = pTcutSave;
1614 inputEventStore = inputEvent;
1615 resonancesStore = resonances;
1616 muMIStore = muMISave;
1617 tmsValueStore = tmsValueSave;
1618 tmsValueNowStore = tmsValueNow;
1619 DparameterStore = DparameterSave;
1620 nJetMaxStore = nJetMaxSave;
1621 nJetMaxNLOStore = nJetMaxNLOSave;
1622 doOrderHistoriesStore = doOrderHistoriesSave;
1625 muFinMEStore = muFinMESave;
1626 muRinMEStore = muRinMESave;
1627 doIgnoreEmissionsStore = doIgnoreEmissionsSave;
1628 doIgnoreStepStore = doIgnoreStepSave;
1630 nMinMPIStore = nMinMPISave;
1631 nJetMaxLocalStore = nJetMaxLocal;
1632 nJetMaxNLOLocalStore = nJetMaxNLOLocal;
1633 hasJetMaxLocalStore = hasJetMaxLocal;
1634 nHardNowStore = nHardNowSave;
1635 nJetNowStore = nJetNowSave;
1636 tmsHardNowStore = tmsHardNowSave;
1637 tmsNowStore = tmsNowSave;
1643 void DireMergingHooks::restore() {
1645 hardProcess->hardIncoming1 = hardProcessStore.hardIncoming1;
1646 hardProcess->hardIncoming2 = hardProcessStore.hardIncoming2;
1647 hardProcess->hardOutgoing1 = hardProcessStore.hardOutgoing1;
1648 hardProcess->hardOutgoing2 = hardProcessStore.hardOutgoing2;
1649 hardProcess->hardIntermediate = hardProcessStore.hardIntermediate;
1650 hardProcess->state = hardProcessStore.state;
1651 hardProcess->PosOutgoing1 = hardProcessStore.PosOutgoing1;
1652 hardProcess->PosOutgoing2 = hardProcessStore.PosOutgoing2;
1653 hardProcess->PosIntermediate = hardProcessStore.PosIntermediate;
1654 hardProcess->tms = hardProcessStore.tms;
1656 nReclusterSave = nReclusterStore;
1657 nRequestedSave = nRequestedStore;
1658 pT0ISRSave = pT0ISRStore;
1659 pTcutSave = pTcutStore;
1660 inputEvent = inputEventStore;
1661 resonances = resonancesStore;
1662 muMISave = muMIStore;
1663 tmsValueSave = tmsValueStore;
1664 tmsValueNow = tmsValueNowStore;
1665 DparameterSave = DparameterStore;
1666 nJetMaxSave = nJetMaxStore;
1667 nJetMaxNLOSave = nJetMaxNLOStore;
1668 doOrderHistoriesSave = doOrderHistoriesStore;
1671 muFinMESave = muFinMEStore;
1672 muRinMESave = muRinMEStore;
1673 doIgnoreEmissionsSave = doIgnoreEmissionsStore;
1674 doIgnoreStepSave = doIgnoreStepStore;
1676 nMinMPISave = nMinMPIStore;
1677 nJetMaxLocal = nJetMaxLocalStore;
1678 nJetMaxNLOLocal = nJetMaxNLOLocalStore;
1679 hasJetMaxLocal = hasJetMaxLocalStore;
1680 nHardNowSave = nHardNowStore;
1681 nJetNowSave = nJetNowStore;
1682 tmsHardNowSave = tmsHardNowStore;
1683 tmsNowSave = tmsNowStore;
1691 bool DireMergingHooks::doVetoEmission(
const Event& event) {
1694 if ( doIgnoreEmissionsSave )
return false;
1697 if ( doUserMerging() || doMGMerging() || doKTMerging()
1698 || doPTLundMerging() || doCutBasedMerging() )
1701 if ( doMOPS() )
return false;
1706 int nSteps = getNumberOfClusteringSteps(event);
1708 double tnow = tmsNow( event);
1711 int nJetMax = nMaxJets();
1714 if ( nRecluster() > 0 ) nSteps = max(1, min(nJetMax-2, 1));
1716 if ( nSteps - 1 < nJetMax && nSteps >= 1 && tnow > tms() && tms() > 0. )
1720 if ( infoPtr->nMPI() > 1 ) veto =
false;
1724 if ( veto && doNL3Tree() ) setWeightCKKWL({0.});
1727 if ( !veto ) doIgnoreEmissionsSave =
true;
1738 bool DireMergingHooks::doVetoStep(
const Event& process,
const Event& event,
1739 bool doResonance ) {
1742 if ( doIgnoreStepSave && !doResonance )
return false;
1745 if ( doUMEPSTree() || doUMEPSSubt() || doUMEPSMerging() || doUNLOPSTree()
1746 || doUNLOPSLoop() || doUNLOPSSubt() || doUNLOPSSubtNLO()
1747 || doUNLOPSMerging() )
1750 if ( doMOPS() )
return false;
1755 if ( getProcessString().find(
"inc") != string::npos )
1756 nSteps = getNumberOfClusteringSteps( bareEvent( process,
false) );
1757 else nSteps = (doResonance) ? getNumberOfClusteringSteps(process)
1758 : getNumberOfClusteringSteps( bareEvent( process,
false) );
1761 int nJetMax = nMaxJets();
1763 double tnow = tmsNow( event );
1769 if ( !doResonance ) {
1772 pTsave = infoPtr->pTnow();
1773 if ( nRecluster() == 1) nSteps--;
1783 if ( nSteps > nMaxJetsNLO() && nSteps < nJetMax && tnow > tms()
1786 weightCKKWL1Save = {0.};
1788 weightCKKWL2Save = getWeightCKKWL();
1790 if ( !includeWGTinXSEC() ) setWeightCKKWL({0.});
1791 if ( includeWGTinXSEC() ) infoPtr->weightContainerPtr->
1792 setWeightNominal(0.);
1798 setEventVetoInfo(nSteps, tnow);
1813 bool revokeVeto =
false;
1819 bool check = (nHardInLeptons() == 0)&& (nHardOutLeptons() == 2)
1820 && (nHardOutPartons() == 2);
1828 if ( pTsave > 0. && check ) {
1831 int nResNow = nResInCurrent();
1838 int sysSize = partonSystemsPtr->sizeSys();
1839 for (
int i=0; i < nResNow; ++i ) {
1840 if ( partonSystemsPtr->sizeOut(sysSize - 1 - i) == 3 )
1841 goodSys.push_back(sysSize - 1 - i);
1845 for (
int i=0; i < int(goodSys.size()); ++i ) {
1848 int iMem1 = partonSystemsPtr->getOut(goodSys[i],0);
1849 int iMem2 = partonSystemsPtr->getOut(goodSys[i],1);
1850 int iMem3 = partonSystemsPtr->getOut(goodSys[i],2);
1853 int iEmtGlue = ((
event[iMem1].id() == 21) ? iMem1
1854 : ((event[iMem2].
id() == 21) ? iMem2
1855 : ((
event[iMem3].id() == 21) ? iMem3: 0)));
1856 int iEmtGamm = ((
event[iMem1].id() == 22) ? iMem1
1857 : ((event[iMem2].
id() == 22) ? iMem2
1858 : ((
event[iMem3].id() == 22) ? iMem3: 0)));
1860 int iEmt = (iEmtGlue != 0) ? iEmtGlue : iEmtGamm;
1864 if ( iEmt == iMem1 ) {
1865 iRad = (
event[iMem2].mother1() !=
event[iMem2].mother2())
1867 iRec = (
event[iMem3].mother1() ==
event[iMem3].mother2())
1869 }
else if ( iEmt == iMem2 ) {
1870 iRad = (
event[iMem1].mother1() !=
event[iMem1].mother2())
1872 iRec = (
event[iMem3].mother1() ==
event[iMem3].mother2())
1875 iRad = (
event[iMem1].mother1() !=
event[iMem1].mother2())
1877 iRec = (
event[iMem2].mother1() ==
event[iMem2].mother2())
1881 double pTres = rhoPythia(event, iRad, iEmt, iRec, 1);
1886 if ( pTres > pTsave ) {
1900 if ( revokeVeto && check ) {
1901 setWeightCKKWL(weightCKKWL2Save);
1902 }
else if ( check ) {
1903 setWeightCKKWL(weightCKKWL1Save);
1904 if ( weightCKKWL1Save[0] == 0. ) veto =
true;
1908 if ( !check && nSteps > nMaxJetsNLO() && nSteps < nJetMax && tnow > tms()
1911 if ( !includeWGTinXSEC() ) setWeightCKKWL({0.});
1912 if ( includeWGTinXSEC() ) infoPtr->weightContainerPtr->
1913 setWeightNominal(0.);
1919 if ( !veto || !doIgnoreStepSave ) doIgnoreStepSave =
true;
1935 int DireMergingHooks::getNumberOfClusteringSteps(
const Event& event,
1939 int nFinalPartons = 0;
1940 for (
int i=0; i <
event.size(); ++i)
1941 if ( event[i].isFinal()
1942 && isInHard( i, event)
1943 && (
event[i].isQuark() ||
event[i].isGluon()) )
1947 int nFinalLeptons = 0;
1948 for(
int i=0; i <
event.size(); ++i)
1949 if ( event[i].isFinal() && isInHard( i, event) &&
event[i].isLepton())
1953 for(
int i=0; i <
event.size(); ++i)
1954 if ( event[i].isFinal() && isInHard( i, event)
1955 &&
event[i].idAbs() == 1000022)
1959 for(
int i=0; i <
event.size(); ++i)
1960 if ( event[i].isFinal() && isInHard( i, event)
1961 && (
event[i].idAbs() == 1000011
1962 ||
event[i].idAbs() == 2000011
1963 ||
event[i].idAbs() == 1000013
1964 ||
event[i].idAbs() == 2000013
1965 ||
event[i].idAbs() == 1000015
1966 ||
event[i].idAbs() == 2000015) )
1970 int nFinalBosons = 0;
1971 for(
int i=0; i <
event.size(); ++i)
1972 if ( event[i].isFinal() && isInHard( i, event)
1973 && (
event[i].idAbs() == 22
1974 ||
event[i].idAbs() == 23
1975 ||
event[i].idAbs() == 24
1976 ||
event[i].idAbs() == 25 ) )
1980 int nFinal = nFinalPartons + nFinalLeptons
1981 + 2*(nFinalBosons - nHardOutBosons() );
1984 int nsteps = nFinal - nHardOutPartons() - nHardOutLeptons();
1986 nsteps = nFinalPartons + nFinalLeptons + nFinalBosons
1987 - (nHardOutPartons() + nHardOutLeptons() + nHardOutBosons());
1991 if ( getProcessString().find(
"inc") != string::npos ) {
1994 int njInc = 0, naInc = 0, nzInc = 0, nwInc =0, nhInc = 0;
1995 for (
int i=0; i <
event.size(); ++i){
1996 if ( event[i].isFinal() &&
event[i].colType() != 0 ) njInc++;
1997 if ( getProcessString().find(
"Ainc") != string::npos
1998 &&
event[i].isFinal() &&
event[i].idAbs() == 22 ) naInc++;
1999 if ( getProcessString().find(
"Zinc") != string::npos
2000 &&
event[i].isFinal() &&
event[i].idAbs() == 23 ) nzInc++;
2001 if ( getProcessString().find(
"Winc") != string::npos
2002 &&
event[i].isFinal() &&
event[i].idAbs() == 24 ) nwInc++;
2003 if ( getProcessString().find(
"Hinc") != string::npos
2004 &&
event[i].isFinal() &&
event[i].idAbs() == 25 ) nhInc++;
2009 if (nzInc == 0 && nwInc == 0 && nhInc == 0 && njInc+naInc > 1) {
2010 nsteps = naInc + njInc - 2;
2012 hasJetMaxLocal =
true;
2013 nJetMaxLocal = nJetMaxSave - 2;
2014 nRequestedSave = nsteps;
2020 if ( nzInc > 0 || nwInc > 0 || nhInc > 0) {
2021 nsteps = njInc + naInc + nzInc + nwInc + nhInc - 1;
2023 hasJetMaxLocal =
true;
2024 nJetMaxLocal = nJetMaxSave - 1;
2025 nRequestedSave = nsteps;
2046 bool DireMergingHooks::setShowerStartingScales(
bool isTrial,
2047 bool doMergeFirstEmm,
double& pTscaleIn,
const Event& event,
2048 double& pTmaxFSRIn,
bool& limitPTmaxFSRIn,
2049 double& pTmaxISRIn,
bool& limitPTmaxISRIn,
2050 double& pTmaxMPIIn,
bool& limitPTmaxMPIIn ) {
2053 bool limitPTmaxFSR = limitPTmaxFSRIn;
2054 bool limitPTmaxISR = limitPTmaxISRIn;
2055 bool limitPTmaxMPI = limitPTmaxMPIIn;
2056 double pTmaxFSR = pTmaxFSRIn;
2057 double pTmaxISR = pTmaxISRIn;
2058 double pTmaxMPI = pTmaxMPIIn;
2059 double pTscale = pTscaleIn;
2067 bool isInclusive = ( getProcessString().find(
"inc") != string::npos );
2075 int nFinalPartons = 0, nInitialPartons = 0, nFinalOther = 0;
2076 for (
int i = 0; i <
event.size(); ++i ) {
2077 if ( (event[i].mother1() == 1 || event[i].mother1() == 2 )
2078 && (
event[i].idAbs() < 6 ||
event[i].id() == 21) )
2080 if (event[i].isFinal() && (
event[i].idAbs() < 6 ||
event[i].id() == 21)) {
2082 pT2to2 =
event[i].pT();
2083 }
else if ( event[i].isFinal() ) nFinalOther++;
2085 bool is2to2QCD = ( nFinalPartons == 2 && nInitialPartons == 2
2086 && nFinalOther == 0 );
2087 bool hasMPIoverlap = is2to2QCD;
2088 bool is2to1 = ( nFinalPartons == 0 );
2090 double scale =
event.scale();
2096 pTmaxISR = pTmaxFSR = pTmaxMPI = scale;
2100 if ( limitPTmaxISR && !isInclusive ) pTmaxISR = min(scale,muF());
2101 if ( limitPTmaxFSR && !isInclusive ) pTmaxFSR = min(scale,muF());
2102 if ( limitPTmaxMPI && !isInclusive ) pTmaxMPI = min(scale,muF());
2105 if ( limitPTmaxISR && isInclusive && is2to1 ) pTmaxISR = min(scale,muF());
2106 if ( limitPTmaxFSR && isInclusive && is2to1 ) pTmaxFSR = min(scale,muF());
2107 if ( limitPTmaxMPI && isInclusive && is2to1 ) pTmaxMPI = min(scale,muF());
2116 if ( hasMPIoverlap ) pTmaxMPI = infoPtr->eCM();
2119 if ( pTscale < infoPtr->eCM() ) {
2120 limitPTmaxISR = limitPTmaxFSR = limitPTmaxMPI =
true;
2122 if ( hasMPIoverlap ) limitPTmaxMPI =
false;
2128 if ( doMergeFirstEmm ) {
2131 bool doRecluster = doUMEPSSubt() || doNL3Subt() || doUNLOPSSubt()
2132 || doUNLOPSSubtNLO();
2135 pTmaxISR = pTmaxFSR = pTmaxMPI = scale;
2139 if ( limitPTmaxISR && !isInclusive ) pTmaxISR = min(scale,muF());
2140 if ( limitPTmaxFSR && !isInclusive ) pTmaxFSR = min(scale,muF());
2141 if ( limitPTmaxMPI && !isInclusive ) pTmaxMPI = min(scale,muF());
2144 if ( limitPTmaxISR && isInclusive && is2to1 ) pTmaxISR = min(scale,muF());
2145 if ( limitPTmaxFSR && isInclusive && is2to1 ) pTmaxFSR = min(scale,muF());
2146 if ( limitPTmaxMPI && isInclusive && is2to1 ) pTmaxMPI = min(scale,muF());
2155 if ( hasMPIoverlap && !doRecluster ) {
2156 pTmaxMPI = infoPtr->eCM();
2157 limitPTmaxMPI =
false;
2162 if ( doRecluster ) {
2164 limitPTmaxMPI =
true;
2169 limitPTmaxFSRIn = limitPTmaxFSR;
2170 limitPTmaxISRIn = limitPTmaxISR;
2171 limitPTmaxMPIIn = limitPTmaxMPI;
2172 pTmaxFSRIn = pTmaxFSR;
2173 pTmaxISRIn = pTmaxISR;
2174 pTmaxMPIIn = pTmaxMPI;
2175 pTscaleIn = pTscale;
2187 double DireMergingHooks::tmsNow(
const Event& event ) {
2192 tnow = scalems(event);
2202 bool DireMergingHooks::checkAgainstCut(
const Particle& particle){
2205 if (particle.colType() == 0)
return false;
2207 if ( particle.idAbs() != 21 && particle.idAbs() > nQuarksMergeSave )
2220 double DireMergingHooks::scalems(
const Event& event){
2223 if (!isFirstEmission(event))
return 0.;
2226 vector<int> ewResonancePos;
2227 ewResonancePos.clear();
2228 for (
int i=0; i <
event.size(); ++i)
2229 if ( abs(event[i].status()) == 22
2230 && (
event[i].idAbs() == 22
2231 ||
event[i].idAbs() == 23
2232 ||
event[i].idAbs() == 24
2233 ||
event[i].idAbs() == 25
2234 ||
event[i].idAbs() == 6 ) )
2235 ewResonancePos.push_back(i);
2238 vector <int> FinalPartPos;
2239 FinalPartPos.clear();
2242 for (
int i=0; i <
event.size(); ++i){
2244 if ( event[i].isFinal()
2245 && isInHard( i, event )
2246 &&
event[i].colType() != 0
2247 && checkAgainstCut(event[i]) ){
2248 bool isDecayProduct =
false;
2249 for(
int j=0; j < int(ewResonancePos.size()); ++j)
2250 if ( event[i].isAncestor( ewResonancePos[j]) )
2251 isDecayProduct =
true;
2253 if ( !isDecayProduct
2254 || getProcessString().compare(
"e+e->jj") == 0
2255 || getProcessString().compare(
"e+e->(z>jj)") == 0 )
2256 FinalPartPos.push_back(i);
2260 if ( getProcessString().find(
"Ainc") != string::npos
2261 && event[i].isFinal() && event[i].idAbs() == 22 )
2262 FinalPartPos.push_back(i);
2264 if ( getProcessString().find(
"Zinc") != string::npos
2265 && event[i].isFinal() && event[i].idAbs() == 23 )
2266 FinalPartPos.push_back(i);
2268 if ( getProcessString().find(
"Winc") != string::npos
2269 && event[i].isFinal() && event[i].idAbs() == 24 )
2270 FinalPartPos.push_back(i);
2275 for (
int i=0; i <
event.size(); ++i)
2276 if (abs(event[i].status()) == 41 ){
2283 for (
int i=0; i <
event.size(); ++i)
2284 if (abs(event[i].status()) == 42 ){
2290 if (in1 == 0 || in2 == 0){
2292 for(
int i=3; i < int(event.size()); ++i){
2293 if ( !isInHard( i, event ) )
continue;
2294 if (event[i].mother1() == 1) in1 = i;
2295 if (event[i].mother1() == 2) in2 = i;
2299 int nInitialPartons(0), nFinalOther(0);
2300 for (
int i = 0; i <
event.size(); ++i ) {
2301 if ( (event[i].mother1() == 1 || event[i].mother1() == 2 )
2302 && (
event[i].idAbs() < 6 ||
event[i].id() == 21) )
2304 if (event[i].isFinal() &&
event[i].idAbs() >= 6 &&
event[i].id() != 21)
2307 bool is2to2QCD = ( int(FinalPartPos.size()) == 2 && nInitialPartons == 2
2308 && nFinalOther == 0 );
2312 double pt12 = min(event[FinalPartPos[0]].pT(),
2313 event[FinalPartPos[1]].pT());
2319 for(
int i=0; i < int(FinalPartPos.size()); ++i)
2320 if ( event[FinalPartPos[i]].idAbs() <= 5
2321 ||
event[FinalPartPos[i]].idAbs() == 21
2322 ||
event[FinalPartPos[i]].idAbs() == 22) nLight++;
2323 if (nLight == 0)
return 0.;
2327 double ptmin =
event[0].e();
2328 for(
int i=0; i < int(FinalPartPos.size()); ++i){
2330 double pt12 = ptmin;
2333 if (event[in1].colType() != 0) {
2334 double temp = rhoPythia( event, in1, FinalPartPos[i], in2, 0);
2335 pt12 = min(pt12, temp);
2339 if ( event[in2].colType() != 0) {
2340 double temp = rhoPythia( event, in2, FinalPartPos[i], in1, 0);
2341 pt12 = min(pt12, temp);
2345 if ( event[in1].colType() != 0 ) {
2346 for(
int j=0; j < int(FinalPartPos.size()); ++j) {
2350 double temp = rhoPythia(event,in1,FinalPartPos[i],FinalPartPos[j],0);
2351 pt12 = min(pt12, temp);
2357 if ( event[in2].colType() != 0 ) {
2358 for(
int j=0; j < int(FinalPartPos.size()); ++j) {
2362 double temp = rhoPythia(event,in2,FinalPartPos[i],FinalPartPos[j],0);
2363 pt12 = min(pt12, temp);
2369 for(
int j=0; j < int(FinalPartPos.size()); ++j) {
2370 for(
int k=0; k < int(FinalPartPos.size()); ++k) {
2372 if ( (i != j) && (i != k) && (j != k) ){
2373 double temp = rhoPythia( event, FinalPartPos[i], FinalPartPos[j],
2374 FinalPartPos[k], 0);
2375 pt12 = min(pt12, temp);
2376 temp = rhoPythia( event, FinalPartPos[j], FinalPartPos[i],
2377 FinalPartPos[k], 0);
2378 pt12 = min(pt12, temp);
2385 if ( event[in1].colType() != 0 ) {
2386 for(
int j=0; j < int(FinalPartPos.size()); ++j) {
2390 double temp = rhoPythia( event, FinalPartPos[i],FinalPartPos[j],
2392 pt12 = min(pt12, temp);
2399 if ( event[in2].colType() != 0) {
2400 for(
int j=0; j < int(FinalPartPos.size()); ++j) {
2404 double temp = rhoPythia( event, FinalPartPos[i],FinalPartPos[j],
2406 pt12 = min(pt12, temp);
2412 ptmin = min(ptmin,pt12);
2424 double DireMergingHooks::rhoPythia(
const Event& event,
int rad,
int emt,
2429 map<string,double> stateVars;
2430 double ptret =
event[0].m();
2431 bool isFSR = showers->timesPtr->isTimelike(event, rad, emt, rec,
"");
2433 vector<string> name = showers->timesPtr->getSplittingName
2434 (event, rad, emt, rec);
2435 for (
int i=0; i < int(name.size()); ++i) {
2436 stateVars = showers->timesPtr->getStateVariables
2437 (event, rad, emt, rec, name[i]);
2438 double pttemp = ptret;
2439 if (stateVars.size() > 0 && stateVars.find(
"t") != stateVars.end())
2440 pttemp = sqrt(stateVars[
"t"]);
2441 ptret = min(ptret,pttemp);
2444 vector<string> name = showers->spacePtr->getSplittingName
2445 (event, rad, emt, rec);
2446 for (
int i=0; i < int(name.size()); ++i) {
2447 stateVars = showers->spacePtr->getStateVariables
2448 (event, rad, emt, rec, name[i]);
2449 double pttemp = ptret;
2450 if (stateVars.size() > 0 && stateVars.find(
"t") != stateVars.end())
2451 pttemp = sqrt(stateVars[
"t"]);
2452 ptret = min(ptret,pttemp);
2477 int DireMergingHooks::findColour(
int col,
int iExclude1,
int iExclude2,
2478 const Event& event,
int type,
bool isHardIn){
2480 bool isHard = isHardIn;
2485 for(
int n = 0; n <
event.size(); ++n) {
2486 if ( n != iExclude1 && n != iExclude2
2487 && event[n].colType() != 0
2488 &&(
event[n].status() > 0
2489 ||
event[n].status() == -21) ) {
2490 if ( event[n].acol() == col ) {
2494 if ( event[n].col() == col ){
2503 for(
int n = 0; n <
event.size(); ++n) {
2504 if ( n != iExclude1 && n != iExclude2
2505 && event[n].colType() != 0
2506 &&(
event[n].status() == 43
2507 ||
event[n].status() == 51
2508 ||
event[n].status() == 52
2509 ||
event[n].status() == -41
2510 ||
event[n].status() == -42) ) {
2511 if ( event[n].acol() == col ) {
2515 if ( event[n].col() == col ){
2523 if ( type == 1 && index < 0)
return abs(index);
2524 if ( type == 2 && index > 0)
return abs(index);