8 #include "Pythia8/VinciaWeights.h"
20 const double VinciaWeights::TINYANT = 1.0e-10;
21 const double VinciaWeights::PACCEPTVARMAX = 0.99;
22 const double VinciaWeights::MINVARWEIGHT = 0.01;
28 bool VinciaWeights::initPtr(Info* infoPtrIn,
29 VinciaCommon* vinComPtrIn) {
31 settingsPtr = infoPtr->settingsPtr;
32 vinComPtr = vinComPtrIn;
41 void VinciaWeights::init() {
45 printOut(
"VinciaWeights::init",
"Error! pointers not initialized");
48 verbose = settingsPtr->mode(
"Vincia:verbose");
50 uncertaintyBands =
false;
52 nWeightsSav = (uncertaintyBands ? 1+varLabels.size() : 1);
55 allKeywords.clear(); allKeywords.resize(0);
56 string ffKeys[5] = {
":",
":qqemit:",
":qgemit:",
":ggemit:",
":gxsplit:" };
57 string ifKeys[8] = {
":",
":qqemit:",
":gqemit:",
":ggemit:",
":ggemit:",
58 ":qxsplit:",
":gxconv:",
":xgsplit:" };
59 string iiKeys[6] = {
":",
":qqemit:",
":gqemit:",
":ggemit:",
":qxsplit:",
61 for (
int i = 0; i < 5; i++) allKeywords.push_back(
"ff"+ffKeys[i]+
"murfac");
62 for (
int i = 0; i < 5; i++) allKeywords.push_back(
"ff"+ffKeys[i]+
"cns");
63 for (
int i = 0; i < 8; i++) allKeywords.push_back(
"if"+ifKeys[i]+
"murfac");
64 for (
int i = 0; i < 8; i++) allKeywords.push_back(
"if"+ifKeys[i]+
"cns");
65 for (
int i = 0; i < 6; i++) allKeywords.push_back(
"ii"+iiKeys[i]+
"murfac");
66 for (
int i = 0; i < 6; i++) allKeywords.push_back(
"ii"+iiKeys[i]+
"cns");
70 iAntToKeyFSR[iQQemitFF] =
"qqemit";
71 iAntToKeyFSR[iQGemitFF] =
"qgemit";
72 iAntToKeyFSR[iGQemitFF] =
"qgemit";
73 iAntToKeyFSR[iGGemitFF] =
"ggemit";
74 iAntToKeyFSR[iGXsplitFF] =
"gxsplit";
76 iAntToKeyISR[iQQemitII] =
"qqemit";
77 iAntToKeyISR[iGQemitII] =
"gqemit";
78 iAntToKeyISR[iGGemitII] =
"ggemit";
79 iAntToKeyISR[iQXsplitII] =
"qxsplit";
80 iAntToKeyISR[iGXconvII] =
"gxconv";
81 iAntToKeyISR[iQQemitIF] =
"qqemit";
82 iAntToKeyISR[iQGemitIF] =
"qgemit";
83 iAntToKeyISR[iGQemitIF] =
"gqemit";
84 iAntToKeyISR[iGGemitIF] =
"ggemit";
85 iAntToKeyISR[iQXsplitIF] =
"qxsplit";
86 iAntToKeyISR[iGXconvIF] =
"gxconv";
87 iAntToKeyISR[iXGsplitIF] =
"xgsplit";
90 for (
int i = 0; i < (int)varLabels.size(); i++) {
91 int strBegin = varLabels[i].find_first_not_of(
" ");
92 if ((i == 0) && (varLabels[i].find(
"{") != string::npos)) strBegin += 1;
93 int strEnd = varLabels[i].find_last_not_of(
" ");
94 if ((i == (
int)varLabels.size()-1) && (varLabels[i].find(
"}") !=
95 string::npos)) strEnd -= 1;
96 int strRange = strEnd - strBegin + 1;
97 varLabels[i] = toLower(varLabels[i].substr(strBegin, strRange));
101 varKeys.clear(); varKeys.resize(varLabels.size());
102 varVals.clear(); varVals.resize(varLabels.size());
103 for (
int i = 0; i < (int)varLabels.size(); i++) {
104 varKeys[i].clear(); varKeys[i].resize(0);
105 varVals[i].clear(); varVals[i].resize(0);
106 string var = varLabels[i];
107 int iEndName = var.find(
" ", 0);
108 string varName = var.substr(0, iEndName);
109 string left = var.substr(iEndName, var.length());
110 left = left.substr(left.find_first_not_of(
" "), left.length());
111 varLabels[i] = varName;
112 while (left.length() > 1) {
113 int iEnd = left.find(
"=", 0);
114 int iAlt = left.find(
" ", 0);
115 if ( (iAlt < iEnd) && (iAlt > 0) ) iEnd = iAlt;
116 string key = left.substr(0, iEnd);
117 if (1+key.find_last_not_of(
" ") < key.length())
118 key = key.substr(0, 1+key.find_last_not_of(
" "));
119 varKeys[i].push_back(key);
120 string val = left.substr(iEnd+1, left.length());
121 val = val.substr(val.find_first_not_of(
" "), val.length());
122 val = val.substr(0, val.find_first_of(
" "));
123 varVals[i].push_back(atof(val.c_str()));
124 left = left.substr(iEnd+1, left.length());
125 if (left.find_first_of(
" ") >= left.length())
break;
126 left = left.substr(left.find_first_of(
" "), left.length());
127 if (left.find_first_not_of(
" ") >= left.length())
break;
128 left = left.substr(left.find_first_not_of(
" "), left.length());
132 if (uncertaintyBands && (verbose >= 4)) {
133 printOut(
"VinciaWeights",
"List of variations, keywords and values:");
134 for (
int i = 0; i < (int)varLabels.size(); i++) {
135 cout <<
" " << varLabels[i] <<
" : ";
136 for (
int j=0; j<(int)varVals[i].size(); j++) {
137 cout <<
" " << varKeys[i][j] <<
" -> " << varVals[i][j];
138 if (j < (
int)varVals[i].size() - 1) cout <<
",";
145 if (uncertaintyBands)
146 for (
int i = 0; i < (int)varKeys.size(); i++)
147 for (
int j = 0; j < (int)varKeys[i].size(); j++) {
149 bool foundValidKey =
false;
150 for (
int k = 0; k < (int)allKeywords.size(); k++)
151 if (allKeywords[k] == varKeys[i][j]) {
152 foundValidKey =
true;
156 printOut(
"VinciaWeights",
"Error! Unknown key " +
157 varKeys[i][j] +
" found, please check!");
164 weightsSav.resize(nWeightsSav);
165 weightsOld.resize(nWeightsSav);
166 weightsMax.resize(nWeightsSav);
167 weightsMin.resize(nWeightsSav);
168 weightSum.resize(nWeightsSav);
169 weightSum2.resize(nWeightsSav);
170 contribSum.resize(nWeightsSav);
171 contribSum2.resize(nWeightsSav);
177 nNonunityInitialWeight = 0;
178 nNegativeInitialWeight = 0;
179 nNonunityWeightNow = 0;
180 nNegativeWeightNow = 0;
181 nNonunityInitialWeightNow = 0;
182 nNegativeInitialWeightNow = 0;
187 for (
int iWeight=0; iWeight<nWeightsSav; iWeight++) {
188 weightsSav[iWeight] = 1.0;
189 weightsOld[iWeight] = 0.0;
190 weightsMax[iWeight] = 0.0;
191 weightsMin[iWeight] = 1.0e10;
192 weightSum[iWeight] = 0.0;
193 weightSum2[iWeight] = 0.0;
194 contribSum[iWeight] = 0.0;
195 contribSum2[iWeight] = 0.0;
204 void VinciaWeights::resetWeights(
int nAccepted) {
206 for (
int iWeight = 0; iWeight < nWeightsSav; iWeight++) {
207 weightsSav[iWeight] = 1.0;
208 weightsOld[iWeight] = 0.0;
218 if (nAccepted < nTotWeights) {
220 nNonunityWeight -= nNonunityWeightNow;
221 nNegativeWeight -= nNegativeWeightNow;
222 nNonunityInitialWeight -= nNonunityInitialWeightNow;
223 nNegativeInitialWeight -= nNegativeInitialWeightNow;
225 for (
int iWeight = 0; iWeight < nWeightsSav; iWeight++) {
226 weightSum[iWeight] -= contribSum[iWeight];
227 weightSum2[iWeight] -= contribSum2[iWeight];
230 nNonunityWeightNow = 0;
231 nNegativeWeightNow = 0;
232 nNonunityInitialWeightNow = 0;
233 nNegativeInitialWeightNow = 0;
235 for (
int iWeight = 0; iWeight<nWeightsSav; iWeight++) {
236 contribSum[iWeight] = 0.0;
237 contribSum2[iWeight] = 0.0;
246 void VinciaWeights::scaleWeightAll(
double scaleFacIn) {
247 for (
int iWeight=0; iWeight<nWeightsSav; iWeight++)
248 weightsSav[iWeight] *= scaleFacIn;
251 void VinciaWeights::scaleWeight(
double scaleFacIn,
int iWeightIn) {
252 if (existsWeight(iWeightIn)) weightsSav[iWeightIn] *= scaleFacIn;
255 void VinciaWeights::scaleWeightVar(vector<double> pAccept,
bool accept,
257 if (!uncertaintyBands)
return;
258 if (nWeightsSav <= 1)
return;
261 if (accept) scaleWeightVarAccept(pAccept);
262 else scaleWeightVarReject(pAccept);
265 void VinciaWeights::scaleWeightVarAccept(vector<double> pAccept) {
266 for (
int iWeight = 1; iWeight<nWeightsSav; iWeight++) {
267 double pAcceptVar = pAccept[iWeight];
268 if (pAcceptVar > PACCEPTVARMAX) pAcceptVar = PACCEPTVARMAX;
269 scaleWeight( pAcceptVar/pAccept[0], iWeight );
273 void VinciaWeights::scaleWeightVarReject(vector<double> pAccept) {
274 for (
int iWeight = 1; iWeight<nWeightsSav; iWeight++) {
275 double pAcceptVar = pAccept[iWeight];
276 if (pAcceptVar > PACCEPTVARMAX) pAcceptVar = PACCEPTVARMAX;
277 double reWeight = (1.0-pAcceptVar)/(1.0-pAccept[0]);
278 if (reWeight < MINVARWEIGHT) reWeight = MINVARWEIGHT;
279 scaleWeight( reWeight, iWeight );
283 void VinciaWeights::scaleWeightEnhanceAccept(
double enhanceFac) {
284 if (enhanceFac == 1.0)
return;
285 else scaleWeightAll(1./enhanceFac);
288 void VinciaWeights::scaleWeightEnhanceReject(
double pAcceptUnenhanced,
290 if (enhanceFac == 1.0)
return;
291 if (enhanceFac > 1.0) {
293 (1. - pAcceptUnenhanced/enhanceFac)/(1. - pAcceptUnenhanced);
294 scaleWeightAll(rRej);
297 (1. - pAcceptUnenhanced)/(1. - enhanceFac*pAcceptUnenhanced);
298 scaleWeightAll(rRej);
306 int VinciaWeights::doVarNow(
string keyIn,
int iAntPhys,
string type) {
309 string asKey =
":murfac", nsKey =
":cns";
310 if (type + asKey == keyIn)
return 1;
311 if (type + nsKey == keyIn)
return 2;
313 map<int,string> keyCvt = (type ==
"ff" ? iAntToKeyFSR : iAntToKeyISR);
314 if (type +
":" + keyCvt[iAntPhys] + asKey == keyIn)
return 1;
315 if (type +
":" + keyCvt[iAntPhys] + nsKey == keyIn)
return 2;
324 void VinciaWeights::doWeighting() {
329 inW = infoPtr->weight();
332 if ( (abs(inW-1.0) > TINY) || (inW < 0.0) ) {
334 if (nReportedWeight <= nReportWeight) {
336 if (nReportedWeight == nReportWeight) isLast =
true;
338 string printMessage =
"Nonunity initial weight occurred, w = ";
341 printMessage =
"Negative initial weight occurred, w = ";
342 nNegativeInitialWeight++;
343 nNegativeInitialWeightNow++;
345 nNonunityInitialWeight++;
346 nNonunityInitialWeightNow++;
349 if ((report && verbose >= 3) || verbose >= 4)
350 printOut(
"VinciaWeights", printMessage + num2str(inW) + (isLast ?
351 ": further output suppressed" :
""));
357 double w0 = inW*weightsSav[0];
358 double wMC0 = weightsSav[0];
359 double wOld = weightsOld[0];
360 weightSum[0] += (w0 - wOld);
361 weightSum2[0] += (pow2(w0) - pow2(wOld));
363 contribSum[0] += (w0 - wOld);
364 contribSum2[0] += (pow2(w0) - pow2(wOld));
373 bool foundWeightToReport =
false;
374 if (abs(wMC0-1.0) > TINY) {
376 if ( wOld < TINY || (abs(wOld) > TINY && (abs(wOld-w0) > TINY)) ) {
378 foundWeightToReport =
true;
381 nNonunityWeightNow++;
384 if (wMC0 < 0.0 && wOld >= 0.0) {
386 foundWeightToReport =
true;
389 nNegativeWeightNow++;
393 if ( foundWeightToReport && (nReportedWeight <= nReportWeight) ) {
395 if (nReportedWeight == nReportWeight) isLast =
true;
398 if ((report && verbose >= 3) || verbose >= 4) {
399 string printMessage = (wMC0 > 0.0 ?
"Nonunity MC reweight occurred, w = "
400 :
"Negative MC reweight occurred, w = ");
401 printOut(
"VinciaWeights", printMessage + num2str(w0) + (isLast ?
402 ": further output suppressed" :
""));
406 weightsMax[0] = max(weightsMax[0], w0);
407 weightsMin[0] = min(weightsMin[0], w0);
413 if (nWeightsSav > 1) {
414 for (
int iWeight = 1; iWeight < nWeightsSav; iWeight++) {
415 double wVar = inW*weightsSav[iWeight];
416 double wVarOld = weightsOld[iWeight];
418 weightSum[iWeight] += (wVar - wVarOld);
419 weightSum2[iWeight] += (pow2(wVar) - pow2(wVarOld));
421 contribSum[iWeight] += (wVar - wVarOld);
422 contribSum2[iWeight] += (pow2(wVar) - pow2(wVarOld));
424 weightsMax[iWeight] = max(weightsMax[iWeight], wVar);
425 weightsMin[iWeight] = min(weightsMin[iWeight], wVar);
427 weightsOld[iWeight] = wVar;