8 #include "ProcessLevel.h"
22 const int ProcessLevel::MAXLOOP = 5;
28 ProcessLevel::~ProcessLevel() {
31 for (
int i = 0; i < int(containerPtrs.size()); ++i)
32 delete containerPtrs[i];
35 for (
int i =0; i < int(container2Ptrs.size()); ++i)
36 delete container2Ptrs[i];
44 bool ProcessLevel::init( Info* infoPtrIn, Settings& settings,
45 ParticleData* particleDataPtrIn, Rndm* rndmPtrIn,
46 BeamParticle* beamAPtrIn, BeamParticle* beamBPtrIn,
47 Couplings* couplingsPtrIn, SigmaTotal* sigmaTotPtrIn,
bool doLHA,
48 SusyLesHouches* slhaPtrIn, UserHooks* userHooksPtrIn,
49 vector<SigmaProcess*>& sigmaPtrs, ostream& os) {
53 particleDataPtr = particleDataPtrIn;
55 beamAPtr = beamAPtrIn;
56 beamBPtr = beamBPtrIn;
57 couplingsPtr = couplingsPtrIn;
58 sigmaTotPtr = sigmaTotPtrIn;
59 userHooksPtr = userHooksPtrIn;
63 resonanceDecays.init( infoPtr, particleDataPtr, rndmPtr);
66 sigmaTotPtr->init( infoPtr, settings, particleDataPtr);
67 int idA = infoPtr->idA();
68 int idB = infoPtr->idB();
69 double eCM = infoPtr->eCM();
70 sigmaTotPtr->calc( idA, idB, eCM);
71 sigmaND = sigmaTotPtr->sigmaND();
74 doSecondHard = settings.flag(
"SecondHard:generate");
75 doSameCuts = settings.flag(
"PhaseSpace:sameForSecond");
76 doResDecays = settings.flag(
"ProcessLevel:resonanceDecays");
77 startColTag = settings.mode(
"Event:startColTag");
80 if (doSecondHard && userHooksPtr != 0
81 && userHooksPtr->canBiasSelection()) {
82 infoPtr->errorMsg(
"Error in ProcessLevel::init: "
83 "cannot combine second interaction with biased phase space");
88 mHatMin1 = settings.parm(
"PhaseSpace:mHatMin");
89 mHatMax1 = settings.parm(
"PhaseSpace:mHatMax");
90 if (mHatMax1 < mHatMin1) mHatMax1 = eCM;
91 pTHatMin1 = settings.parm(
"PhaseSpace:pTHatMin");
92 pTHatMax1 = settings.parm(
"PhaseSpace:pTHatMax");
93 if (pTHatMax1 < pTHatMin1) pTHatMax1 = eCM;
94 mHatMin2 = settings.parm(
"PhaseSpace:mHatMinSecond");
95 mHatMax2 = settings.parm(
"PhaseSpace:mHatMaxSecond");
96 if (mHatMax2 < mHatMin2) mHatMax2 = eCM;
97 pTHatMin2 = settings.parm(
"PhaseSpace:pTHatMinSecond");
98 pTHatMax2 = settings.parm(
"PhaseSpace:pTHatMaxSecond");
99 if (pTHatMax2 < pTHatMin2) pTHatMax2 = eCM;
102 cutsAgree = doSameCuts;
103 if (mHatMin2 == mHatMin1 && mHatMax2 == mHatMax1 && pTHatMin2 == pTHatMin1
104 && pTHatMax2 == pTHatMax1) cutsAgree =
true;
105 cutsOverlap = cutsAgree;
107 bool mHatOverlap = (max( mHatMin1, mHatMin2)
108 < min( mHatMax1, mHatMax2));
109 bool pTHatOverlap = (max( pTHatMin1, pTHatMin2)
110 < min( pTHatMax1, pTHatMax2));
111 if (mHatOverlap && pTHatOverlap) cutsOverlap =
true;
115 SetupContainers setupContainers;
116 setupContainers.init(containerPtrs, settings, particleDataPtr, couplingsPtr);
119 if (sigmaPtrs.size() > 0) {
120 for (
int iSig = 0; iSig < int(sigmaPtrs.size()); ++iSig)
121 containerPtrs.push_back(
new ProcessContainer(sigmaPtrs[iSig],
127 SigmaProcess* sigmaPtr =
new SigmaLHAProcess();
128 containerPtrs.push_back(
new ProcessContainer(sigmaPtr) );
131 iLHACont = containerPtrs.size() - 1;
132 containerPtrs[iLHACont]->setLHAPtr(lhaUpPtr);
136 if (
int(containerPtrs.size()) == 0) {
137 infoPtr->errorMsg(
"Error in ProcessLevel::init: "
138 "no process switched on");
143 bool hasSUSY =
false;
144 for (
int i = 0; i < int(containerPtrs.size()); ++i)
145 if (containerPtrs[i]->isSUSY()) hasSUSY =
true;
148 if(hasSUSY && !couplingsPtr->isSUSY) {
149 infoPtr->errorMsg(
"Error in ProcessLevel::init: "
150 "SUSY process switched on but no SUSY couplings found");
159 for (
int i = 0; i < int(containerPtrs.size()); ++i)
160 if (containerPtrs[i]->init(
true, infoPtr, settings, particleDataPtr,
161 rndmPtr, beamAPtr, beamBPtr, couplingsPtr, sigmaTotPtr,
162 &resonanceDecays, slhaPtr, userHooksPtr)) ++numberOn;
166 for (
int i = 0; i < int(containerPtrs.size()); ++i)
167 sigmaMaxSum += containerPtrs[i]->sigmaMax();
172 setupContainers.init2(container2Ptrs, settings);
173 if (
int(container2Ptrs.size()) == 0) {
174 infoPtr->errorMsg(
"Error in ProcessLevel::init: "
175 "no second hard process switched on");
178 for (
int i2 = 0; i2 < int(container2Ptrs.size()); ++i2)
179 if (container2Ptrs[i2]->init(
false, infoPtr, settings, particleDataPtr,
180 rndmPtr, beamAPtr, beamBPtr, couplingsPtr, sigmaTotPtr,
181 &resonanceDecays, slhaPtr, userHooksPtr)) ++number2On;
183 for (
int i2 = 0; i2 < int(container2Ptrs.size()); ++i2)
184 sigma2MaxSum += container2Ptrs[i2]->sigmaMax();
188 if (settings.flag(
"Init:showProcesses")) {
191 string collision =
"We collide " + particleDataPtr->name(idA)
192 +
" with " + particleDataPtr->name(idB) +
" at a CM energy of ";
193 string pad( 51 - collision.length(),
' ');
196 os <<
"\n *------- PYTHIA Process Initialization ---------"
197 <<
"-----------------*\n"
200 <<
" | " << collision << scientific << setprecision(3)
201 << setw(9) << eCM <<
" GeV" << pad <<
" |\n"
204 <<
" |---------------------------------------------------"
205 <<
"---------------|\n"
208 <<
" | Subprocess Code"
209 <<
" | Estimated |\n"
214 <<
" |---------------------------------------------------"
215 <<
"---------------|\n"
221 for (
int i = 0; i < int(containerPtrs.size()); ++i)
222 os <<
" | " << left << setw(45) << containerPtrs[i]->name()
223 << right << setw(5) << containerPtrs[i]->code() <<
" | "
224 << scientific << setprecision(3) << setw(11)
225 << containerPtrs[i]->sigmaMax() <<
" |\n";
231 <<
" |---------------------------------------------------"
232 <<
"---------------|\n"
235 for (
int i2 = 0; i2 < int(container2Ptrs.size()); ++i2)
236 os <<
" | " << left << setw(45) << container2Ptrs[i2]->name()
237 << right << setw(5) << container2Ptrs[i2]->code() <<
" | "
238 << scientific << setprecision(3) << setw(11)
239 << container2Ptrs[i2]->sigmaMax() <<
" |\n";
245 <<
" *------- End PYTHIA Process Initialization ----------"
246 <<
"-------------*" << endl;
250 if ( numberOn == 0 || sigmaMaxSum <= 0.) {
251 infoPtr->errorMsg(
"Error in ProcessLevel::init: "
252 "all processes have vanishing cross sections");
255 if ( doSecondHard && (number2On == 0 || sigma2MaxSum <= 0.) ) {
256 infoPtr->errorMsg(
"Error in ProcessLevel::init: "
257 "all second hard processes have vanishing cross sections");
265 bool foundMatch =
false;
268 for (
int i = 0; i < int(containerPtrs.size()); ++i) {
271 for (
int i2 = 0; i2 < int(container2Ptrs.size()); ++i2)
272 if (container2Ptrs[i2]->code() == containerPtrs[i]->code())
274 containerPtrs[i]->isSame( foundMatch );
275 if (!foundMatch) allHardSame =
false;
276 if ( foundMatch) noneHardSame =
false;
280 for (
int i2 = 0; i2 < int(container2Ptrs.size()); ++i2) {
283 for (
int i = 0; i < int(containerPtrs.size()); ++i)
284 if (containerPtrs[i]->code() == container2Ptrs[i2]->code())
286 container2Ptrs[i2]->isSame( foundMatch );
287 if (!foundMatch) allHardSame =
false;
288 if ( foundMatch) noneHardSame =
false;
293 if (!cutsAgree) allHardSame =
false;
294 someHardSame = !allHardSame && !noneHardSame;
313 bool ProcessLevel::next(
Event& process) {
316 bool physical = (doSecondHard) ? nextTwo( process) : nextOne( process);
319 if (physical) physical = checkColours( process);
329 void ProcessLevel::accumulate() {
332 containerPtrs[iContainer]->accumulate();
338 double sigmaSum = 0.;
339 double delta2Sum = 0.;
340 double sigSelSum = 0.;
341 double weightSum = 0.;
342 for (
int i = 0; i < int(containerPtrs.size()); ++i)
343 if (containerPtrs[i]->sigmaMax() != 0.) {
344 nTrySum += containerPtrs[i]->nTried();
345 nSelSum += containerPtrs[i]->nSelected();
346 nAccSum += containerPtrs[i]->nAccepted();
347 sigmaSum += containerPtrs[i]->sigmaMC();
348 delta2Sum += pow2(containerPtrs[i]->deltaMC());
349 sigSelSum += containerPtrs[i]->sigmaSelMC();
350 weightSum += containerPtrs[i]->weightSum();
354 if (infoPtr->isLHA()) {
355 int codeLHANow = infoPtr->codeSub();
357 for (
int i = 0; i < int(codeLHA.size()); ++i)
358 if (codeLHANow == codeLHA[i]) iFill = i;
359 if (iFill >= 0) ++nEvtLHA[iFill];
363 codeLHA.push_back(codeLHANow);
364 nEvtLHA.push_back(1);
365 for (
int i =
int(codeLHA.size()) - 1; i > 0; --i) {
366 if (codeLHA[i] < codeLHA[i - 1]) {
367 swap(codeLHA[i], codeLHA[i - 1]);
368 swap(nEvtLHA[i], nEvtLHA[i - 1]);
377 double deltaSum = sqrtpos(delta2Sum);
378 infoPtr->setSigma( nTrySum, nSelSum, nAccSum, sigmaSum, deltaSum,
384 container2Ptrs[i2Container]->accumulate();
388 sumImpactFac += infoPtr->enhanceMPI();
389 sum2ImpactFac += pow2(infoPtr->enhanceMPI());
392 double sigma2Sum = 0.;
393 double sig2SelSum = 0.;
394 for (
int i2 = 0; i2 < int(container2Ptrs.size()); ++i2)
395 if (container2Ptrs[i2]->sigmaMax() != 0.) {
396 nTrySum += container2Ptrs[i2]->nTried();
397 sigma2Sum += container2Ptrs[i2]->sigmaMC();
398 sig2SelSum += container2Ptrs[i2]->sigmaSelMC();
402 double invN = 1. / max(1, nImpact);
403 double impactFac = max( 1., sumImpactFac * invN);
404 double impactErr2 = ( sum2ImpactFac * invN / pow2(impactFac) - 1.) * invN;
408 double sigmaComb = 0.5 * (sigmaSum * sig2SelSum + sigSelSum * sigma2Sum);
409 sigmaComb *= impactFac / sigmaND;
410 if (allHardSame) sigmaComb *= 0.5;
411 double deltaComb = sqrtpos(2. / nAccSum + impactErr2) * sigmaComb;
414 infoPtr->setSigma( nTrySum, nSelSum, nAccSum, sigmaComb, deltaComb,
423 void ProcessLevel::statistics(
bool reset, ostream& os) {
427 statistics2(reset, os);
432 os <<
"\n *------- PYTHIA Event and Cross Section Statistics ------"
433 <<
"-------------------------------------------------------*\n"
436 <<
" | Subprocess Code | "
437 <<
" Number of events | sigma +- delta |\n"
439 <<
"Tried Selected Accepted | (estimated) (mb) |\n"
442 <<
" |------------------------------------------------------------"
443 <<
"-----------------------------------------------------|\n"
451 double sigmaSum = 0.;
452 double delta2Sum = 0.;
455 for (
int i = 0; i < int(containerPtrs.size()); ++i)
456 if (containerPtrs[i]->sigmaMax() != 0.) {
459 long nTry = containerPtrs[i]->nTried();
460 long nSel = containerPtrs[i]->nSelected();
461 long nAcc = containerPtrs[i]->nAccepted();
462 double sigma = containerPtrs[i]->sigmaMC();
463 double delta = containerPtrs[i]->deltaMC();
468 delta2Sum += pow2(delta);
471 os <<
" | " << left << setw(45) << containerPtrs[i]->name()
472 << right << setw(5) << containerPtrs[i]->code() <<
" | "
473 << setw(11) << nTry <<
" " << setw(10) << nSel <<
" "
474 << setw(10) << nAcc <<
" | " << scientific << setprecision(3)
475 << setw(11) << sigma << setw(11) << delta <<
" |\n";
478 if (containerPtrs[i]->code() == 9999)
479 for (
int j = 0; j < int(codeLHA.size()); ++j)
480 os <<
" | ... whereof user classification code " << setw(10)
481 << codeLHA[j] <<
" | " << setw(10)
482 << nEvtLHA[j] <<
" | | \n";
488 <<
" | " << left << setw(50) <<
"sum" << right <<
" | " << setw(11)
489 << nTrySum <<
" " << setw(10) << nSelSum <<
" " << setw(10)
490 << nAccSum <<
" | " << scientific << setprecision(3) << setw(11)
491 << sigmaSum << setw(11) << sqrtpos(delta2Sum) <<
" |\n";
496 <<
" *------- End PYTHIA Event and Cross Section Statistics -----"
497 <<
"-----------------------------------------------------*" << endl;
500 if (reset) resetStatistics();
508 void ProcessLevel::resetStatistics() {
510 for (
int i = 0; i < int(containerPtrs.size()); ++i)
511 containerPtrs[i]->reset();
513 for (
int i2 = 0; i2 < int(container2Ptrs.size()); ++i2)
514 container2Ptrs[i2]->reset();
522 void ProcessLevel::initSLHA() {
525 string blockName =
"sminputs";
526 double mZ = particleDataPtr->m0(23);
527 slhaPtr->set(blockName,1,1.0/couplingsPtr->alphaEM(pow2(mZ)));
528 slhaPtr->set(blockName,2,couplingsPtr->GF());
529 slhaPtr->set(blockName,3,couplingsPtr->alphaS(pow2(mZ)));
530 slhaPtr->set(blockName,4,mZ);
532 slhaPtr->set(blockName,5,particleDataPtr->m0(5));
533 slhaPtr->set(blockName,6,particleDataPtr->m0(6));
534 slhaPtr->set(blockName,7,particleDataPtr->m0(15));
535 slhaPtr->set(blockName,8,particleDataPtr->m0(16));
536 slhaPtr->set(blockName,11,particleDataPtr->m0(11));
537 slhaPtr->set(blockName,12,particleDataPtr->m0(12));
538 slhaPtr->set(blockName,13,particleDataPtr->m0(13));
539 slhaPtr->set(blockName,14,particleDataPtr->m0(14));
541 slhaPtr->set(blockName,21,
double(0.0));
542 slhaPtr->set(blockName,22,
double(0.0));
543 slhaPtr->set(blockName,23,
double(0.0));
545 slhaPtr->set(blockName,24,particleDataPtr->m0(4));
551 while (particleDataPtr->nextId(
id) > id) {
552 slhaPtr->set(blockName,
id,particleDataPtr->m0(
id));
553 id = particleDataPtr->nextId(
id);
556 infoPtr->errorMsg(
"Error in ProcessLevel::initSLHA: "
557 "encountered infinite loop when saving mass block");
568 bool ProcessLevel::nextOne(
Event& process) {
571 double eCM = infoPtr->eCM();
572 for (
int i = 0; i < int(containerPtrs.size()); ++i)
573 containerPtrs[i]->newECM(eCM);
576 bool physical =
true;
577 for (
int loop = 0; loop < MAXLOOP; ++loop) {
578 if (!physical) process.clear();
585 double sigmaMaxNow = sigmaMaxSum * rndmPtr->flat();
586 int iMax = containerPtrs.size() - 1;
588 do sigmaMaxNow -= containerPtrs[++iContainer]->sigmaMax();
589 while (sigmaMaxNow > 0. && iContainer < iMax);
592 if (containerPtrs[iContainer]->trialProcess())
break;
595 if (infoPtr->atEndOfFile())
return false;
599 if (containerPtrs[iContainer]->newSigmaMax()) {
601 for (
int i = 0; i < int(containerPtrs.size()); ++i)
602 sigmaMaxSum += containerPtrs[i]->sigmaMax();
606 if ( !containerPtrs[iContainer]->constructProcess( process) )
610 if ( physical && doResDecays
611 && !containerPtrs[iContainer]->decayResonances( process) )
615 if (physical) findJunctions( process);
629 bool ProcessLevel::nextTwo(
Event& process) {
632 double eCM = infoPtr->eCM();
633 for (
int i = 0; i < int(containerPtrs.size()); ++i)
634 containerPtrs[i]->newECM(eCM);
635 for (
int i2 = 0; i2 < int(container2Ptrs.size()); ++i2)
636 container2Ptrs[i2]->newECM(eCM);
639 bool physical =
true;
640 for (
int loop = 0; loop < MAXLOOP; ++loop) {
641 if (!physical) process.clear();
651 double sigmaMaxNow = sigmaMaxSum * rndmPtr->flat();
652 int iMax = containerPtrs.size() - 1;
654 do sigmaMaxNow -= containerPtrs[++iContainer]->sigmaMax();
655 while (sigmaMaxNow > 0. && iContainer < iMax);
658 if (containerPtrs[iContainer]->trialProcess())
break;
661 if (infoPtr->atEndOfFile())
return false;
665 if (containerPtrs[iContainer]->newSigmaMax()) {
667 for (
int i = 0; i < int(containerPtrs.size()); ++i)
668 sigmaMaxSum += containerPtrs[i]->sigmaMax();
675 double sigma2MaxNow = sigma2MaxSum * rndmPtr->flat();
676 int i2Max = container2Ptrs.size() - 1;
678 do sigma2MaxNow -= container2Ptrs[++i2Container]->sigmaMax();
679 while (sigma2MaxNow > 0. && i2Container < i2Max);
682 if (container2Ptrs[i2Container]->trialProcess())
break;
686 if (container2Ptrs[i2Container]->newSigmaMax()) {
688 for (
int i2 = 0; i2 < int(container2Ptrs.size()); ++i2)
689 sigma2MaxSum += container2Ptrs[i2]->sigmaMax();
693 double xA1 = containerPtrs[iContainer]->x1();
694 double xB1 = containerPtrs[iContainer]->x2();
695 double xA2 = container2Ptrs[i2Container]->x1();
696 double xB2 = container2Ptrs[i2Container]->x2();
697 if (xA1 + xA2 >= 1. || xB1 + xB2 >= 1.)
continue;
703 int idA1 = containerPtrs[iContainer]->id1();
704 int idB1 = containerPtrs[iContainer]->id2();
705 int idA2 = container2Ptrs[i2Container]->id1();
706 int idB2 = container2Ptrs[i2Container]->id2();
707 double Q2Fac1 = containerPtrs[iContainer]->Q2Fac();
708 double Q2Fac2 = container2Ptrs[i2Container]->Q2Fac();
709 double pdfA2Raw = beamAPtr->xf( idA2, xA2,Q2Fac2);
710 double pdfB2Raw = beamBPtr->xf( idB2, xB2,Q2Fac2);
713 beamAPtr->append( 3, idA1, xA1);
714 beamAPtr->xfISR( 0, idA1, xA1, Q2Fac1);
715 beamAPtr->pickValSeaComp();
716 beamBPtr->append( 4, idB1, xB1);
717 beamBPtr->xfISR( 0, idB1, xB1, Q2Fac1);
718 beamBPtr->pickValSeaComp();
721 double pdfA2Mod = beamAPtr->xfMPI( idA2, xA2,Q2Fac2);
722 double pdfB2Mod = beamBPtr->xfMPI( idB2, xB2,Q2Fac2);
723 double wtPdfMod = (pdfA2Mod * pdfB2Mod) / (pdfA2Raw * pdfB2Raw);
724 if (wtPdfMod < rndmPtr->flat())
continue;
729 if ( someHardSame && containerPtrs[iContainer]->isSame()
730 && container2Ptrs[i2Container]->isSame()) {
732 if (rndmPtr->flat() > 0.5) toLoop =
true;
734 double mHat1 = containerPtrs[iContainer]->mHat();
735 double pTHat1 = containerPtrs[iContainer]->pTHat();
736 double mHat2 = container2Ptrs[i2Container]->mHat();
737 double pTHat2 = container2Ptrs[i2Container]->pTHat();
738 if (mHat1 > mHatMin2 && mHat1 < mHatMax2
739 && pTHat1 > pTHatMin2 && pTHat1 < pTHatMax2
740 && mHat2 > mHatMin1 && mHat2 < mHatMax1
741 && pTHat2 > pTHatMin1 && pTHat2 < pTHatMax1
742 && rndmPtr->flat() > 0.5) toLoop =
true;
745 if (toLoop)
continue;
753 process2.init(
"(second hard)", particleDataPtr, startColTag);
754 process2.initColTag();
755 if ( !containerPtrs[iContainer]->constructProcess( process) )
757 if (physical && !container2Ptrs[i2Container]->constructProcess( process2,
758 false) ) physical =
false;
761 if ( physical && doResDecays
762 && !containerPtrs[iContainer]->decayResonances( process) )
764 if ( physical && doResDecays
765 && !container2Ptrs[i2Container]->decayResonances( process2) )
769 if (physical) combineProcessRecords( process, process2);
772 if (physical) findJunctions( process);
787 void ProcessLevel::combineProcessRecords(
Event& process,
Event& process2) {
790 int nSize = process.size();
792 while (nHard < nSize && process[nHard].mother1() == 3) ++nHard;
795 vector<Particle> resProd;
797 for (
int i = nHard; i < nSize; ++i) resProd.push_back( process[i] );
798 process.popBack(nSize - nHard);
802 int nSize2 = process2.size();
804 while (nHard2 < nSize2 && process2[nHard2].mother1() == 3) ++nHard2;
807 int addPos = nHard - 3;
808 int addCol = process.lastColTag() - startColTag;
811 for (
int i = 3; i < nSize2; ++i) {
814 process2[i].offsetHistory( 2, addPos, 2, addPos);
815 process2[i].offsetCol( addCol);
818 if (i < nHard2) process.append( process2[i] );
822 int addPos2 = nHard2 - 3;
826 for (
int i = 5; i < nHard; ++i)
827 process[i].offsetHistory( 0, 0, nHard - 1, addPos2);
830 for (
int i = 0; i < int(resProd.size()); ++i) {
831 resProd[i].offsetHistory( nHard - 1, addPos2, nHard - 1, addPos2);
832 process.append( resProd[i] );
837 if (nHard2 < nSize2) {
838 int nHard3 = nHard + nHard2 - 3;
839 int addPos3 = nSize - nHard;
842 for (
int i = nHard + 2; i < nHard3; ++i)
843 process[i].offsetHistory( 0, 0, nHard3 - 1, addPos3);
846 for (
int i = nHard2; i < nSize2; ++i) {
847 process2[i].offsetHistory( nHard3 - 1, addPos3, nHard3 - 1, addPos3);
848 process.append( process2[i] );
853 process.scaleSecond( process2.scale() );
862 void ProcessLevel::findJunctions(
Event& junEvent) {
865 for (
int i = 1; i<junEvent.size(); i++) {
869 if (abs(junEvent[i].status()) <= 21 || junEvent[i].colType() == 0)
continue;
870 vector<int> motherList = junEvent.motherList(i);
871 int iMot1 = motherList[0];
872 vector<int> sisterList = junEvent.daughterList(iMot1);
876 map<int,int> colVertex, acolVertex;
879 for (
unsigned int indx = 0; indx < motherList.size(); indx++) {
880 int iMot = motherList[indx];
881 if ( abs(junEvent[iMot].colType()) == 1 )
882 barSum -= junEvent[iMot].colType();
883 else if ( abs(junEvent[iMot].colType()) == 3)
884 barSum -= 2*junEvent[iMot].colType()/3;
885 int col = junEvent[iMot].acol();
886 int acol = junEvent[iMot].col();
890 if (acolVertex.find(col) == acolVertex.end() ) colVertex[col] = iMot;
891 else acolVertex.erase(col);
892 }
else if (col < 0) {
893 if (colVertex.find(-col) == colVertex.end() ) acolVertex[-col] = iMot;
894 else colVertex.erase(-col);
897 if (colVertex.find(acol) == colVertex.end()) acolVertex[acol] = iMot;
898 else colVertex.erase(acol);
899 }
else if (acol < 0) {
900 if (acolVertex.find(-acol) == acolVertex.end()) colVertex[-acol] = iMot;
901 else acolVertex.erase(-acol);
906 for (
unsigned int indx = 0; indx < sisterList.size(); indx++) {
907 int iDau = sisterList[indx];
908 if ( abs(junEvent[iDau].colType()) == 1 )
909 barSum += junEvent[iDau].colType();
910 else if ( abs(junEvent[iDau].colType()) == 3)
911 barSum += 2*junEvent[iDau].colType()/3;
912 int col = junEvent[iDau].col();
913 int acol = junEvent[iDau].acol();
917 if (acolVertex.find(col) == acolVertex.end() ) colVertex[col] = iDau;
918 else acolVertex.erase(col);
919 }
else if (col < 0) {
920 if (colVertex.find(-col) == colVertex.end() ) acolVertex[-col] = iDau;
921 else colVertex.erase(-col);
924 if (colVertex.find(acol) == colVertex.end()) acolVertex[acol] = iDau;
925 else colVertex.erase(acol);
926 }
else if (acol < 0) {
927 if (acolVertex.find(-acol) == acolVertex.end()) colVertex[-acol] = iDau;
928 else acolVertex.erase(-acol);
934 if (barSum == 0)
continue;
937 for (
int iJun = 0; iJun < junEvent.sizeJunction(); ++iJun) {
939 for (
int j = 0; j < 3; ++j) {
940 int colNow = junEvent.colJunction(iJun, j);
941 if (junEvent.kindJunction(iJun) % 2 == 1) colVertex.erase(colNow);
942 else acolVertex.erase(colNow);
947 if (colVertex.size() == 0 && acolVertex.size() == 0)
continue;
951 if (colVertex.size() == 3 && acolVertex.size() == 0) kindJun = 1;
952 else if (colVertex.size() == 0 && acolVertex.size() == 3) kindJun = 2;
954 infoPtr->errorMsg(
"Error in ProcessLevel::findJunctions: "
955 "N(unmatched (anti)colour tags) != 3");
960 map<int,int> colJun = (kindJun == 1) ? colVertex : acolVertex;
964 for (map<int,int>::iterator it = colJun.begin();
965 it != colJun.end(); it++) {
967 int iCol = it->second;
968 for (
unsigned int indx = 0; indx < motherList.size(); indx++) {
969 if (iCol == motherList[indx]) {
971 colVec.insert(colVec.begin(),col);
974 if (colVec.size() == 0 || colVec[0] != col) colVec.push_back(col);
978 junEvent.appendJunction( kindJun, colVec[0], colVec[1], colVec[2]);
987 bool ProcessLevel::checkColours(
Event& process) {
990 bool physical =
true;
992 int colType, col, acol, iPos, iNow, iNowA;
993 vector<int> colTags, colPos, acolPos;
996 for (
int i = 0; i < process.size(); ++i) {
997 colType = process[i].colType();
998 col = process[i].col();
999 acol = process[i].acol();
1000 if (colType == 0 && (col != 0 || acol != 0)) physical =
false;
1001 else if (colType == 1 && (col <= 0 || acol != 0)) physical =
false;
1002 else if (colType == -1 && (col != 0 || acol <= 0)) physical =
false;
1003 else if (colType == 2 && (col <= 0 || acol <= 0)) physical =
false;
1006 else if (colType == 3 && (col <= 0 || acol >= 0)) physical =
false;
1007 else if (colType == -3 && (col >= 0 || acol <= 0)) physical =
false;
1009 else if (colType < -1 || colType > 3) physical =
false;
1014 for (
int ic = 0; ic < int(colTags.size()) ; ++ic)
1015 if (col == colTags[ic]) match =
true;
1016 if (!match) colTags.push_back(col);
1017 }
else if (acol > 0) {
1019 for (
int ic = 0; ic < int(colTags.size()) ; ++ic)
1020 if (acol == colTags[ic]) match =
true;
1021 if (!match) colTags.push_back(acol);
1026 for (
int ic = 0; ic < int(colTags.size()) ; ++ic)
1027 if (-col == colTags[ic]) match =
true;
1028 if (!match) colTags.push_back(-col);
1029 }
else if (acol < 0) {
1031 for (
int ic = 0; ic < int(colTags.size()) ; ++ic)
1032 if (-acol == colTags[ic]) match =
true;
1033 if (!match) colTags.push_back(-acol);
1039 infoPtr->errorMsg(
"Error in ProcessLevel::checkColours: "
1040 "incorrect colour assignment");
1045 for (
int iJun = 0; iJun < process.sizeJunction(); ++iJun) {
1046 for (
int j = 0; j < 3; ++j) {
1047 int colJun = process.colJunction(iJun, j);
1048 for (
int ic = 0; ic < int(colTags.size()) ; ++ic)
1049 if (colJun == colTags[ic]) {
1050 colTags[ic] = colTags[colTags.size() - 1];
1058 for (
int ic = 0; ic < int(colTags.size()); ++ic) {
1062 for (
int i = 0; i < process.size(); ++i) {
1063 if (process[i].col() == col || process[i].acol() == -col)
1064 colPos.push_back(i);
1065 if (process[i].acol() == col || process[i].col() == -col)
1066 acolPos.push_back(i);
1070 while (colPos.size() > 1) {
1071 iPos = colPos.size() - 1;
1072 iNow = colPos[iPos];
1073 if ( process[iNow].mother1() == colPos[iPos - 1]
1074 && process[iNow].mother2() == 0) colPos.pop_back();
1077 while (acolPos.size() > 1) {
1078 iPos = acolPos.size() - 1;
1079 iNow = acolPos[iPos];
1080 if ( process[iNow].mother1() == acolPos[iPos - 1]
1081 && process[iNow].mother2() == 0) acolPos.pop_back();
1086 if (colPos.size() + acolPos.size() != 2) physical =
false;
1089 else if (colPos.size() == 2) {
1091 if ( process[iNow].mother1() != colPos[0]
1092 && process[iNow].mother2() != colPos[0] ) physical =
false;
1094 else if (acolPos.size() == 2) {
1096 if ( process[iNowA].mother1() != acolPos[0]
1097 && process[iNowA].mother2() != acolPos[0] ) physical =
false;
1104 if ( process[iNow].status() == -21 && process[iNowA].status() == -21 );
1105 else if ( (process[iNow].mother1() != process[iNowA].mother1())
1106 || (process[iNow].mother2() != process[iNowA].mother2()) )
1113 if (!physical) infoPtr->errorMsg(
"Error in ProcessLevel::checkColours: "
1114 "unphysical colour flow");
1123 void ProcessLevel::statistics2(
bool reset, ostream& os) {
1126 double invN = 1. / max(1, nImpact);
1127 double impactFac = max( 1., sumImpactFac * invN);
1128 double impactErr2 = ( sum2ImpactFac * invN / pow2(impactFac) - 1.) * invN;
1131 double sigma2SelSum = 0.;
1133 for (
int i2 = 0; i2 < int(container2Ptrs.size()); ++i2) {
1134 sigma2SelSum += container2Ptrs[i2]->sigmaSelMC();
1135 n2SelSum += container2Ptrs[i2]->nSelected();
1137 double factor1 = impactFac * sigma2SelSum / sigmaND;
1138 double rel1Err = sqrt(1. / max(1, n2SelSum) + impactErr2);
1139 if (allHardSame) factor1 *= 0.5;
1142 double sigma1SelSum = 0.;
1144 for (
int i = 0; i < int(containerPtrs.size()); ++i) {
1145 sigma1SelSum += containerPtrs[i]->sigmaSelMC();
1146 n1SelSum += containerPtrs[i]->nSelected();
1148 double factor2 = impactFac * sigma1SelSum / sigmaND;
1149 if (allHardSame) factor2 *= 0.5;
1150 double rel2Err = sqrt(1. / max(1, n1SelSum) + impactErr2);
1153 os <<
"\n *------- PYTHIA Event and Cross Section Statistics ------"
1154 <<
"--------------------------------------------------*\n"
1157 <<
" | Subprocess Code | "
1158 <<
"Number of events | sigma +- delta |\n"
1160 <<
" Selected Accepted | (estimated) (mb) |\n"
1163 <<
" |------------------------------------------------------------"
1164 <<
"------------------------------------------------|\n"
1167 <<
" | First hard process: | "
1176 double sigmaSum = 0.;
1177 double delta2Sum = 0.;
1180 for (
int i = 0; i < int(containerPtrs.size()); ++i)
1181 if (containerPtrs[i]->sigmaMax() != 0.) {
1184 long nTry = containerPtrs[i]->nTried();
1185 long nSel = containerPtrs[i]->nSelected();
1186 long nAcc = containerPtrs[i]->nAccepted();
1187 double sigma = containerPtrs[i]->sigmaMC() * factor1;
1188 double delta2 = pow2( containerPtrs[i]->deltaMC() * factor1 );
1193 delta2Sum += delta2;
1194 delta2 += pow2( sigma * rel1Err );
1197 os <<
" | " << left << setw(40) << containerPtrs[i]->name()
1198 << right << setw(5) << containerPtrs[i]->code() <<
" | "
1199 << setw(11) << nTry <<
" " << setw(10) << nSel <<
" "
1200 << setw(10) << nAcc <<
" | " << scientific << setprecision(3)
1201 << setw(11) << sigma << setw(11) << sqrtpos(delta2) <<
" |\n";
1205 delta2Sum += pow2( sigmaSum * rel1Err );
1208 <<
" | " << left << setw(45) <<
"sum" << right <<
" | " << setw(11)
1209 << nTrySum <<
" " << setw(10) << nSelSum <<
" " << setw(10)
1210 << nAccSum <<
" | " << scientific << setprecision(3) << setw(11)
1211 << sigmaSum << setw(11) << sqrtpos(delta2Sum) <<
" |\n";
1217 <<
" |------------------------------------------------------------"
1218 <<
"------------------------------------------------|\n"
1221 <<
" | Second hard process: | "
1234 for (
int i2 = 0; i2 < int(container2Ptrs.size()); ++i2)
1235 if (container2Ptrs[i2]->sigmaMax() != 0.) {
1238 long nTry = container2Ptrs[i2]->nTried();
1239 long nSel = container2Ptrs[i2]->nSelected();
1240 long nAcc = container2Ptrs[i2]->nAccepted();
1241 double sigma = container2Ptrs[i2]->sigmaMC() * factor2;
1242 double delta2 = pow2( container2Ptrs[i2]->deltaMC() * factor2 );
1247 delta2Sum += delta2;
1248 delta2 += pow2( sigma * rel2Err );
1251 os <<
" | " << left << setw(40) << container2Ptrs[i2]->name()
1252 << right << setw(5) << container2Ptrs[i2]->code() <<
" | "
1253 << setw(11) << nTry <<
" " << setw(10) << nSel <<
" "
1254 << setw(10) << nAcc <<
" | " << scientific << setprecision(3)
1255 << setw(11) << sigma << setw(11) << sqrtpos(delta2) <<
" |\n";
1259 delta2Sum += pow2( sigmaSum * rel2Err );
1262 <<
" | " << left << setw(45) <<
"sum" << right <<
" | " << setw(11)
1263 << nTrySum <<
" " << setw(10) << nSelSum <<
" " << setw(10)
1264 << nAccSum <<
" | " << scientific << setprecision(3) << setw(11)
1265 << sigmaSum << setw(11) << sqrtpos(delta2Sum) <<
" |\n";
1270 <<
" |------------------------------------------------------------"
1271 <<
"------------------------------------------------|\n"
1274 <<
" | Uncombined cross sections for the two event sets were "
1275 << setw(10) << sigma1SelSum <<
" and " << sigma2SelSum <<
" mb, "
1276 <<
"respectively, combined |\n"
1277 <<
" | using a sigma(nonDiffractive) of " << setw(10) << sigmaND
1278 <<
" mb and an impact-parameter enhancement factor of "
1279 << setw(10) << impactFac <<
". |\n";
1284 <<
" *------- End PYTHIA Event and Cross Section Statistics -----"
1285 <<
"------------------------------------------------*" << endl;
1288 if (reset) resetStatistics();