10 #include "Pythia8/VinciaQED.h"
22 double HungarianAlgorithm::solve(std::vector <std::vector<double> >&
23 distMatrix, std::vector<int>& assignment) {
25 unsigned int nRows = distMatrix.size();
26 unsigned int nCols = distMatrix[0].size();
27 double *distMatrixIn =
new double[nRows * nCols];
28 int *solution =
new int[nRows];
36 for (
unsigned int i = 0; i < nRows; i++)
37 for (
unsigned int j = 0; j < nCols; j++)
38 distMatrixIn[i + nRows * j] = distMatrix[i][j];
41 optimal(solution, &cost, distMatrixIn, nRows, nCols);
43 for (
unsigned int r = 0; r < nRows; r++)
44 assignment.push_back(solution[r]);
45 delete[] distMatrixIn;
55 void HungarianAlgorithm::optimal(
int *assignment,
double *cost,
56 double *distMatrixIn,
int nOfRows,
int nOfColumns) {
59 double *distMatrix, *distMatrixTemp, *distMatrixEnd, *columnEnd,
61 bool *coveredColumns, *coveredRows, *starMatrix, *newStarMatrix,
63 int nOfElements, minDim, row, col;
65 for (row = 0; row<nOfRows; row++) assignment[row] = -1;
69 nOfElements = nOfRows * nOfColumns;
70 distMatrix = (
double *)malloc(nOfElements *
sizeof(
double));
71 distMatrixEnd = distMatrix + nOfElements;
72 for (row = 0; row<nOfElements; row++) {
73 value = distMatrixIn[row];
75 std::cerr <<
"HungarianAlgorithm::assigmentoptimal(): All"
76 <<
" matrix elements have to be non-negative." << std::endl;
77 distMatrix[row] = value;
81 coveredColumns = (
bool *)calloc(nOfColumns,
sizeof(
bool));
82 coveredRows = (
bool *)calloc(nOfRows,
sizeof(
bool));
83 starMatrix = (
bool *)calloc(nOfElements,
sizeof(
bool));
84 primeMatrix = (
bool *)calloc(nOfElements,
sizeof(
bool));
86 newStarMatrix = (
bool *)calloc(nOfElements,
sizeof(
bool));
89 if (nOfRows <= nOfColumns) {
91 for (row = 0; row<nOfRows; row++) {
93 distMatrixTemp = distMatrix + row;
94 minValue = *distMatrixTemp;
95 distMatrixTemp += nOfRows;
96 while (distMatrixTemp < distMatrixEnd) {
97 value = *distMatrixTemp;
100 distMatrixTemp += nOfRows;
104 distMatrixTemp = distMatrix + row;
105 while (distMatrixTemp < distMatrixEnd) {
106 *distMatrixTemp -= minValue;
107 distMatrixTemp += nOfRows;
112 for (row = 0; row<nOfRows; row++)
113 for (col = 0; col<nOfColumns; col++)
114 if (abs(distMatrix[row + nOfRows*col]) < DBL_EPSILON)
115 if (!coveredColumns[col]) {
116 starMatrix[row + nOfRows*col] =
true;
117 coveredColumns[col] =
true;
122 for (col = 0; col<nOfColumns; col++) {
124 distMatrixTemp = distMatrix + nOfRows*col;
125 columnEnd = distMatrixTemp + nOfRows;
126 minValue = *distMatrixTemp++;
127 while (distMatrixTemp < columnEnd) {
128 value = *distMatrixTemp++;
129 if (value < minValue)
134 distMatrixTemp = distMatrix + nOfRows*col;
135 while (distMatrixTemp < columnEnd)
136 *distMatrixTemp++ -= minValue;
140 for (col = 0; col<nOfColumns; col++)
141 for (row = 0; row<nOfRows; row++)
142 if (abs(distMatrix[row + nOfRows*col]) < DBL_EPSILON)
143 if (!coveredRows[row]) {
144 starMatrix[row + nOfRows*col] =
true;
145 coveredColumns[col] =
true;
146 coveredRows[row] =
true;
149 for (row = 0; row<nOfRows; row++)
150 coveredRows[row] =
false;
154 step2b(assignment, distMatrix, starMatrix, newStarMatrix, primeMatrix,
155 coveredColumns, coveredRows, nOfRows, nOfColumns, minDim);
158 calcCost(assignment, cost, distMatrixIn, nOfRows);
162 free(coveredColumns);
175 void HungarianAlgorithm::vect(
int *assignment,
176 bool *starMatrix,
int nOfRows,
int nOfColumns) {
178 for (row = 0; row<nOfRows; row++)
179 for (col = 0; col<nOfColumns; col++)
180 if (starMatrix[row + nOfRows*col]) {
181 assignment[row] = col;
190 void HungarianAlgorithm::calcCost(
int *assignment,
double *cost,
191 double *distMatrix,
int nOfRows) {
193 for (row = 0; row<nOfRows; row++) {
194 col = assignment[row];
195 if (col >= 0) *cost += distMatrix[row + nOfRows*col];
203 void HungarianAlgorithm::step2a(
int *assignment,
double *distMatrix,
204 bool *starMatrix,
bool *newStarMatrix,
bool *primeMatrix,
205 bool *coveredColumns,
bool *coveredRows,
int nOfRows,
int nOfColumns,
209 bool *starMatrixTemp, *columnEnd;
211 for (col = 0; col<nOfColumns; col++) {
212 starMatrixTemp = starMatrix + nOfRows*col;
213 columnEnd = starMatrixTemp + nOfRows;
214 while (starMatrixTemp < columnEnd) {
215 if (*starMatrixTemp++) {
216 coveredColumns[col] =
true;
223 step2b(assignment, distMatrix, starMatrix, newStarMatrix, primeMatrix,
224 coveredColumns, coveredRows, nOfRows, nOfColumns, minDim);
232 void HungarianAlgorithm::step2b(
int *assignment,
double *distMatrix,
233 bool *starMatrix,
bool *newStarMatrix,
bool *primeMatrix,
234 bool *coveredColumns,
bool *coveredRows,
int nOfRows,
int nOfColumns,
238 int col, nOfCoveredColumns;
239 nOfCoveredColumns = 0;
240 for (col = 0; col<nOfColumns; col++)
241 if (coveredColumns[col]) nOfCoveredColumns++;
244 if (nOfCoveredColumns == minDim)
245 vect(assignment, starMatrix, nOfRows, nOfColumns);
247 else step3(assignment, distMatrix, starMatrix, newStarMatrix, primeMatrix,
248 coveredColumns, coveredRows, nOfRows, nOfColumns, minDim);
256 void HungarianAlgorithm::step3(
int *assignment,
double *distMatrix,
257 bool *starMatrix,
bool *newStarMatrix,
bool *primeMatrix,
258 bool *coveredColumns,
bool *coveredRows,
int nOfRows,
int nOfColumns,
262 int row, col, starCol;
266 for (col = 0; col<nOfColumns; col++)
267 if (!coveredColumns[col])
268 for (row = 0; row<nOfRows; row++)
269 if ((!coveredRows[row]) && (abs(distMatrix[row + nOfRows*col])
272 primeMatrix[row + nOfRows*col] =
true;
275 for (starCol = 0; starCol<nOfColumns; starCol++)
276 if (starMatrix[row + nOfRows*starCol])
280 if (starCol == nOfColumns) {
281 step4(assignment, distMatrix, starMatrix, newStarMatrix,
282 primeMatrix, coveredColumns, coveredRows, nOfRows,
283 nOfColumns, minDim, row, col);
286 coveredRows[row] =
true;
287 coveredColumns[starCol] =
false;
295 step5(assignment, distMatrix, starMatrix, newStarMatrix, primeMatrix,
296 coveredColumns, coveredRows, nOfRows, nOfColumns, minDim);
304 void HungarianAlgorithm::step4(
int *assignment,
double *distMatrix,
305 bool *starMatrix,
bool *newStarMatrix,
bool *primeMatrix,
306 bool *coveredColumns,
bool *coveredRows,
int nOfRows,
int nOfColumns,
307 int minDim,
int row,
int col) {
310 int n, starRow, starCol, primeRow, primeCol;
311 int nOfElements = nOfRows*nOfColumns;
312 for (n = 0; n<nOfElements; n++) newStarMatrix[n] = starMatrix[n];
314 newStarMatrix[row + nOfRows*col] =
true;
317 for (starRow = 0; starRow<nOfRows; starRow++)
318 if (starMatrix[starRow + nOfRows*starCol])
320 while (starRow < nOfRows) {
322 newStarMatrix[starRow + nOfRows*starCol] =
false;
325 for (primeCol = 0; primeCol<nOfColumns; primeCol++)
326 if (primeMatrix[primeRow + nOfRows*primeCol])
329 newStarMatrix[primeRow + nOfRows*primeCol] =
true;
332 for (starRow = 0; starRow<nOfRows; starRow++)
333 if (starMatrix[starRow + nOfRows*starCol])
339 for (n = 0; n<nOfElements; n++) {
340 primeMatrix[n] =
false;
341 starMatrix[n] = newStarMatrix[n];
343 for (n = 0; n<nOfRows; n++) coveredRows[n] =
false;
346 step2a(assignment, distMatrix, starMatrix, newStarMatrix, primeMatrix,
347 coveredColumns, coveredRows, nOfRows, nOfColumns, minDim);
355 void HungarianAlgorithm::step5(
int *assignment,
double *distMatrix,
356 bool *starMatrix,
bool *newStarMatrix,
bool *primeMatrix,
357 bool *coveredColumns,
bool *coveredRows,
int nOfRows,
int nOfColumns,
364 for (row = 0; row<nOfRows; row++)
365 if (!coveredRows[row])
366 for (col = 0; col<nOfColumns; col++)
367 if (!coveredColumns[col]) {
368 value = distMatrix[row + nOfRows*col];
374 for (row = 0; row<nOfRows; row++)
375 if (coveredRows[row])
376 for (col = 0; col<nOfColumns; col++)
377 distMatrix[row + nOfRows*col] += h;
380 for (col = 0; col<nOfColumns; col++)
381 if (!coveredColumns[col])
382 for (row = 0; row<nOfRows; row++)
383 distMatrix[row + nOfRows*col] -= h;
386 step3(assignment, distMatrix, starMatrix, newStarMatrix, primeMatrix,
387 coveredColumns, coveredRows, nOfRows, nOfColumns, minDim);
399 void QEDemitElemental::initPtr(Rndm* rndmPtrIn,
400 PartonSystems* partonSystemsPtrIn) {
402 partonSystemsPtr = partonSystemsPtrIn;
410 void QEDemitElemental::init(
Event &event,
int xIn,
int yIn,
double shhIn,
413 if (!isInitPtr) printOut(__METHOD_NAME__,
"initPtr not called");
426 if (!event[x].isFinal() && !event[y].isFinal() && event[x].pz() < 0)
430 if (event[x].isFinal() && !event[y].isFinal()) swap(x,y);
433 if (event[x].isFinal() && event[y].isFinal())
434 if (!event[x].isCharged() || event[y].isCharged()) swap(x,y);
442 m2Ant = m2(event[x], event[y]);
443 sAnt = 2*dot4(event[x], event[y]);
444 QQ = -
event[x].charge() *
event[y].charge();
447 if (!event[x].isFinal() && !event[y].isFinal()) isII =
true;
450 if (!event[x].isFinal() && event[y].isFinal()) {
454 int mother1 =
event[x].mother1();
458 if (event[x].pz() > 0) isIA =
true;
464 if (event[x].isFinal() && event[y].isFinal()) isFF =
true;
474 void QEDemitElemental::init(
Event &event,
int xIn, vector<int> iRecoilIn,
475 double shhIn,
double verboseIn) {
492 for (
int i = 0; i < (int)iRecoil.size(); i++)
493 pRecoil += event[iRecoil[i]].p();
494 my2 = pRecoil.m2Calc();
495 m2Ant = (pRecoil +
event[xIn].p()).m2Calc();
496 sAnt = 2*pRecoil*
event[xIn].p();
507 double QEDemitElemental::generateTrial(
Event &event,
double q2Start,
508 double q2Low,
double alphaIn,
double cIn) {
510 if (hasTrial)
return q2Sav;
518 q2Start = min(q2Start, sAnt/4.);
519 if (q2Start < q2Low)
return q2Low;
522 double lambda = m2Ant*m2Ant + mx2*mx2 + my2*my2
523 - 2.*m2Ant*mx2 - 2.*m2Ant*my2 - 2.*mx2*my2;
525 double zMin = (4*q2Low/sAnt < 1E-8)
527 : 0.5*(1. - sqrt(1. - 4*q2Low/sAnt));
531 double Iz = (zMin < 1E-8)
532 ? -2*log(zMin) - 2*zMin - pow2(zMin)
533 : 2*log((1-zMin)/zMin);
534 double comFac = 2*M_PI*sqrt(lambda)/alpha/Iz/c/sAnt;
535 double q2New = q2Start*pow(rndmPtr->flat(), comFac);
538 zetaSav = 1/(exp(Iz*(0.5 - rndmPtr->flat())) + 1);
539 sxjSav = zetaSav != 1 ? sqrt(sAnt*q2Sav*zetaSav/((1-zetaSav))) : 0;
540 syjSav = zetaSav != 0 ? sqrt(sAnt*q2Sav*(1-zetaSav)/(zetaSav)) :
541 std::numeric_limits<double>::infinity();
545 if (isFF && abs(idx) == 24) {
546 double Iz = (zMin < 1E-8) ?
547 -log(zMin) - zMin - pow2(zMin)/2. : log((1-zMin)/zMin);
548 double comFac = 3.*M_PI*sqrt(lambda)/alpha/Iz/c/sAnt/2.;
549 double q2New = q2Start*pow(rndmPtr->flat(), comFac);
552 double r = rndmPtr->flat();
553 zetaSav = (zMin < 1E-8)
554 ? 1 - pow(zMin,r)*(1. - (1.-r)*zMin)
555 : 1 - pow(zMin,r)*pow(1.-zMin, 1.-r);
556 sxjSav = q2Sav/zetaSav;
557 syjSav = zetaSav*sAnt;
561 if (isFF && abs(idy) == 24) {
562 double Iz = (zMin < 1E-8)
563 ? -log(zMin) - zMin - pow2(zMin)/2.
564 : log((1-zMin)/zMin);
565 double comFac = 3.*M_PI*sqrt(lambda)/alpha/Iz/c/sAnt/2.;
566 double q2New = q2Start*pow(rndmPtr->flat(), comFac);
569 double r = rndmPtr->flat();
570 zetaSav = (zMin < 1E-8)
571 ? 1 - pow(zMin,r)*(1. - (1.-r)*zMin)
572 : 1 - pow(zMin,r)*pow(1.-zMin, 1.-r);
573 sxjSav = zetaSav*sAnt;
574 syjSav = q2Sav/zetaSav;
583 int nSys = partonSystemsPtr->sizeSys();
584 for (
int i=0; i<nSys; i++) {
586 if (isIA) iEv = partonSystemsPtr->getInA(i);
587 else iEv = partonSystemsPtr->getInB(i);
588 exUsed +=
event[iEv].e();
590 double exMax = sqrt(shh)/2.0 - (exUsed-ex);
591 double sjkMax = sAnt*(exMax-ex)/ex;
594 q2Start = min(q2Start, sAnt*(exMax - ex)/ex);
595 if (q2Start < q2Low)
return q2Low;
596 double zMax = sjkMax/(sjkMax + my2);
597 double zMin = q2Low/sjkMax;
603 double Iz = log(zMax/zMin);
605 double comFac = M_PI/alpha/Iz/c/Rpdf;
606 double q2New = q2Start*pow(rndmPtr->flat(), comFac);
609 zetaSav = zMin*pow(zMax/zMin, rndmPtr->flat());
610 sxjSav = sAnt*zetaSav + q2Sav;
611 syjSav = q2Sav/zetaSav;
618 if (abs(idy) == 24) {
619 double Iz = log((1-zMin)/(1-zMax));
621 double comFac = 3.*M_PI/alpha/Iz/c/Rpdf/2.;
622 double q2New = q2Start;
623 double zetaNew, sxjNew, syjNew;
625 q2New *= pow(rndmPtr->flat(), comFac);
626 if (q2New < q2Sav) {
break;}
627 zetaNew = 1. - (1-zMin)*pow((1-zMax)/(1-zMin),rndmPtr->flat());
628 sxjNew = sAnt*zetaNew + q2New;
629 syjNew = q2New/zetaNew;
632 double pVeto = sAnt/(sAnt + syjNew);
633 if (rndmPtr->flat() < pVeto) {
648 q2Start = min(q2Start, pow2(shh-sAnt)/shh/4.);
649 if (q2Start < q2Low) {
return q2Low;}
653 double zMin = 0.5*(shh-sAnt -
654 sqrt((shh-sAnt)*(shh-sAnt) - (4.*shh*q2Low)))/shh;
655 double zMax = 0.5*(shh-sAnt +
656 sqrt((shh-sAnt)*(shh-sAnt) - (4.*shh*q2Low)))/shh;
657 if (4.*shh*q2Low/pow2((shh-sAnt)) < 1e-8)
658 zMin = q2Low/(shh-sAnt);
659 double Iz = log(zMax*(1-zMin)/(1-zMax)/zMin);
661 double comFac = M_PI/alpha/Iz/c/Rpdf;
662 double q2New = q2Start*pow(rndmPtr->flat(), comFac);
665 double r = rndmPtr->flat();
666 double w = pow(zMax/(1-zMax), r) * pow(zMin/(1-zMin), 1.-r);
668 sxjSav = (q2Sav + sAnt*zetaSav)/(1.-zetaSav);
669 syjSav = q2Sav/zetaSav;
677 double mr2 = abs((event[x].p() - event[y].p()).m2Calc());
678 double mx = sqrt(mx2);
679 double my = sqrt(my2);
680 double mr = sqrt(mr2);
681 double lambda = mr2*mr2 + mx2*mx2 + my2*my2
682 - 2.*mr2*mx2 - 2.*mr2*my2 - 2.*mx2*my2;
683 double sjkMax = pow2(mx - mr) - my2;
684 double sajMax = mx2 - pow2(my + mr);
686 q2Start = min(q2Start, sajMax*sjkMax/(sAnt + sjkMax));
690 double zMin = q2Low/sjkMax;
691 double zMax = sajMax/sAnt;
693 double Iz = log(zMax/zMin);
694 double comFac = M_PI*sqrt(lambda)*sAnt/alpha/Iz/c/pow2(sAnt+sjkMax);
695 double q2New = q2Start;
696 double zetaNew, sxjNew, syjNew;
698 q2New *= pow(rndmPtr->flat(), comFac);
699 if (q2New < q2Sav) {
break;}
700 zetaNew = zMin*pow(zMax/zMin, rndmPtr->flat());
701 sxjNew = sAnt*zetaNew + q2New;
702 syjNew = q2New/zetaNew;
705 double pVeto = pow2(syjNew+sAnt)/pow2(sjkMax+sAnt);
706 if (rndmPtr->flat() < pVeto) {
718 if (abs(idx) == 24) {
719 double zMin = q2Low/(sajMax - q2Low);
720 double zMax = sjkMax/sAnt;
721 if(zMin < zMax && zMin > 0){
722 double Iz = pow2(zMax) + (1./3.)*pow3(zMax)
723 - pow2(zMin) - (1./3.)*pow3(zMin);
724 double comFac = 3.*M_PI*sqrt(lambda)/alpha/Iz/c/sAnt/2.;
725 double q2New = q2Start*pow(rndmPtr->flat(), comFac);
728 double a = rndmPtr->flat()*Iz + pow2(zMin) + (1./3.)*pow3(zMin);
734 double f = pow2(zetaSav) + pow3(zetaSav)/3. - a;
735 double fPrime = 2.*zetaSav + pow2(zetaSav);
736 double zetaNew = zetaSav - f/fPrime;
737 if (zetaNew > zMax) {zetaSav = zMax;
continue;}
738 if (zetaNew < zMin) {zetaSav = zMin;
continue;}
739 if (abs(zetaNew - zetaSav) < 1E-8*zetaNew) {
744 printOut(__METHOD_NAME__,
745 "RF(W) failed to find zeta with Newton-Raphson");
751 sxjSav = (1.+zetaSav)*q2Sav/zetaSav;
752 syjSav = sAnt*zetaSav;
758 if (abs(idy) == 24) {
759 double zMin = q2Low/sjkMax;
760 double zMax = sajMax/sAnt;
762 double Iz = log((1-zMin)/(1-zMax));
763 double comFac = 3.*M_PI*sqrt(lambda)/alpha/Iz/c/(sAnt+sjkMax)/2.;
764 double q2New = q2Start;
765 double zetaNew, sxjNew, syjNew;
767 q2New *= pow(rndmPtr->flat(), comFac);
768 if (q2New < q2Sav) {
break;}
769 zetaNew = 1. - (1-zMin)*pow((1-zMax)/(1-zMin),rndmPtr->flat());
770 sxjNew = sAnt*zetaNew + q2New;
771 syjNew = q2New/zetaNew;
774 double pVeto = (syjNew+sAnt)/(sjkMax+sAnt);
775 if (rndmPtr->flat() < pVeto) {
786 phiSav = 2.*M_PI*rndmPtr->flat();
800 void QEDemitSystem::initPtr(Info* infoPtrIn, VinciaCommon* vinComPtrIn) {
802 particleDataPtr = infoPtr->particleDataPtr;
803 partonSystemsPtr = infoPtr->partonSystemsPtr;
804 rndmPtr = infoPtr->rndmPtr;
805 settingsPtr = infoPtr->settingsPtr;
806 vinComPtr = vinComPtrIn;
814 void QEDemitSystem::init(BeamParticle* beamAPtrIn, BeamParticle* beamBPtrIn,
819 printOut(__METHOD_NAME__,
"QEDemitSystem:initPtr not called");
823 beamAPtr = beamAPtrIn;
824 beamBPtr = beamBPtrIn;
827 mode = settingsPtr->mode(
"Vincia:photonEmissionMode");
828 useFullWkernel = settingsPtr->flag(
"Vincia:fullWkernel");
829 emitBelowHad = settingsPtr->flag(
"PartonLevel:Remnants");
832 TINYPDF = pow(10,-10);
843 void QEDemitSystem::prepare(
int iSysIn,
Event &event,
double q2CutIn,
844 bool isBelowHadIn, vector<double> evolutionWindowsIn, AlphaEM alIn) {
847 infoPtr->errorMsg(
"Error in "+__METHOD_NAME__+
": Not initialised.");
852 if (verbose >= louddebug) printOut(__METHOD_NAME__,
"begin --------------");
858 isBelowHad = isBelowHadIn;
859 evolutionWindows = evolutionWindowsIn;
864 if (verbose >= louddebug) printOut(__METHOD_NAME__,
"end --------------");
872 double QEDemitSystem::aTrial(QEDemitElemental* ele,
double sxj,
double syj,
879 if (ele->isFF || ele->isDip) {
880 double s = sxj + syj + sxy;
882 if (ele->isFF && abs(idx) == 24) ant += 8.*s/sxj/(s - syj)/3.;
883 if (ele->isFF && abs(idy) == 24) ant += 8.*s/syj/(s - sxj)/3.;
888 double s = sxj + sxy - syj;
889 ant += 4*pow2(s+syj)/(s*sxj*syj);
890 if (abs(idy) == 24) ant += 8.*(s + syj)/syj/(s + syj - sxj)/3.;
895 double s = sxy - sxj - syj;
896 ant += 4*sxy*sxy/s/sxj/syj;
901 double s = sxj + sxy - syj;
902 ant += 4*pow2(s+syj)/s/sxj/syj;
903 if (abs(idx) == 24) ant += 8*(2.*syj/s + pow2(syj)/pow2(s))/sxj/3.;
904 if (abs(idy) == 24) ant += 8.*(s + syj)/syj/(s + syj - sxj)/3.;
914 double QEDemitSystem::aPhys(QEDemitElemental* ele,
double sxj,
double syj,
916 double mx2 = ele->mx2;
917 double my2 = ele->my2;
924 double s = sxj + syj + sxy;
926 ant += 4.*sxy/sxj/syj - 4.*mx2/sxj/sxj - 4.*my2/syj/syj;
929 if (abs(idx) == 24 && useFullWkernel)
930 ant += (4./3.)*(syj/(s - syj) + syj*(s - syj)/s/s)/sxj;
935 if (abs(idy) == 24 && useFullWkernel)
936 ant += (4./3.)*(sxj/(s - sxj) + sxj*(s - sxj)/s/s)/syj;
943 double s = sxj + syj + sxy;
944 ant += 4.*sxy/sxj/(sxj+syj) - 4.*mx2/sxj/sxj + 2.*syj/sxj/s;
949 double s = sxj + sxy - syj;
952 ant += 4.*sxy/sxj/syj - 4.*my2/syj/syj + 2.*syj/sxj/s;
954 if (abs(idy) == 24 && useFullWkernel)
955 ant += (8./3.)*( sxj/(sxy + syj) + sxj/(s + syj)
956 - pow2(sxj)/pow2(s + syj) )/syj;
963 double s = sxy - sxj - syj;
965 ant = 4.*sxy/sxj/syj + 2.*(sxj/syj + syj/sxj)/s;
970 double s = sxj + sxy - syj;
972 ant = 4.*sxy/sxj/syj - 4.*mx2/sxj/sxj - 4.*my2/syj/syj;
975 if (abs(idx) == 24 && useFullWkernel)
976 ant += (8./3.)*( syj/(s+syj) + syj/s + pow2(syj)/pow2(s) )/sxj;
981 if (abs(idy) == 24 && useFullWkernel)
982 ant += (8./3.)*( sxj/(sxy + syj) + sxj/(s + syj)
983 - pow2(sxj)/pow2(s + syj) )/syj;
995 double QEDemitSystem::PDFratio(
bool isA,
double eOld,
double eNew,
int id,
997 double xOld = eOld/(sqrt(shh)/2.0);
998 double xNew = eNew/(sqrt(shh)/2.0);
999 double newPDF, oldPDF;
1001 newPDF = beamAPtr->xfISR(iSys,
id, xNew, Qt2)/xNew;
1002 oldPDF = beamAPtr->xfISR(iSys,
id, xOld, Qt2)/xOld;
1003 if (abs(newPDF) < TINYPDF) newPDF = TINYPDF;
1004 if (abs(oldPDF) < TINYPDF) oldPDF = TINYPDF;
1006 newPDF = beamBPtr->xfISR(iSys,
id, xNew, Qt2)/xNew;
1007 oldPDF = beamBPtr->xfISR(iSys,
id, xOld, Qt2)/xOld;
1008 if (abs(newPDF) < TINYPDF) newPDF = TINYPDF;
1009 if (abs(oldPDF) < TINYPDF) oldPDF = TINYPDF;
1011 return newPDF/oldPDF;
1018 void QEDemitSystem::buildSystem(
Event &event) {
1026 HungarianAlgorithm ha;
1028 if (isBelowHad && emitBelowHad) {
1029 map<int, vector<int> > posMap, negMap;
1030 vector<Vec4> posMoms, negMoms;
1033 vector<int> iQuarks, iLeptons;
1034 int sysSize = partonSystemsPtr->sizeOut(iSys);
1035 for (
int i = 0; i < sysSize; i++) {
1036 int iEv = partonSystemsPtr->getOut(iSys, i);
1037 if (event[iEv].col() != 0 && event[iEv].acol()==0 &&
1038 event[iEv].isFinal()) {
1042 for (
int iJun = 0; iJun <
event.sizeJunction(); ++iJun) {
1043 for (
int iLeg = 0; iLeg < 3; ++iLeg) {
1044 if (event[iEv].col() ==
event.endColJunction(iJun,iLeg)) {
1050 if (!isJun) iQuarks.push_back(iEv);
1052 if (event[iEv].isLepton() && event[iEv].isCharged())
1053 iLeptons.push_back(iEv);
1057 if (iLeptons.size() == 0)
return;
1060 for (
int i = 0; i < (int)iLeptons.size(); i++) {
1061 int iEv = iLeptons[i];
1062 vector<int> iLeptonVec;
1063 iLeptonVec.push_back(iEv);
1064 if (event[iEv].chargeType() == 3) {
1065 posMoms.push_back(event[iEv].p());
1066 posMap[posMoms.size()-1] = iLeptonVec;
1068 if (event[iEv].chargeType() == -3) {
1069 negMoms.push_back(event[iEv].p());
1070 negMap[negMoms.size()-1] = iLeptonVec;
1074 for (
int i = 0; i < (int)iQuarks.size(); i++) {
1077 int iEv = iQuarks[i];
1078 vector<int> iPseudoVec;
1079 iPseudoVec.push_back(iEv);
1080 pPseudo +=
event[iEv].p();
1084 int colTag =
event[iEv].col();
1085 for (
int j = 0; j < sysSize; j++) {
1086 int jEv = partonSystemsPtr->getOut(iSys, j);
1087 if (event[jEv].acol() == colTag && event[jEv].isFinal()) {
1092 if (iEv == iPseudoVec.back()) {
1093 infoPtr->errorMsg(
"Error in "+__METHOD_NAME__
1094 +
": Colour tracing failed.");
1097 iPseudoVec.push_back(iEv);
1098 pPseudo +=
event[iEv].p();
1100 while(!event[iEv].isQuark()&&!event[iEv].isDiquark());
1103 int chargeTypePseudo =
event[iPseudoVec.front()].chargeType()
1104 +
event[iPseudoVec.back()].chargeType();
1106 if (chargeTypePseudo == 3) {
1107 posMoms.push_back(pPseudo);
1108 posMap[posMoms.size()-1] = iPseudoVec;
1110 if (chargeTypePseudo == -3) {
1111 negMoms.push_back(pPseudo);
1112 negMap[negMoms.size()-1] = iPseudoVec;
1116 if (chargeTypePseudo == 6) {
1117 posMoms.push_back(pPseudo);
1118 posMap[posMoms.size()-1] = iPseudoVec;
1119 posMoms.push_back(pPseudo);
1120 posMap[posMoms.size()-1] = iPseudoVec;
1122 if (chargeTypePseudo == -6) {
1123 negMoms.push_back(pPseudo);
1124 negMap[negMoms.size()-1] = iPseudoVec;
1125 negMoms.push_back(pPseudo);
1126 negMap[negMoms.size()-1] = iPseudoVec;
1131 if (posMoms.size() == 0)
return;
1134 vector<vector<double> > weights;
1135 weights.resize(posMoms.size());
1136 for (
int i=0; i<(int)posMoms.size(); i++) {
1137 weights[i].resize(negMoms.size());
1138 for (
int j=0; j<(int)negMoms.size(); j++) {
1139 double w = posMoms[i]*negMoms[j]
1140 - posMoms[i].mCalc()*negMoms[j].mCalc();
1144 vector<int> assignment;
1145 ha.solve(weights, assignment);
1147 for (
int i = 0; i < (int)posMoms.size(); i++) {
1149 int iNeg = assignment[i];
1151 if (posMap[iPos].size() == 1 || negMap[iNeg].size() == 1) {
1152 eleVec.push_back(QEDemitElemental());
1153 eleVec.back().initPtr(rndmPtr, partonSystemsPtr);
1155 if (posMap[iPos].size() == 1 && negMap[iNeg].size() == 1)
1156 eleVec.back().init(event, posMap[iPos][0], negMap[iNeg][0], shh,
1159 if (posMap[iPos].size() == 1 && negMap[iNeg].size() != 1)
1160 eleVec.back().init(event, posMap[iPos][0], negMap[iNeg], shh,
1162 if (posMap[iPos].size()!=1 && negMap[iNeg].size()==1)
1163 eleVec.back().init(event, negMap[iNeg][0], posMap[iPos], shh,
1169 }
else if(!isBelowHad) {
1171 int sysSize = partonSystemsPtr->sizeAll(iSys);
1172 for (
int i = 0; i < sysSize; i++) {
1173 int iEv = partonSystemsPtr->getAll(iSys, i);
1174 if (event[iEv].isCharged()) iCoh.push_back(iEv);
1180 if (partonSystemsPtr->getInA(iSys) == 0 &&
1181 partonSystemsPtr->getInB(iSys) == 0 &&
1182 partonSystemsPtr->getInRes(iSys) == 0) {
1184 int iRes =
event[partonSystemsPtr->getOut(iSys, 0)].mother1();
1185 if (iRes != 0 && event[iRes].isCharged()) {
1187 int ida1 =
event[iRes].daughter1();
1188 int ida2 =
event[iRes].daughter2();
1191 for (
int i=0; i<partonSystemsPtr->sizeOut(iSys); ++i)
1192 if (partonSystemsPtr->getOut(iSys,i) < ida1
1193 || partonSystemsPtr->getOut(iSys,i) > ida2) isOK =
false;
1194 if (isOK) {iCoh.push_back(iRes);}
1200 int chargeTypeTot = 0;
1201 for (
int i = 0; i < (int)iCoh.size(); i++) {
1202 double cType =
event[iCoh[i]].chargeType();
1203 chargeTypeTot += (
event[iCoh[i]].isFinal() ? cType : -cType);
1206 if (chargeTypeTot != 0) {
1207 infoPtr->errorMsg(
"Error in "+__METHOD_NAME__
1208 +
": Charge not conserved above hadronization scale");
1209 if (verbose >= superdebug) {
1210 printOut(__METHOD_NAME__,
"Printing events and systems");
1212 partonSystemsPtr->list();
1218 vector<vector<int> > posChargeTypes;
1219 posChargeTypes.resize(3);
1220 vector<vector<int> > negChargeTypes;
1221 negChargeTypes.resize(3);
1223 for (
int i = 0; i < (int)iCoh.size(); i++) {
1226 double Q =
event[iEv].charge();
1228 int n = abs(event[iEv].chargeType()) - 1;
1230 if (!event[iEv].isFinal()) {Q = -Q;}
1231 if (Q > 0) posChargeTypes[n].push_back(iEv);
1232 else negChargeTypes[n].push_back(iEv);
1239 for (
int i=0; i<3; i++) {
1240 int posSize = posChargeTypes[i].size();
1241 int negSize = negChargeTypes[i].size();
1242 int maxSize = max(posSize,negSize);
1244 vector<vector<double> > weights;
1245 weights.resize(maxSize);
1247 for (
int x = 0; x < maxSize; x++) {
1248 weights[x].resize(maxSize);
1249 for (
int y = 0; y < maxSize; y++) {
1252 double wIn = (0.9 + 0.2*rndmPtr->flat())*1E300;
1253 if (x < posSize && y < negSize) {
1254 int xEv = posChargeTypes[i][x];
1255 int yEv = negChargeTypes[i][y];
1256 wIn =
event[xEv].p()*
event[yEv].p()
1257 -
event[xEv].m()*
event[yEv].m();
1259 weights[x][y] = wIn;
1264 vector<int> assignment;
1265 ha.solve(weights, assignment);
1269 for (
int j = 0; j < maxSize; j++) {
1271 int y = assignment[j];
1272 if (x < posSize && y < negSize) {
1273 int xEv = posChargeTypes[i][x];
1274 int yEv = negChargeTypes[i][y];
1275 eleVec.push_back(QEDemitElemental());
1276 eleVec.back().initPtr(rndmPtr, partonSystemsPtr);
1277 eleVec.back().init(event, xEv, yEv, shh, verbose);
1278 }
else if (x < posSize) {
1279 int xEv = posChargeTypes[i][x];
1280 iCoh.push_back(xEv);
1281 }
else if (y < negSize) {
1282 int yEv = negChargeTypes[i][y];
1283 iCoh.push_back(yEv);
1291 eleMat.resize(iCoh.size());
1292 for (
int i = 0; i < (int)iCoh.size(); i++) {
1293 eleMat[i].resize(i);
1294 for (
int j = 0; j < i; j++) {
1295 eleMat[i][j].initPtr(rndmPtr, partonSystemsPtr);
1296 eleMat[i][j].init(event, iCoh[i], iCoh[j], shh, verbose);
1302 for (
int i = 0; i < (int)eleMat.size(); i++)
1303 for (
int j = 0; j < i; j++) cMat += max(eleMat[i][j].QQ, 0.);
1312 double QEDemitSystem::generateTrialScale(
Event &event,
double q2Start) {
1315 if (q2Start < q2Cut || evolutionWindows.size() == 0) {
return 0;}
1318 int iEvol = evolutionWindows.size() - 1;
1319 while (iEvol >= 1 && q2Start <= evolutionWindows[iEvol]) iEvol--;
1320 double q2Low = evolutionWindows[iEvol];
1322 infoPtr->errorMsg(
"Error in "+__METHOD_NAME__+
": Evolution window < 0");
1326 double alphaMax = al.alphaEM(q2Start);
1329 for (
int i = 0; i < (int)eleVec.size(); i++) {
1330 double c = eleVec[i].QQ;
1331 double q2New = eleVec[i].generateTrial(event, q2Start, q2Low, alphaMax, c);
1332 if (q2New > q2Low && q2New > q2Trial) {
1334 eleTrial = &eleVec[i];
1340 for (
int i = 0; i < (int)eleMat.size(); i++) {
1341 for (
int j = 0; j < i; j++) {
1342 double q2New = eleMat[i][j].generateTrial(event, q2Start, q2Low,
1344 if (q2New > q2Low && q2New > q2Trial) {
1346 eleTrial = &eleMat[i][j];
1353 if (q2Trial < q2Low) {
1354 if (iEvol == 0) {
return 0;}
1356 for (
int i = 0; i < (int)eleVec.size(); i++) eleVec[i].hasTrial =
false;
1357 for (
int i=0; i<(int)eleMat.size(); i++)
1358 for (
int j=0; j<i; j++) eleMat[i][j].hasTrial =
false;
1359 return generateTrialScale(event, q2Low);
1371 bool QEDemitSystem::checkVeto(
Event &event) {
1374 if (verbose >= debug) printOut(__METHOD_NAME__,
"begin --------------");
1375 eleTrial->hasTrial =
false;
1378 vector<Vec4> pOld, pNew;
1385 if (eleTrial->isII) {
1386 double saj = eleTrial->sxjSav;
1387 double sbj = eleTrial->syjSav;
1388 double phi = eleTrial->phiSav;
1389 double sAB = eleTrial->sAnt;
1390 double sab = sAB + saj + sbj;
1393 pOld.push_back(event[eleTrial->x].p());
1394 pOld.push_back(event[eleTrial->y].p());
1397 int sysSize = partonSystemsPtr->sizeAll(iSys);
1398 for (
int i = 0; i < sysSize; i++) {
1399 int iEv = partonSystemsPtr->getAll(iSys, i);
1400 if (iEv < 0 || !event[iEv].isFinal())
continue;
1401 if (iEv == eleTrial->x || iEv == eleTrial->y)
continue;
1402 pRec.push_back(event[iEv].p());
1403 iRec.push_back(iEv);
1407 if (!vinComPtr->map2to3IImassless(pNew, pRec, pOld, sAB,saj,sbj,sab, phi))
1411 double eaUsed = 0, ebUsed = 0;
1412 int nSys = partonSystemsPtr->sizeSys();
1413 for (
int i = 0; i < nSys; i++) {
1414 eaUsed +=
event[partonSystemsPtr->getInA(i)].e();
1415 ebUsed +=
event[partonSystemsPtr->getInB(i)].e();
1417 if ((eaUsed - pOld[0].e() + pNew[0].e()) > 0.98*sqrt(shh)/2.)
return false;
1418 if ((ebUsed - pOld[1].e() + pNew[2].e()) > 0.98*sqrt(shh)/2.)
return false;
1422 else if (eleTrial->isIF) {
1423 double saj = eleTrial->sxjSav;
1424 double sjk = eleTrial->syjSav;
1425 double phi = eleTrial->phiSav;
1426 double sAK = eleTrial->sAnt;
1427 double sak = sAK + sjk - saj;
1428 double mK2 = eleTrial->my2;
1431 if (sak < 0 || saj*sjk*sak - saj*saj*mK2 < 0) {
return false;}
1434 pOld.push_back(event[eleTrial->x].p());
1435 pOld.push_back(event[eleTrial->y].p());
1438 if (!vinComPtr->map2to3IFlocal(pNew, pOld, sAK, saj, sjk, sak, phi,
1439 mK2, 0, mK2))
return false;
1443 int nSys = partonSystemsPtr->sizeSys();
1444 for (
int i = 0; i < nSys; i++) {
1446 if (eleTrial->isIA) iEv = partonSystemsPtr->getInA(i);
1447 else iEv = partonSystemsPtr->getInB(i);
1448 eaUsed +=
event[iEv].e();
1450 if ((eaUsed - pOld[0].e() + pNew[0].e()) > 0.98*sqrt(shh)/2.)
return false;
1454 else if (eleTrial->isRF) {
1455 double saj = eleTrial->sxjSav;
1456 double sjk = eleTrial->syjSav;
1457 double sAK = eleTrial->sAnt;
1458 double sak = sAK + sjk - saj;
1459 double phi = eleTrial->phiSav;
1460 double mA2 = eleTrial->mx2;
1461 double mK2 = eleTrial->my2;
1464 if (sak < 0 || saj*sjk*sak - saj*saj*mK2 - sjk*sjk*mA2 < 0)
return false;
1467 pOld.push_back(event[eleTrial->x].p());
1468 pOld.push_back(event[eleTrial->y].p());
1471 int sysSize = partonSystemsPtr->sizeAll(iSys);
1472 for (
int i = 0; i < sysSize; i++) {
1473 int iEv = partonSystemsPtr->getAll(iSys, i);
1474 if (iEv < 0 || !event[iEv].isFinal()) {
continue;}
1475 if (iEv == eleTrial->x || iEv == eleTrial->y) {
continue;}
1476 pRec.push_back(event[iEv].p());
1477 iRec.push_back(iEv);
1481 vector<double> masses;
1482 masses.push_back(sqrt(mA2));
1483 masses.push_back(0.);
1484 masses.push_back(sqrt(mK2));
1485 masses.push_back(sqrtpos(mA2+mK2-sAK));
1486 vector<double> invariants;
1487 invariants.push_back(sAK);
1488 invariants.push_back(saj);
1489 invariants.push_back(sjk);
1490 invariants.push_back(sak);
1491 vector<Vec4> pAfter;
1492 vector<Vec4> pBefore = pOld;
1493 pBefore.insert(pBefore.end(), pRec.begin(), pRec.end());
1494 if (!vinComPtr->map2toNRFmassive(pAfter, pBefore, 0, 1, invariants, phi,
1495 masses))
return false;
1496 pNew.push_back(pAfter[0]);
1497 pNew.push_back(pAfter[1]);
1498 pNew.push_back(pAfter[2]);
1502 for (
int i = 3; i < (int)pAfter.size(); i++) pRec.push_back(pAfter[i]);
1505 if (pRec.size() != iRec.size()) {
1506 infoPtr->errorMsg(
"Error in "+__METHOD_NAME__
1507 +
": inconsistent recoilers in RF kinematics.");
1513 else if (eleTrial->isFF) {
1514 double sIK = eleTrial->m2Ant - eleTrial->mx2 - eleTrial->my2;
1515 double sij = eleTrial->sxjSav;
1516 double sjk = eleTrial->syjSav;
1517 double sik = sIK - sij - sjk;
1518 double mi = sqrt(eleTrial->mx2);
1519 double mk = sqrt(eleTrial->my2);
1520 double phi = eleTrial->phiSav;
1522 vector<double> invariants;
1523 invariants.push_back(sIK);
1524 invariants.push_back(sij);
1525 invariants.push_back(sjk);
1527 vector<double> masses;
1528 masses.push_back(mi);
1529 masses.push_back(0);
1530 masses.push_back(mk);
1533 if (sik < 0)
return false;
1534 if (sij*sjk*sik - pow2(sij)*pow2(mk) - pow2(sjk)*pow2(mi) < 0)
1538 pOld.push_back(event[eleTrial->x].p());
1539 pOld.push_back(event[eleTrial->y].p());
1542 if (!vinComPtr->map2to3FF(pNew, pOld, 3, invariants, phi, masses))
1547 else if (eleTrial->isDip) {
1550 for (
int i = 0; i < (int)eleTrial->iRecoil.size(); i++)
1551 pk += event[eleTrial->iRecoil[i]].p();
1552 double sIK = eleTrial->m2Ant - eleTrial->mx2 - eleTrial->my2;
1553 double sij = eleTrial->sxjSav;
1554 double sjk = eleTrial->syjSav;
1555 double sik = sIK - sij - sjk;
1556 double mi = sqrt(eleTrial->mx2);
1557 double mk = pk.mCalc();
1558 double phi = eleTrial->phiSav;
1560 vector<double> invariants;
1561 invariants.push_back(sIK);
1562 invariants.push_back(sij);
1563 invariants.push_back(sjk);
1565 vector<double> masses;
1566 masses.push_back(mi);
1567 masses.push_back(0);
1568 masses.push_back(mk);
1571 if (sik < 0) {
return false;}
1572 if (sij*sjk*sik - pow2(sij)*pow2(mk) - pow2(sjk)*pow2(mi) < 0)
1576 pOld.push_back(event[eleTrial->x].p());
1580 if (!vinComPtr->map2to3FF(pNew, pOld, 3, invariants, phi, masses))
1583 Vec4 pPhot = pNew[1];
1586 int x = eleTrial->x;
1587 int y = eleTrial->y;
1588 double sxj = eleTrial->sxjSav;
1589 double syj = eleTrial->syjSav;
1590 double sxy = px*py*2.;
1596 pVeto *= al.alphaEM(eleTrial->q2Sav) / eleTrial->alpha;
1597 if (pVeto > 1) printOut(__METHOD_NAME__,
"Alpha increased");
1602 double aTrialNow = aTrial(eleTrial, sxj, syj, sxy);
1603 double aPhysNow = aPhys(eleTrial, sxj, syj, sxy);
1605 if (aPhysNow/aTrialNow > 1.001) {
1607 ss1 <<
"Incorrect overestimate (eleVec) " << aPhysNow/aTrialNow;
1608 printOut(__METHOD_NAME__, ss1.str());
1609 if (verbose > louddebug) {
1610 stringstream ss2, ss3;
1611 if (eleTrial->isFF) ss2 <<
"Antenna is FF";
1612 if (eleTrial->isIF) ss2 <<
"Antenna is IF";
1613 if (eleTrial->isRF) ss2 <<
"Antenna is RF";
1614 if (eleTrial->isII) ss2 <<
"Antenna is II";
1615 printOut(__METHOD_NAME__, ss2.str());
1616 printOut(__METHOD_NAME__, ss3.str());
1619 pVeto *= aPhysNow/aTrialNow;
1624 double aSectorNow = aPhys(eleTrial, sxj, syj, sxy);
1625 double aTrialFull = eleTrial->c*aTrial(eleTrial, sxj, syj, sxy);
1626 double aPhysFull = 0;
1629 map<int, double> sj;
1632 for (
int i = 0; i < (int)iCoh.size(); i++) {
1638 }
else if (iEv == y) {
1644 if (eleTrial->isII) {
1646 for (
int j = 0; j < (int)iRec.size(); j++) {
1647 if (iEv == iRec[j]) {
1649 sj[iEv] = 2.*pRec[j]*pPhot;
1655 p[iEv] =
event[iEv].p();
1656 sj[iEv] = 2.*
event[iEv].p()*pPhot;
1662 for (
int v=0; v<(int)eleMat.size(); v++) {
1663 for (
int w=0; w<v; w++) {
1664 double sxjNow = sj[eleMat[v][w].x];
1665 double syjNow = sj[eleMat[v][w].y];
1666 double sxyNow = 2.*p[eleMat[v][w].x]*p[eleMat[v][w].y];
1667 double aPhysNow = aPhys(&eleMat[v][w], sxjNow, syjNow, sxyNow);
1670 if (aPhysNow > aSectorNow)
return false;
1673 aPhysFull += eleMat[v][w].QQ*aPhysNow;
1677 if (aPhysFull < 0) {aPhysFull = 0;}
1680 if (aPhysFull/aTrialFull > 1) {
1682 ss1 <<
"Incorrect overestimate (eleVec) " << aPhysFull/aTrialFull;
1683 printOut(__METHOD_NAME__, ss1.str());
1686 pVeto *= aPhysFull/aTrialFull;
1690 if (eleTrial->isIF) {
1691 pVeto *= PDFratio(eleTrial->isIA, pOld[0].e(), pNew[0].e(),
1692 eleTrial->idx, eleTrial->q2Sav);
1694 if (eleTrial->isII) {
1695 pVeto *= PDFratio(
true, pOld[0].e(), pNew[0].e(),
1696 eleTrial->idx, eleTrial->q2Sav);
1697 pVeto *= PDFratio(
false, pOld[1].e(), pNew[2].e(),
1698 eleTrial->idy, eleTrial->q2Sav);
1702 if (rndmPtr->flat() > pVeto)
return false;
1708 if (eleTrial->isDip) {
1710 Particle newPhoton(22, 51, 0, 0, 0, 0, 0, 0, pPhot);
1711 Particle newPartx =
event[x];
1715 int xNew =
event.append(newPartx);
1716 int jNew =
event.append(newPhoton);
1719 partonSystemsPtr->replace(iSys, x, xNew);
1720 partonSystemsPtr->addOut(iSys, jNew);
1723 event[x].statusNeg();
1726 event[xNew].mothers(x,0);
1727 event[jNew].mothers(x,0);
1728 event[x].daughters(xNew, jNew);
1729 event[xNew].daughters(0,0);
1730 event[jNew].daughters(0,0);
1731 event[xNew].statusCode(51);
1732 event[jNew].statusCode(51);
1735 for (
int i = 0; i < (int)eleTrial->iRecoil.size(); i++) {
1736 int iDipRec = eleTrial->iRecoil[i];
1737 Vec4 pDipRec =
event[iDipRec].p();
1738 pDipRec.bstback(pOld[1]);
1739 pDipRec.bst(pNew[2]);
1741 int iDipRecNew =
event.copy(iDipRec, 52);
1743 event[iDipRecNew].p(pDipRec);
1745 partonSystemsPtr->replace(iSys, iDipRec, iDipRecNew);
1748 }
else if (eleTrial->isRF) {
1751 Particle newPhoton(22, 51, 0, 0, 0, 0, 0, 0, pPhot);
1752 Particle newParty =
event[y];
1758 jNew =
event.append(newPhoton);
1759 yNew =
event.append(newParty);
1761 yNew =
event.append(newParty);
1762 jNew =
event.append(newPhoton);
1766 partonSystemsPtr->addOut(iSys, jNew);
1767 partonSystemsPtr->replace(iSys, y, yNew);
1770 event[y].statusNeg();
1771 event[jNew].mothers(y,0);
1772 event[yNew].mothers(y,0);
1773 event[jNew].daughters(0,0);
1774 event[yNew].daughters(0,0);
1775 event[y].daughters(yNew,jNew);
1776 event[yNew].statusCode(51);
1779 vector<pair<int,int> > iRecNew;
1782 for (
int j = 0; j <
event.size(); j++)
1783 if (event[j].isFinal())
1784 for (
int k = 0; k < (int)iRec.size(); k++)
1787 int inew =
event.copy(j, 52);
1789 event[inew].p(pRec[k]);
1790 iRecNew.push_back(make_pair(iRec[k], inew));
1794 for (
int k=0; k<(int)iRecNew.size(); k++)
1795 partonSystemsPtr->replace(iSys, iRecNew[k].first, iRecNew[k].second);
1800 Particle newPhoton(22, 51, 0, 0, 0, 0, 0, 0, pPhot);
1801 Particle newPartx =
event[x];
1803 Particle newParty =
event[y];
1807 int xNew, jNew, yNew;
1809 xNew =
event.append(newPartx);
1810 jNew =
event.append(newPhoton);
1811 yNew =
event.append(newParty);
1813 yNew =
event.append(newParty);
1814 jNew =
event.append(newPhoton);
1815 xNew =
event.append(newPartx);
1819 partonSystemsPtr->replace(iSys, x, xNew);
1820 partonSystemsPtr->addOut(iSys, jNew);
1821 partonSystemsPtr->replace(iSys, y, yNew);
1824 event[x].statusNeg();
1825 event[y].statusNeg();
1828 if (eleTrial->isII) {
1829 event[xNew].mothers(event[x].mother1(), event[x].mother2());
1830 event[jNew].mothers(xNew, yNew);
1831 event[yNew].mothers(event[y].mother1(), event[y].mother2());
1832 event[x].mothers(xNew, 0);
1833 event[y].mothers(yNew, 0);
1834 event[xNew].daughters(jNew, x);
1835 event[yNew].daughters(jNew, y);
1836 event[jNew].daughters(0,0);
1837 event[xNew].status(-41);
1838 event[yNew].status(-41);
1839 event[jNew].status(43);
1843 bool founda =
false;
1844 bool foundb =
false;
1845 for (
int i = 0; i < (int)event.size(); i++) {
1847 if (event[i].daughter1() == x) {
1848 event[i].daughters(xNew, 0);
1852 if (event[i].daughter1() == y) {
1853 event[i].daughters(yNew, 0);
1856 if (founda && foundb)
break;
1861 vector<pair<int,int> > iRecNew;
1864 for (
int j=0; j<
event.size(); j++)
1865 if (event[j].isFinal())
1866 for (
int k=0; k<(int)iRec.size(); k++)
1869 int inew =
event.copy(j, 44);
1871 event[inew].p(pRec[k]);
1872 iRecNew.push_back(make_pair(iRec[k], inew));
1877 for (
int k = 0; k < (int)iRecNew.size(); k++)
1878 partonSystemsPtr->replace(iSys, iRecNew[k].first, iRecNew[k].second);
1879 partonSystemsPtr->setInA(iSys, xNew);
1880 partonSystemsPtr->setInB(iSys, yNew);
1883 BeamParticle& beam1 = *beamAPtr;
1884 BeamParticle& beam2 = *beamBPtr;
1887 if (event[xNew].pz() < 0) {
1888 printOut(__METHOD_NAME__,
"Swapped II antenna");
1892 beam1[iSys].update(xNew, event[xNew].
id(), event[xNew].e()/beam1.e());
1893 beam2[iSys].update(yNew, event[yNew].
id(), event[yNew].e()/beam2.e());
1896 if (eleTrial->isIF) {
1897 event[xNew].mothers(event[x].mother1(), event[x].mother2());
1898 event[jNew].mothers(y,xNew);
1899 event[yNew].mothers(y,0);
1900 event[x].mothers(xNew,0);
1901 event[xNew].daughters(jNew,x);
1902 event[jNew].daughters(0,0);
1903 event[yNew].daughters(0,0);
1904 event[y].daughters(jNew, yNew);
1905 event[xNew].status(-41);
1906 event[yNew].status(43);
1907 event[jNew].status(43);
1911 for (
int i=0; i<(int)event.size(); i++)
1912 if (event[i].daughter1() == x) {
1913 event[i].daughters(xNew, 0);
1918 if (eleTrial->isIA) partonSystemsPtr->setInA(iSys, xNew);
1919 else partonSystemsPtr->setInB(iSys, xNew);
1922 BeamParticle&
beam = (eleTrial->isIA ? *beamAPtr : *beamBPtr);
1923 beam[iSys].update(xNew, event[xNew].
id(), event[xNew].e()/beam.e());
1926 if (eleTrial->isFF) {
1927 event[xNew].mothers(x,0);
1928 event[jNew].mothers(x,y);
1929 event[yNew].mothers(y,0);
1930 event[x].daughters(xNew, jNew);
1931 event[y].daughters(yNew, jNew);
1932 event[xNew].daughters(0,0);
1933 event[jNew].daughters(0,0);
1934 event[yNew].daughters(0,0);
1935 event[xNew].statusCode(51);
1936 event[jNew].statusCode(51);
1937 event[yNew].statusCode(51);
1941 event.restorePtrs();
1944 double shat = (
event[partonSystemsPtr->getInA(iSys)].p() +
1945 event[partonSystemsPtr->getInB(iSys)].p()).m2Calc();
1946 partonSystemsPtr->setSHat(iSys, shat);
1948 if (verbose >= debug) {
1949 if (verbose >= superdebug) {
1951 partonSystemsPtr->list();
1953 printOut(__METHOD_NAME__,
"end --------------");
1963 void QEDemitSystem::print() {
1964 cout <<
"Printing QEDemit internal system" << endl;
1965 cout <<
"Pairing elementals" << endl;
1966 for (
int i = 0; i < (int)eleVec.size(); i++) {
1967 if (eleVec[i].isDip) {
1968 cout <<
"Dipole: x = ";
1969 cout << eleVec[i].x <<
" Recoilers: (";
1970 for (
int j = 0; j < (int)eleVec[i].iRecoil.size(); j++) {
1971 cout << eleVec[i].iRecoil[j] <<
", ";
1972 if (j == (
int)eleVec[i].iRecoil.size()-1) cout <<
")";
1975 }
else cout <<
"Antennae: x = " << eleVec[i].x <<
", y = " << eleVec[i].y;
1976 cout <<
", QQ = " << eleVec[i].QQ <<
", s = " << eleVec[i].sAnt << endl;
1978 cout <<
"Coherent elementals" << endl;
1979 for (
int i = 0; i < (int)eleMat.size(); i++)
1980 for (
int j = 0; j < i; j++)
1981 cout <<
"x = " << eleMat[i][j].x <<
", y = " << eleMat[i][j].y
1982 <<
", QQ = " << eleMat[i][j].QQ <<
", s = " << eleMat[i][j].sAnt
1994 void QEDsplitSystem::initPtr(Info* infoPtrIn, VinciaCommon* vinComPtrIn) {
1995 infoPtr = infoPtrIn;
1996 particleDataPtr = infoPtr->particleDataPtr;
1997 partonSystemsPtr = infoPtr->partonSystemsPtr;
1998 rndmPtr = infoPtr->rndmPtr;
1999 settingsPtr = infoPtr->settingsPtr;
2000 vinComPtr = vinComPtrIn;
2008 void QEDsplitSystem::init(BeamParticle* beamAPtrIn, BeamParticle* beamBPtrIn,
2010 if (!isInitPtr) printOut(__METHOD_NAME__,
"initPtr not called");
2011 verbose = verboseIn;
2012 q2Max = pow2(settingsPtr->parm(
"Vincia:mMaxGamma"));
2013 nLepton = settingsPtr->mode(
"Vincia:nGammaToLepton");
2014 nQuark = settingsPtr->mode(
"Vincia:nGammaToQuark");
2015 beamAPtr = beamAPtrIn;
2016 beamBPtr = beamBPtrIn;
2024 void QEDsplitSystem::prepare(
int iSysIn,
Event &event,
double q2CutIn,
2025 bool isBelowHadIn, vector<double> evolutionWindowsIn, AlphaEM alIn) {
2028 infoPtr->errorMsg(
"Error in "+__METHOD_NAME__+
": Not initialised.");
2031 if (verbose >= louddebug) printOut(__METHOD_NAME__,
"begin --------------");
2036 isBelowHad = isBelowHadIn;
2037 evolutionWindows = evolutionWindowsIn;
2047 for (
int i = 0; i < nLepton; i++) {
2048 ids.push_back(11 + 2*i);
2049 idWeights.push_back(1);
2053 for (
int i = 1; i <= nQuark; i++) {
2055 idWeights.push_back((i%2==0 ? 4./3. : 1./3.));
2059 for (
int i=0; i<(int)ids.size(); i++) {
2060 totIdWeight += idWeights[i];
2061 if (idWeights[i] > maxIdWeight) maxIdWeight = idWeights[i];
2066 if (verbose >= louddebug) printOut(__METHOD_NAME__,
"end --------------");
2074 void QEDsplitSystem::buildSystem(
Event &event) {
2081 vector<int> photList, chSpecList, uchSpecList;
2082 int sysSize = partonSystemsPtr->sizeAll(iSys);
2083 for (
int i = 0; i < sysSize; i++) {
2084 int iEv = partonSystemsPtr->getAll(iSys, i);
2087 if (event[iEv].isFinal()) {
2089 if (event[iEv].
id()==22) photList.push_back(iEv);
2091 if (event[iEv].isCharged()) chSpecList.push_back(iEv);
2092 else uchSpecList.push_back(iEv);
2098 if (chSpecList.empty() && uchSpecList.empty())
return;
2101 for (
int i = 0; i < (int)photList.size(); i++) {
2102 int iPhot = photList[i];
2104 if (chSpecList.empty()) {
2106 bool otherSpecAvail =
false;
2107 for (
int j = 0; j < (int)uchSpecList.size(); j++)
2108 if (uchSpecList[j] != iPhot) {otherSpecAvail =
true;
break;}
2110 if (!otherSpecAvail)
continue;
2115 iSpec = uchSpecList[rndmPtr->flat()*uchSpecList.size()];
2116 if (iSpec != iPhot)
break;
2118 eleVec.push_back(QEDsplitElemental(event, iPhot, iSpec));
2119 eleVec.back().ariWeight = 1.;
2124 vector<QEDsplitElemental> tempEleVec;
2125 for (
int j = 0; j < (int)chSpecList.size(); j++) {
2126 int iSpec = chSpecList[j];
2127 tempEleVec.push_back(QEDsplitElemental(event, iPhot, iSpec));
2128 ariNorm += 1./tempEleVec.back().m2Ant;
2131 for (
int j = 0; j < (int)tempEleVec.size(); j++)
2132 tempEleVec[j].ariWeight = 1./(tempEleVec[j].m2Ant*ariNorm);
2133 eleVec.insert(eleVec.end(), tempEleVec.begin(), tempEleVec.end());
2142 double QEDsplitSystem::generateTrialScale(
Event &event,
double q2Start) {
2145 if (hasTrial)
return q2Trial;
2148 if (eleVec.size() == 0)
return 0;
2151 q2Trial = min(q2Max, q2Start);
2154 if (q2Trial <= q2Cut)
return 0;
2157 int iEvol = evolutionWindows.size() - 1;
2158 while (q2Start <= evolutionWindows[iEvol]) iEvol--;
2159 double q2Low = evolutionWindows[iEvol];
2162 vector<double> weightVec;
2163 double totWeight(0), maxWeight(0);
2164 for (
int i = 0; i < (int)eleVec.size(); i++) {
2165 double Iz = q2Low > eleVec[i].m2Ant ? 0 : 1. - q2Low/eleVec[i].m2Ant;
2166 double w = totIdWeight*eleVec[i].ariWeight*Iz*eleVec[i].getKallen();
2167 weightVec.push_back(w);
2169 if (w > maxWeight) maxWeight = w;
2173 if (totWeight < TINY) q2Trial = 0;
2178 double alphaMax = al.alphaEM(q2Trial);
2179 q2Trial *= pow(rndmPtr->flat(), M_PI/totWeight/alphaMax);
2180 double alphaNew = al.alphaEM(q2Trial);
2181 if (rndmPtr->flat() < alphaNew/alphaMax)
break;
2186 if (q2Trial < q2Low) {
2187 if (iEvol == 0)
return 0;
2188 return generateTrialScale(event, q2Low);
2193 int i = rndmPtr->flat()*weightVec.size();
2194 if (rndmPtr->flat() < weightVec[i]/maxWeight) {
2195 eleTrial = &eleVec[i];
2202 int idIndex = rndmPtr->flat()*ids.size();
2203 idTrial = ids[idIndex];
2204 if (rndmPtr->flat() < idWeights[idIndex]/maxIdWeight)
break;
2208 zTrial = (1. - q2Low/eleTrial->m2Ant)*rndmPtr->flat();
2209 phiTrial = rndmPtr->flat()*2*M_PI;
2219 bool QEDsplitSystem::checkVeto(
Event &event) {
2222 if (verbose >= debug) printOut(__METHOD_NAME__,
"begin --------------");
2226 int iPhot = eleTrial->iPhot;
2227 int iSpec = eleTrial->iSpec;
2228 double m2Ant = eleTrial->m2Ant;
2231 vector<Vec4> pOld, pNew;
2232 pOld.push_back(event[iPhot].p());
2233 pOld.push_back(event[iSpec].p());
2236 double mFerm = particleDataPtr->m0(idTrial);
2237 double mSpec = sqrt(eleTrial->m2Spec);
2238 double sIK = m2Ant - 2*pow2(mFerm) - pow2(mSpec);
2239 double sij = q2Trial - 2*pow2(mFerm);
2240 double sjk = zTrial*m2Ant;
2241 double sik = m2Ant - sij - sjk - 2*pow2(mFerm) - pow2(mSpec);
2244 if (sik < 0)
return false;
2245 if (sij*sjk*sik - pow2(sij)*pow2(mSpec)
2246 - (pow2(sjk) + pow2(sik))*pow2(mFerm) < 0)
return false;
2249 double pVeto = ( (pow2(sik) + pow2(sjk))/m2Ant + 2.*pow2(mFerm)/q2Trial)/2.;
2250 if (rndmPtr->flat() > pVeto)
return false;
2251 vector<double> invariants;
2252 invariants.push_back(sIK);
2253 invariants.push_back(sij);
2254 invariants.push_back(sjk);
2255 vector<double> masses;
2256 masses.push_back(mFerm);
2257 masses.push_back(mFerm);
2258 masses.push_back(mSpec);
2261 if (!vinComPtr->map2to3FF(pNew, pOld, 3, invariants, phiTrial, masses))
2265 int colTag = idTrial < 10 ? 10*(
event.nextColTag()/10 + 1) + 1
2266 + rndmPtr->flat()*10 : 0;
2267 Particle partFermNew(idTrial, 51, iPhot, 0, 0, 0, colTag, 0, pNew[0], mFerm);
2268 Particle partAFermNew(-idTrial,51,iPhot, 0, 0, 0, 0, colTag, pNew[1], mFerm);
2269 Particle partSpecNew =
event[iSpec];
2270 partSpecNew.mothers(iSpec, iSpec);
2271 partSpecNew.p(pNew[2]);
2272 partSpecNew.statusCode(52);
2275 int iFermNew =
event.append(partFermNew);
2276 int iAFermNew =
event.append(partAFermNew);
2277 int iSpecNew =
event.append(partSpecNew);
2280 event[iPhot].statusNeg();
2281 event[iPhot].daughters(iFermNew, iAFermNew);
2282 event[iSpec].statusNeg();
2283 event[iSpec].daughters(iSpecNew, 0);
2286 partonSystemsPtr->replace(iSys, iPhot, iFermNew);
2287 partonSystemsPtr->addOut(iSys, iAFermNew);
2288 partonSystemsPtr->replace(iSys, iSpec, iSpecNew);
2289 event.restorePtrs();
2290 if (verbose >= debug) printOut(__METHOD_NAME__,
"end --------------");
2299 void QEDsplitSystem::print() {
2300 cout <<
"Splitting" << endl;
2301 for (
int i = 0; i < (int)eleVec.size(); i++)
2302 cout <<
"(" << eleVec[i].iPhot <<
" " << eleVec[i].iSpec <<
") "
2303 <<
"s = " << eleVec[i].m2Ant <<
" ariFac = " << eleVec[i].ariWeight
2315 void QEDconvSystem::initPtr(Info* infoPtrIn, VinciaCommon* vinComPtrIn) {
2316 infoPtr = infoPtrIn;
2317 particleDataPtr = infoPtr->particleDataPtr;
2318 partonSystemsPtr = infoPtr->partonSystemsPtr;
2319 rndmPtr = infoPtr->rndmPtr;
2320 settingsPtr = infoPtr->settingsPtr;
2321 vinComPtr = vinComPtrIn;
2328 void QEDconvSystem::init(BeamParticle* beamAPtrIn, BeamParticle* beamBPtrIn,
2332 if (!isInitPtr) printOut(__METHOD_NAME__,
"initPtr not called");
2333 verbose = verboseIn;
2338 if (!settingsPtr->flag(
"Vincia:convertGammaToQuark")) nQuark = 0;
2353 TINYPDF = pow(10, -10);
2356 beamAPtr = beamAPtrIn;
2357 beamBPtr = beamBPtrIn;
2366 void QEDconvSystem::prepare(
int iSysIn,
Event &event,
double q2CutIn,
2367 bool isBelowHadIn, vector<double> evolutionWindowsIn, AlphaEM alIn) {
2370 infoPtr->errorMsg(
"Error in "+__METHOD_NAME__+
": Not initialised.");
2373 if (verbose >= louddebug) printOut(__METHOD_NAME__,
"begin --------------");
2378 isBelowHad = isBelowHadIn;
2380 evolutionWindows = evolutionWindowsIn;
2390 if (nQuark == 0)
return;
2394 for (
int i = 1; i <= nQuark; i++) {
2397 idWeights.push_back((i%2==0 ? 4./9. : 1./9.)*Rhat[i]);
2398 idWeights.push_back((i%2==0 ? 4./9. : 1./9.)*Rhat[-i]);
2401 for (
int i = 0; i < (int)idWeights.size(); i++) {
2402 totIdWeight += idWeights[i];
2403 if (idWeights[i] > maxIdWeight) maxIdWeight = idWeights[i];
2408 if (verbose >= louddebug) printOut(__METHOD_NAME__,
"end --------------");
2416 void QEDconvSystem::buildSystem(
Event &event) {
2422 iA = partonSystemsPtr->getInA(iSys);
2423 iB = partonSystemsPtr->getInB(iSys);
2424 isAPhot =
event[iA].id() == 22;
2425 isBPhot =
event[iB].id() == 22;
2426 s = (
event[iA].p() +
event[iB].p()).m2Calc();
2434 double QEDconvSystem::generateTrialScale(
Event &event,
double q2Start) {
2437 if (hasTrial)
return q2Trial;
2440 if (!isAPhot && !isBPhot) {
return 0;}
2441 double totWeight = 1.;
2444 if (isAPhot && !isBPhot) {iPhotTrial = iA; iSpecTrial = iB;}
2445 else if (isBPhot && !isAPhot) {iPhotTrial = iB; iSpecTrial = iA;}
2447 if (rndmPtr->flat() < 0.5) {iPhotTrial = iA; iSpecTrial = iB;}
2448 else {iPhotTrial = iB; iSpecTrial = iA;}
2457 if (q2Trial <= q2Cut)
return 0;
2460 int iEvol = evolutionWindows.size() - 1;
2461 while(q2Start <= evolutionWindows[iEvol]) {iEvol--;}
2462 double q2Low = evolutionWindows[iEvol];
2465 double zPlus = shh/s;
2466 double zMin = 1 + q2Low/s;
2467 if (zPlus < zMin) {
return 0;}
2468 double Iz = log(zPlus/zMin);
2469 totWeight *= totIdWeight*Iz;
2472 if (totWeight < TINY)
return 0;
2477 double alphaMax = al.alphaEM(q2Trial);
2478 q2Trial *= pow(rndmPtr->flat(), M_PI/totWeight/alphaMax);
2479 double alphaNew = al.alphaEM(q2Trial);
2480 if (rndmPtr->flat() < alphaNew/alphaMax)
break;
2484 if (q2Trial < q2Low) {
2485 if (iEvol==0)
return 0;
2486 return generateTrialScale(event, q2Low);
2491 int idIndex = rndmPtr->flat()*ids.size();
2492 idTrial = ids[idIndex];
2493 if (rndmPtr->flat() < idWeights[idIndex]/maxIdWeight)
break;
2495 zTrial = zMin*pow(zPlus/zMin, rndmPtr->flat());
2496 phiTrial = rndmPtr->flat()*2*M_PI;
2506 bool QEDconvSystem::checkVeto(
Event &event) {
2509 if (verbose >= debug) printOut(__METHOD_NAME__,
"begin --------------");
2513 double mf2 = pow2(particleDataPtr->m0(idTrial));
2516 int idSpec =
event[iSpecTrial].id();
2519 vector<Vec4> pOld, pNew;
2520 pOld.push_back(event[iPhotTrial].p());
2521 pOld.push_back(event[iSpecTrial].p());
2526 double saj = q2Trial + 2*mf2;
2527 double sbj = (zTrial-1)*s - saj + mf2;
2528 double sab = s + saj + sbj - mf2;
2531 if (sbj < 0)
return false;
2532 if (sab*saj*sbj - mf2*sab*sab < 0)
return false;
2535 bool isPhotA = (iPhotTrial == iA) ?
true :
false;
2540 int sysSize = partonSystemsPtr->sizeAll(iSys);
2541 for (
int i=0; i<sysSize; i++) {
2542 int iEv = partonSystemsPtr->getAll(iSys, i);
2543 if (iEv < 0 || !event[iEv].isFinal())
continue;
2544 pRec.push_back(event[iEv].p());
2545 iRec.push_back(iEv);
2549 if (!vinComPtr->map2to3II(pNew, pRec, pOld, s, saj, sbj, sab,
2550 phiTrial, mf2))
return false;
2553 double eaUsed = 0, ebUsed = 0;
2554 int nSys = partonSystemsPtr->sizeSys();
2555 for (
int i=0; i<nSys; i++) {
2556 eaUsed +=
event[partonSystemsPtr->getInA(i)].e();
2557 ebUsed +=
event[partonSystemsPtr->getInB(i)].e();
2560 if ((eaUsed - pOld[0].e() + pNew[0].e()) > 0.98*sqrt(shh)/2.)
return false;
2561 if ((ebUsed - pOld[1].e() + pNew[2].e()) > 0.98*sqrt(shh)/2.)
return false;
2563 if ((ebUsed - pOld[0].e() + pNew[0].e()) > 0.98*sqrt(shh)/2.)
return false;
2564 if ((eaUsed - pOld[1].e() + pNew[2].e()) > 0.98*sqrt(shh)/2.)
return false;
2568 double pVeto = 0.5*(1. + pow2(sbj)/pow2(sab)
2569 - 2.*mf2*pow2(s)/pow2(sab)/(saj-2*mf2));
2573 double xPhotOld = pOld[0].e()/(sqrt(shh)/2.);
2574 double xPhotNew = pNew[0].e()/(sqrt(shh)/2.);
2575 double xSpecOld = pOld[1].e()/(sqrt(shh)/2.);
2576 double xSpecNew = pNew[2].e()/(sqrt(shh)/2.);
2580 double newPDFPhot = beamAPtr->xfISR(iSys, idTrial, xPhotNew, q2Trial);
2581 double oldPDFPhot = beamAPtr->xfISR(iSys, 22, xPhotOld, q2Trial);
2582 if (abs(newPDFPhot) < TINYPDF) newPDFPhot = TINYPDF;
2583 if (abs(oldPDFPhot) < TINYPDF) oldPDFPhot = TINYPDF;
2584 Rpdf *= newPDFPhot/oldPDFPhot;
2587 double newPDFSpec = beamBPtr->xfISR(iSys, idSpec, xSpecNew, q2Trial);
2588 double oldPDFSpec = beamBPtr->xfISR(iSys, idSpec, xSpecOld, q2Trial);
2589 if (abs(newPDFSpec) < TINYPDF) newPDFSpec = TINYPDF;
2590 if (abs(oldPDFSpec) < TINYPDF) oldPDFSpec = TINYPDF;
2591 Rpdf *= newPDFSpec/oldPDFSpec;
2594 double newPDFPhot = beamBPtr->xfISR(iSys, idTrial, xPhotNew, q2Trial);
2595 double oldPDFPhot = beamBPtr->xfISR(iSys, 22, xPhotOld, q2Trial);
2596 if (abs(newPDFPhot) < TINYPDF) newPDFPhot = TINYPDF;
2597 if (abs(oldPDFPhot) < TINYPDF) oldPDFPhot = TINYPDF;
2598 Rpdf *= newPDFPhot/oldPDFPhot;
2601 double newPDFSpec = beamAPtr->xfISR(iSys, idSpec, xSpecNew, q2Trial);
2602 double oldPDFSpec = beamAPtr->xfISR(iSys, idSpec, xSpecOld, q2Trial);
2603 if (abs(newPDFSpec) < TINYPDF) newPDFSpec = TINYPDF;
2604 if (abs(oldPDFSpec) < TINYPDF) oldPDFSpec = TINYPDF;
2605 Rpdf *= newPDFSpec/oldPDFSpec;
2608 if (Rpdf > Rhat[idTrial]) {
2610 ss <<
"Incorrect pdf overestimate " <<
"id = " << idTrial <<
"ratio = "
2611 << Rpdf/Rhat[idTrial];
2612 printOut(__METHOD_NAME__, ss.str());
2616 pVeto *= (Rpdf/Rhat[idTrial]);
2619 if (rndmPtr->flat() > pVeto)
return false;
2622 Particle partSpecNew =
event[iSpecTrial];
2623 partSpecNew.p(pNew[2]);
2624 partSpecNew.statusCode(41);
2627 int colTag = 10*(
event.nextColTag()/10 + 1) + 1 + rndmPtr->flat()*10;
2628 Particle partBeamNew (idTrial, -41, 0, 0, 0, 0, idTrial > 0 ?
2629 colTag : 0, idTrial > 0 ? 0 : colTag, pNew[0]);
2630 Particle partFinalNew (idTrial, 43, 0, 0, 0, 0, idTrial > 0 ?
2631 colTag : 0, idTrial > 0 ? 0 : colTag, pNew[1], sqrt(mf2));
2632 int iBeamNew =
event.append(partBeamNew);
2633 int iFinalNew =
event.append(partFinalNew);
2634 int iSpecNew =
event.append(partSpecNew);
2635 event[iPhotTrial].statusNeg();
2636 event[iSpecTrial].statusNeg();
2637 event[iBeamNew].mothers(event[iPhotTrial].mother1(),
2638 event[iPhotTrial].mother2());
2639 event[iFinalNew].mothers(iBeamNew, 0);
2640 event[iSpecNew].mothers(event[iSpecTrial].mother1(),
2641 event[iSpecTrial].mother2());
2642 event[iPhotTrial].mothers(iBeamNew, 0);
2643 event[iSpecTrial].mothers(iSpecNew, 0);
2644 event[iBeamNew].daughters(iFinalNew, iPhotTrial);
2645 event[iFinalNew].daughters(0,0);
2646 event[iSpecNew].daughters(iSpecTrial);
2650 bool foundPhot =
false;
2651 bool foundSpec =
false;
2652 for (
int i = 0; i < (int)event.size(); i++) {
2654 if (event[i].daughter1() == iPhotTrial) {
2655 event[i].daughters(iBeamNew, 0);
2659 if (event[i].daughter1() == iSpecTrial) {
2660 event[i].daughters(iSpecNew, 0);
2663 if (foundPhot && foundSpec)
break;
2668 vector<pair<int,int> > iRecNew;
2671 for (
int j = 0; j <
event.size(); j++)
2672 if (event[j].isFinal())
2673 for (
int k = 0; k < (int)iRec.size(); k++)
2676 int inew =
event.copy(j,44);
2677 event[inew].p(pRec[k]);
2678 iRecNew.push_back(make_pair(iRec[k], inew));
2682 partonSystemsPtr->replace(iSys, iPhotTrial, iBeamNew);
2683 partonSystemsPtr->addOut(iSys, iFinalNew);
2684 partonSystemsPtr->replace(iSys, iSpecTrial, iSpecNew);
2687 for (
int k=0; k<(int)iRecNew.size(); k++) {
2688 partonSystemsPtr->replace(iSys, iRecNew[k].first, iRecNew[k].second);
2691 partonSystemsPtr->setInA(iSys, iBeamNew);
2692 partonSystemsPtr->setInB(iSys, iSpecNew);
2694 partonSystemsPtr->setInA(iSys, iSpecNew);
2695 partonSystemsPtr->setInB(iSys, iBeamNew);
2697 double shat = (
event[partonSystemsPtr->getInA(iSys)].p() +
2698 event[partonSystemsPtr->getInB(iSys)].p()).m2Calc();
2699 partonSystemsPtr->setSHat(iSys, shat);
2702 BeamParticle& beam1 = *beamAPtr;
2703 BeamParticle& beam2 = *beamBPtr;
2705 beam1[iSys].update(iBeamNew, event[iBeamNew].
id(),
2706 event[iBeamNew].e()/beam1.e());
2707 beam2[iSys].update(iSpecNew, event[iSpecNew].
id(),
2708 event[iSpecNew].e()/beam2.e());
2710 beam1[iSys].update(iSpecNew, event[iSpecNew].
id(),
2711 event[iSpecNew].e()/beam1.e());
2712 beam2[iSys].update(iBeamNew, event[iBeamNew].
id(),
2713 event[iBeamNew].e()/beam2.e());
2715 if (verbose >= debug) printOut(__METHOD_NAME__,
"end --------------");
2724 void QEDconvSystem::print() {
2725 cout <<
"Conversion" << endl;
2726 cout <<
"s = " << s << endl;
2737 void QEDShower::initPtr(Info* infoPtrIn, VinciaCommon* vinComPtrIn) {
2738 infoPtr = infoPtrIn;
2739 particleDataPtr = infoPtr->particleDataPtr;
2740 partonSystemsPtr = infoPtr->partonSystemsPtr;
2741 rndmPtr = infoPtr->rndmPtr;
2742 settingsPtr = infoPtr->settingsPtr;
2743 vinComPtr = vinComPtrIn;
2751 void QEDShower::init(BeamParticle* beamAPtrIn, BeamParticle* beamBPtrIn) {
2754 verbose = settingsPtr->mode(
"Vincia:verbose");
2755 double alpEM0Vincia = settingsPtr->parm(
"Vincia:alphaEM0");
2756 double alpEMmzVincia = settingsPtr->parm(
"Vincia:alphaEMmz");
2757 double alpEM0Pythia = settingsPtr->parm(
"StandardModel:alphaEM0");
2758 double alpEMmzPythia = settingsPtr->parm(
"StandardModel:alphaEMmZ");
2759 int alphaEMorder = settingsPtr->mode(
"Vincia:alphaEMorder");
2762 settingsPtr->parm(
"StandardModel:alphaEM0", alpEM0Vincia);
2763 settingsPtr->parm(
"StandardModel:alphaEMmZ", alpEMmzVincia);
2764 al.init(alphaEMorder, settingsPtr);
2765 settingsPtr->parm(
"StandardModel:alphaEM0", alpEM0Pythia);
2766 settingsPtr->parm(
"StandardModel:alphaEMmz", alpEMmzPythia);
2769 doQED = settingsPtr->flag(
"Vincia:doQED");
2771 nGammaToLepton = settingsPtr->mode(
"Vincia:nGammaToLepton");
2772 nGammaToQuark = settingsPtr->mode(
"Vincia:nGammaToQuark") >= 1;
2773 doConvertGamma = settingsPtr->flag(
"Vincia:convertGammaToQuark");
2774 doConvertQuark = settingsPtr->flag(
"Vincia:convertQuarkToGamma");
2777 q2minColouredSav = pow2(settingsPtr->parm(
"Vincia:QminChgQ"));
2778 q2minSav = pow2(settingsPtr->parm(
"Vincia:QminChgL"));
2781 beamAPtr = beamAPtrIn;
2782 beamBPtr = beamBPtrIn;
2791 void QEDShower::prepare(
int iSysIn,
Event &event,
bool isBelowHad) {
2795 if (verbose >= debug) {
2796 printOut(__METHOD_NAME__,
"begin --------------");
2797 if (verbose >= superdebug)
event.list();
2801 double q2cut = (isBelowHad) ? q2minSav : q2minColouredSav;
2805 if (iSysIn == 0 || iSysIn == -1) {
2808 double q2BiggestEver = infoPtr->s();
2809 double q2Window = q2cut;
2810 double winStep = 100.0;
2811 evolutionWindows.clear();
2813 evolutionWindows.push_back(q2Window);
2814 q2Window *= winStep;
2815 }
while(q2Window < q2BiggestEver);
2819 bool isResDecay =
false;
2821 if (partonSystemsPtr->hasInRes(iSysIn) ||
2822 (partonSystemsPtr->getInA(iSysIn)==0 &&
2823 partonSystemsPtr->getInB(iSysIn)==0) ) isResDecay =
true;
2827 if ( iSysIn <= 0 || isResDecay || isBelowHad ) {
2829 emitSystems.clear();
2830 splitSystems.clear();
2831 convSystems.clear();
2839 iSysIn = partonSystemsPtr->addSys();
2842 for (
int i = 1; i <
event.size(); ++i) {
2843 if (!event[i].isFinal())
continue;
2844 partonSystemsPtr->addOut(iSysIn, i);
2849 iSystems.push_back(iSysIn);
2850 emitSystems.push_back(QEDemitSystem());
2851 splitSystems.push_back(QEDsplitSystem());
2852 convSystems.push_back(QEDconvSystem());
2855 emitSystems.back().initPtr(infoPtr, vinComPtr);
2856 splitSystems.back().initPtr(infoPtr, vinComPtr);
2857 convSystems.back().initPtr(infoPtr, vinComPtr);
2861 emitSystems.back().init(beamAPtr, beamBPtr,verbose);
2862 splitSystems.back().init(beamAPtr, beamBPtr,verbose);
2863 convSystems.back().init(beamAPtr, beamBPtr,verbose);
2866 emitSystems.back().prepare(iSysIn, event, q2cut, isBelowHad,
2867 evolutionWindows, al);
2868 splitSystems.back().prepare(iSysIn, event, q2cut, isBelowHad,
2869 evolutionWindows, al);
2870 convSystems.back().prepare(iSysIn, event, q2cut, isBelowHad,
2871 evolutionWindows, al);
2874 if(verbose >= debug) printOut(__METHOD_NAME__,
"end --------------");
2882 void QEDShower::update(
Event &event,
int iSys) {
2885 if (verbose >= debug) printOut(__METHOD_NAME__,
"begin --------------");
2886 for (
int i = 0; i < (int)iSystems.size(); i++) {
2887 if (iSystems[i] == iSys) {
2889 emitSystems[i].buildSystem(event);
2890 splitSystems[i].buildSystem(event);
2891 convSystems[i].buildSystem(event);
2895 if (verbose >= debug) {
2896 if (verbose >= superdebug)
event.list();
2897 printOut(__METHOD_NAME__,
"end --------------");
2905 double QEDShower::generateTrialScale(
Event &event,
double q2Start) {
2909 isTrialEmit =
false;
2910 isTrialSplit =
false;
2911 isTrialConv =
false;
2912 if (!doQED)
return 0.0;
2913 if (verbose >= louddebug) {
2914 printOut(__METHOD_NAME__,
"begin --------------");
2915 if (verbose >= superdebug)
2916 cout <<
" QEDShower::generateTrialScale() q2Start = " << q2Start
2917 <<
" doEmit = " << bool2str(doEmission)
2918 <<
" nSplitGamToLep = " << num2str(nGammaToLepton)
2919 <<
" nSplitGamToQuark = " << num2str(nGammaToQuark)
2920 <<
" doConv = " << bool2str(doConvertGamma) << endl;
2925 for (
int i = 0; i < (int)emitSystems.size(); i++) {
2926 double q2TrialEmitNew =
2927 emitSystems[i].generateTrialScale(event, q2Start);
2928 if (q2TrialEmitNew > q2Trial) {
2929 q2Trial = q2TrialEmitNew;
2930 iSysTrial = iSystems[i];
2933 isTrialSplit =
false;
2934 isTrialConv =
false;
2940 if (nGammaToLepton + nGammaToQuark > 0) {
2941 for (
int i = 0; i < (int)splitSystems.size(); i++) {
2942 double q2TrialSplitNew =
2943 splitSystems[i].generateTrialScale(event, q2Start);
2944 if (q2TrialSplitNew > q2Trial) {
2945 q2Trial = q2TrialSplitNew;
2946 iSysTrial = iSystems[i];
2948 isTrialEmit =
false;
2949 isTrialSplit =
true;
2950 isTrialConv =
false;
2956 if (doConvertGamma) {
2957 for (
int i = 0; i < (int)convSystems.size(); i++) {
2958 double q2TrialConvNew =
2959 convSystems[i].generateTrialScale(event, q2Start);
2960 if (q2TrialConvNew > q2Trial) {
2961 q2Trial = q2TrialConvNew;
2962 iSysTrial = iSystems[i];
2964 isTrialEmit =
false;
2965 isTrialSplit =
false;
2970 if (verbose >= louddebug) printOut(__METHOD_NAME__,
"end --------------");
2979 bool QEDShower::checkVeto(
Event &event) {
2980 if (verbose >= debug) printOut(__METHOD_NAME__,
"begin --------------");
2981 bool doVeto =
false;
2982 if (isTrialEmit) doVeto = emitSystems[iSysIndexTrial].checkVeto(event);
2983 if (isTrialSplit) doVeto = splitSystems[iSysIndexTrial].checkVeto(event);
2984 if (isTrialConv) doVeto = convSystems[iSysIndexTrial].checkVeto(event);
2985 if (verbose >= debug) printOut(__METHOD_NAME__,
"end --------------");