StRoot  1
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
DireWeightContainer.cc
1 // DireWeightContainer.cc is a part of the PYTHIA event generator.
2 // Copyright (C) 2020 Stefan Prestel, Torbjorn Sjostrand.
3 // PYTHIA is licenced under the GNU GPL v2 or later, see COPYING for details.
4 // Please respect the MCnet Guidelines, see GUIDELINES for details.
5 
6 // Function definitions (not found in the header) for the
7 // DireWeightContainer class.
8 
9 #include "Pythia8/DireWeightContainer.h"
10 #include "Pythia8/DireSpace.h"
11 #include "Pythia8/DireTimes.h"
12 
13 namespace Pythia8 {
14 
15 //==========================================================================
16 
17 const double DireWeightContainer::LARGEWT = 2e0;
18 
19 // Container for all shower weights, including handling.
20 
21 void DireWeightContainer::setup() {
22 
23  // Clear everything.
24  init();
25  enhanceFactors.clear();
26 
27  // Initialize MG5 MEs interface.
28  card = settingsPtr->word("Dire:MG5card");
29  string mePlugin = settingsPtr->word("Dire:MEplugin");
30  if (mePlugin.size() > 0) {
31  if (!hasMEs) {
32  matrixElements = ShowerMEsPlugin("libpythia8mg5" + mePlugin + ".so");
33  }
34  hasMEs = matrixElements.initDire(infoPtr,card);
35  }
36 
37  // Initialize additional user-defined enhancements of splitting kernel
38  // overestimates.
39  //int sizeNames = 48;
40  int sizeNames = 100;
41  const char* names[] = {
42  // QCD FSR
43  "Dire_fsr_qcd_1->1&21",
44  "Dire_fsr_qcd_1->21&1",
45  "Dire_fsr_qcd_21->21&21a",
46  "Dire_fsr_qcd_21->21&21b",
47  "Dire_fsr_qcd_21->1&1a",
48  "Dire_fsr_qcd_21->1&1b",
49  "Dire_fsr_qcd_1->2&1&2",
50  "Dire_fsr_qcd_1->1&1&1",
51  "Dire_fsr_qcd_1->1&21_notPartial",
52  "Dire_fsr_qcd_21->21&21_notPartial",
53  "Dire_fsr_qcd_21->1&1_notPartial",
54  "Dire_fsr_qcd_1->1&21&21",
55  "Dire_fsr_qcd_1->1&d&dbar",
56  "Dire_fsr_qcd_1->1&dbar&d",
57  "Dire_fsr_qcd_1->1&u&ubar",
58  "Dire_fsr_qcd_1->1&ubar&u",
59  "Dire_fsr_qcd_1->1&s&sbar",
60  "Dire_fsr_qcd_1->1&sbar&s",
61  "Dire_fsr_qcd_1->1&c&cbar",
62  "Dire_fsr_qcd_1->1&cbar&c",
63  "Dire_fsr_qcd_1->1&b&bbar",
64  "Dire_fsr_qcd_1->1&bbar&b",
65  "Dire_fsr_qcd_21->21&21&21",
66  "Dire_fsr_qcd_21->21&d&dbar",
67  "Dire_fsr_qcd_21->21&dbar&d",
68  "Dire_fsr_qcd_21->21&u&ubar",
69  "Dire_fsr_qcd_21->21&ubar&u",
70  "Dire_fsr_qcd_21->21&s&sbar",
71  "Dire_fsr_qcd_21->21&sbar&s",
72  "Dire_fsr_qcd_21->21&c&cbar",
73  "Dire_fsr_qcd_21->21&cbar&c",
74  "Dire_fsr_qcd_21->21&b&bbar",
75  "Dire_fsr_qcd_21->21&bbar&b",
76  // QCD ISR
77  "Dire_isr_qcd_1->1&21",
78  "Dire_isr_qcd_21->1&1",
79  "Dire_isr_qcd_21->21&21a",
80  "Dire_isr_qcd_21->21&21b",
81  "Dire_isr_qcd_1->21&1",
82  "Dire_isr_qcd_1->2&1&2",
83  "Dire_isr_qcd_1->1&1&1",
84  // QED FSR
85  "Dire_fsr_qed_1->1&22",
86  "Dire_fsr_qed_1->22&1",
87  "Dire_fsr_qed_11->11&22",
88  "Dire_fsr_qed_11->22&11",
89  "Dire_fsr_qed_22->1&1a",
90  "Dire_fsr_qed_22->1&1b",
91  "Dire_fsr_qed_22->2&2a",
92  "Dire_fsr_qed_22->2&2b",
93  "Dire_fsr_qed_22->3&3a",
94  "Dire_fsr_qed_22->3&3b",
95  "Dire_fsr_qed_22->4&4a",
96  "Dire_fsr_qed_22->4&4b",
97  "Dire_fsr_qed_22->5&5a",
98  "Dire_fsr_qed_22->5&5b",
99  "Dire_fsr_qed_22->11&11a",
100  "Dire_fsr_qed_22->11&11b",
101  "Dire_fsr_qed_22->13&13a",
102  "Dire_fsr_qed_22->13&13b",
103  "Dire_fsr_qed_22->15&15a",
104  "Dire_fsr_qed_22->15&15b",
105  // QED ISR
106  "Dire_isr_qed_1->1&22",
107  "Dire_isr_qed_1->22&1",
108  "Dire_isr_qed_22->1&1",
109  "Dire_isr_qed_11->11&22",
110  "Dire_isr_qed_11->22&11",
111  "Dire_isr_qed_22->11&11",
112  // EW FSR
113  "Dire_fsr_ew_1->1&23",
114  "Dire_fsr_ew_1->23&1",
115  "Dire_fsr_ew_23->1&1a",
116  "Dire_fsr_ew_23->1&1b",
117  "Dire_fsr_ew_24->1&1a",
118  "Dire_fsr_ew_24->1&1b",
119  // New U(1) FSR
120  "Dire_fsr_u1new_1->1&22",
121  "Dire_fsr_u1new_1->22&1",
122  "Dire_fsr_u1new_11->11&22",
123  "Dire_fsr_u1new_11->22&11",
124  "Dire_fsr_u1new_22->1&1a",
125  "Dire_fsr_u1new_22->1&1b",
126  "Dire_fsr_u1new_22->2&2a",
127  "Dire_fsr_u1new_22->2&2b",
128  "Dire_fsr_u1new_22->3&3a",
129  "Dire_fsr_u1new_22->3&3b",
130  "Dire_fsr_u1new_22->4&4a",
131  "Dire_fsr_u1new_22->4&4b",
132  "Dire_fsr_u1new_22->5&5a",
133  "Dire_fsr_u1new_22->5&5b",
134  "Dire_fsr_u1new_22->11&11a",
135  "Dire_fsr_u1new_22->11&11b",
136  "Dire_fsr_u1new_22->13&13a",
137  "Dire_fsr_u1new_22->13&13b",
138  "Dire_fsr_u1new_22->15&15a",
139  "Dire_fsr_u1new_22->15&15b",
140  "Dire_fsr_u1new_22->211&211a",
141  "Dire_fsr_u1new_22->211&211b",
142  // New U(1) ISR
143  "Dire_isr_u1new_1->1&22",
144  "Dire_isr_u1new_1->22&1",
145  "Dire_isr_u1new_22->1&1",
146  "Dire_isr_u1new_11->11&22",
147  "Dire_isr_u1new_11->22&11",
148  "Dire_isr_u1new_22->11&11"
149  };
150 
151  for (int i=0; i < sizeNames; ++i) {
152  if (settingsPtr->parm("Enhance:"+string(names[i])) > 1.0) {
153  enhanceFactors.insert(
154  make_pair( string(names[i]),
155  settingsPtr->parm("Enhance:"+string(names[i]))) );
156  }
157  }
158 
159  string vkey = "base";
160  rejectWeight.insert( make_pair(vkey, map<ulong, DirePSWeight>() ));
161  acceptWeight.insert( make_pair(vkey, map<ulong, DirePSWeight>() ));
162  showerWeight.insert( make_pair(vkey, 1.) );
163  weightNames.push_back( vkey );
164 
165  bool doVar = settingsPtr->flag("Variations:doVariations");
166  if ( doVar ) {
167  vector<string> group;
168  // Down-variations of renormalization scale.
169  if (settingsPtr->parm("Variations:muRisrDown") != 1.) {
170  bookWeightVar("Variations:muRisrDown");
171  group.push_back("Variations:muRisrDown");
172  }
173  if (settingsPtr->parm("Variations:muRfsrDown") != 1.) {
174  bookWeightVar("Variations:muRfsrDown");
175  group.push_back("Variations:muRfsrDown");
176  }
177  if (int(group.size()) > 0) {
178  weightCombineList.insert ( make_pair("scaleDown", group) );
179  weightCombineListNames.push_back ("scaleDown");
180  }
181 
182  group.resize(0);
183  // Up-variations of renormalization scale.
184  if (settingsPtr->parm("Variations:muRisrUp") != 1.) {
185  bookWeightVar("Variations:muRisrUp");
186  group.push_back("Variations:muRisrUp");
187  }
188  if (settingsPtr->parm("Variations:muRfsrUp") != 1.) {
189  bookWeightVar("Variations:muRfsrUp");
190  group.push_back("Variations:muRfsrUp");
191  }
192  if (int(group.size()) > 0) {
193  weightCombineList.insert ( make_pair("scaleUp", group) );
194  weightCombineListNames.push_back ("scaleUp");
195  }
196 
197  // PDF variations.
198  group.resize(0);
199  if (settingsPtr->flag("Variations:PDFup")) {
200  bookWeightVar("Variations:PDFup",false);
201  group.push_back("Variations:PDFup");
202  weightCombineList.insert ( make_pair("PDFup", group) );
203  weightCombineListNames.push_back ("PDFup");
204  }
205  group.resize(0);
206  if (settingsPtr->flag("Variations:PDFdown")) {
207  bookWeightVar("Variations:PDFdown",false);
208  group.push_back("Variations:PDFdown");
209  weightCombineList.insert ( make_pair("PDFdown", group) );
210  weightCombineListNames.push_back ("PDFdown");
211  }
212 
213  // ME variations.
214  if (settingsPtr->parm("Variations:muRmeUp") != 1.)
215  bookWeightVar("Variations:muRmeUp");
216  if (settingsPtr->parm("Variations:muRmeDown") != 1.)
217  bookWeightVar("Variations:muRmeDown");
218  if (settingsPtr->parm("Variations:muFmeUp") != 1.)
219  bookWeightVar("Variations:muFmeUp");
220  if (settingsPtr->parm("Variations:muFmeDown") != 1.)
221  bookWeightVar("Variations:muFmeDown");
222 
223  }
224 
225  // Remember groups of weights that should be combined into one weight.
226  //vector<string> group;
227  //group = createvector<string>("Variations:muRfsrUp")
228  // ("Variations:muRisrUp");
229  //weightCombineList.insert ( make_pair("scaleUp", group) );
230  //weightCombineListNames.push_back ("scaleUp");
231  //group = createvector<string>("Variations:muRfsrDown")
232  // ("Variations:muRisrDown");
233  //weightCombineList.insert ( make_pair("scaleDown", group) );
234  //weightCombineListNames.push_back ("scaleDown");
235 
236 }
237 
238 //--------------------------------------------------------------------------
239 
240 void DireWeightContainer::bookWeightVar( string vkey, bool checkSettings) {
241  bool insert = !checkSettings || settingsPtr->parm(vkey) != 1.0;
242  if (insert) {
243  rejectWeight.insert( make_pair(vkey, map<ulong, DirePSWeight>() ));
244  acceptWeight.insert( make_pair(vkey, map<ulong, DirePSWeight>() ));
245  showerWeight.insert( make_pair(vkey, 1.) );
246  weightNames.push_back( vkey );
247  }
248 }
249 
250 //--------------------------------------------------------------------------
251 
252 void DireWeightContainer::setWeight( string varKey, double value) {
253  unordered_map<string, double>::iterator it = showerWeight.find( varKey );
254  if ( it == showerWeight.end() ) return;
255  it->second = value;
256 }
257 
258 //--------------------------------------------------------------------------
259 
260 void DireWeightContainer::resetAcceptWeight( double pT2key, double value,
261  string varKey) {
262  unordered_map<string, map<ulong, DirePSWeight> >::iterator
263  it0 = acceptWeight.find( varKey );
264  if ( it0 == acceptWeight.end() ) return;
265  map<ulong, DirePSWeight>::iterator
266  it = acceptWeight[varKey].find( key(pT2key) );
267  if ( it == acceptWeight[varKey].end() ) return;
268  acceptWeight[varKey].erase(it);
269  acceptWeight[varKey].insert( make_pair( key(pT2key),
270  DirePSWeight(value,1,0,pT2key,"")));
271 }
272 
273 //--------------------------------------------------------------------------
274 
275 void DireWeightContainer::resetRejectWeight( double pT2key, double value,
276  string varKey) {
277  unordered_map<string, map<ulong, DirePSWeight> >::iterator
278  it0 = rejectWeight.find( varKey );
279  if ( it0 == rejectWeight.end() ) return;
280  map<ulong, DirePSWeight>::iterator
281  it = rejectWeight[varKey].find( key(pT2key) );
282  if ( it == rejectWeight[varKey].end() ) return;
283  rejectWeight[varKey].erase(it);
284  rejectWeight[varKey].insert( make_pair( key(pT2key),
285  DirePSWeight(value,1,0,pT2key,"")));
286 }
287 
288 //--------------------------------------------------------------------------
289 
290 void DireWeightContainer::eraseAcceptWeight( double pT2key, string varKey) {
291  unordered_map<string, map<ulong, DirePSWeight> >::iterator
292  it0 = acceptWeight.find( varKey );
293  if ( it0 == acceptWeight.end() ) return;
294  map<ulong, DirePSWeight>::iterator
295  it = acceptWeight[varKey].find( key(pT2key) );
296  if ( it == acceptWeight[varKey].end() ) return;
297  acceptWeight[varKey].erase(it);
298 }
299 
300 //--------------------------------------------------------------------------
301 
302 void DireWeightContainer::eraseRejectWeight( double pT2key, string varKey) {
303  unordered_map<string, map<ulong, DirePSWeight> >::iterator it0 =
304  rejectWeight.find( varKey );
305  if ( it0 == rejectWeight.end() ) return;
306  map<ulong, DirePSWeight>::iterator it =
307  rejectWeight[varKey].find( key(pT2key) );
308  if ( it == rejectWeight[varKey].end() ) return;
309  rejectWeight[varKey].erase(it);
310 }
311 
312 //--------------------------------------------------------------------------
313 
314 double DireWeightContainer::getAcceptWeight( double pT2key, string varKey) {
315  unordered_map<string, map<ulong, DirePSWeight> >::iterator it0 =
316  acceptWeight.find( varKey );
317  if ( it0 == acceptWeight.end() ) return 0./0.;
318  map<ulong, DirePSWeight>::iterator it =
319  acceptWeight[varKey].find( key(pT2key) );
320  if ( it == acceptWeight[varKey].end() ) return 0./0.;
321  return it->second.weight();
322 }
323 
324 
325 //--------------------------------------------------------------------------
326 
327 double DireWeightContainer::getRejectWeight( double pT2key, string varKey) {
328  unordered_map<string, map<ulong, DirePSWeight> >::iterator it0 =
329  rejectWeight.find( varKey );
330  if ( it0 == rejectWeight.end() ) return 0./0.;
331  map<ulong, DirePSWeight>::iterator it =
332  rejectWeight[varKey].find( key(pT2key) );
333  if ( it == rejectWeight[varKey].end() ) return 0./0.;
334  return it->second.weight();
335 }
336 
337 //--------------------------------------------------------------------------
338 
339 // Attach accept/reject probabilities for a proposed shower step.
340 void DireWeightContainer::insertWeights( map<double,double> aWeight,
341  multimap<double,double> rWeight, string varKey ) {
342 
343  unordered_map<string, map<ulong, DirePSWeight> >::iterator itA0 =
344  acceptWeight.find( varKey );
345  if ( itA0 == acceptWeight.end() ) return;
346  unordered_map<string, map<ulong, DirePSWeight> >::iterator itR0 =
347  rejectWeight.find( varKey );
348  if ( itR0 == rejectWeight.end() ) return;
349 
350  // New accept weights.
351  for ( map<double,double>::iterator it = aWeight.begin();
352  it != aWeight.end(); ++it ){
353  map<ulong, DirePSWeight>::iterator itLo
354  = acceptWeight[varKey].find( key(it->first) );
355  if (itLo == acceptWeight[varKey].end())
356  acceptWeight[varKey].insert(make_pair( key(it->first),
357  DirePSWeight(it->second,1,0,it->first,"")));
358  else
359  itLo->second *= it->second;
360  }
361  // New reject weights.
362  for ( multimap<double,double>::iterator it = rWeight.begin();
363  it != rWeight.end(); ++it ){
364  map<ulong, DirePSWeight>::iterator itLo
365  = rejectWeight[varKey].find( key(it->first) );
366  if (itLo == rejectWeight[varKey].end())
367  rejectWeight[varKey].insert
368  (make_pair( key(it->first),
369  DirePSWeight(it->second,-1,0,it->first,"")));
370  else
371  itLo->second *= it->second;
372  }
373 }
374 
375 //--------------------------------------------------------------------------
376 
377 // Function to calculate the weight of the shower evolution step.
378 void DireWeightContainer::calcWeight(double pT2, bool includeAcceptAtPT2,
379  bool includeRejectAtPT2) {
380 
381  // Loop though weights.
382  for ( unordered_map<string, map<ulong, DirePSWeight> >::iterator
383  it = rejectWeight.begin(); it != rejectWeight.end(); ++it ) {
384  // Set accept weight.
385  bool hasAccept = ( acceptWeight[it->first].find(key(pT2))
386  != acceptWeight[it->first].end());
387  double acceptWt = (hasAccept && includeAcceptAtPT2)
388  ? acceptWeight[it->first].find(key(pT2))->second.weight()
389  : 1.;
390 
391  // Now multiply rejection weights.
392  double rejectWt = 1.;
393  for ( map<ulong, DirePSWeight>::reverse_iterator itR
394  = it->second.rbegin(); itR != it->second.rend(); ++itR ){
395  if ( includeRejectAtPT2 && itR->first == key(pT2) ) {
396  rejectWt *= itR->second.weight(); }
397  if ( itR->first > key(pT2) ) { rejectWt *= itR->second.weight(); }
398  if ( itR->first < key(pT2) || itR->first-key(pT2) == 0) break;
399  }
400 
401  // Remember weights
402  unordered_map<string, double>::iterator itW = showerWeight.find(it->first);
403 
404  if (itW != showerWeight.end()) itW->second *= acceptWt*rejectWt;
405 
406  }
407 
408 }
409 
410 //--------------------------------------------------------------------------
411 
412 // Function to calculate the weight of the shower evolution step.
413 pair<double,double> DireWeightContainer::getWeight(double pT2, string varKey) {
414 
415  // Set accept weight.
416  bool hasAccept = ( acceptWeight[varKey].find(key(pT2))
417  != acceptWeight[varKey].end());
418  double acceptWt = (hasAccept)
419  ? acceptWeight[varKey].find(key(pT2))->second.weight()
420  : 1.;
421 
422  // Now multiply rejection weights.
423  double rejectWt = 1.;
424  unordered_map<string, map<ulong, DirePSWeight> >::iterator itRW
425  = rejectWeight.find(varKey);
426  if (itRW != rejectWeight.end()) {
427 
428  // Now multiply rejection weights.
429  for ( map<ulong, DirePSWeight>::reverse_iterator itR
430  = itRW->second.rbegin(); itR != itRW->second.rend();
431  ++itR ){
432  if ( itR->first > key(pT2) ) rejectWt *= itR->second.weight();
433  if ( itR->first < key(pT2) || itR->first-key(pT2) == 0) break;
434  }
435 
436  }
437 
438  // Remember weights
439  unordered_map<string, double>::iterator itW = showerWeight.find(varKey);
440 
441  if (itW != showerWeight.end()
442  && abs(itW->second) > LARGEWT) direInfoPtr->message(1) << scientific
443  << setprecision(8) << __FILE__ << " " << __func__ << " "
444  << __LINE__ << " : Found large shower weight=" << itW->second
445  << " at pT2=" << pT2 << endl;
446 
447  if (itW != showerWeight.end()) rejectWt *= itW->second;
448 
449  // Diagnostic messages.
450  if (abs(acceptWt) > LARGEWT) direInfoPtr->message(1) << scientific
451  << setprecision(8) << __FILE__ << " " << __func__ << " "
452  << __LINE__ << " : Found large accept weight=" << acceptWt
453  << " at pT2=" << pT2 << endl;
454  if ( abs(rejectWt) > LARGEWT) {
455  for ( map<ulong, DirePSWeight>::reverse_iterator itR
456  = itRW->second.rbegin(); itR != itRW->second.rend(); ++itR ){
457  if ( itR->first > key(pT2) ) {
458  if ( abs(itR->second.weight()) > LARGEWT) direInfoPtr->message(1)
459  << scientific << setprecision(8) << __FILE__ << " " << __func__
460  << " " << __LINE__ << " : Found large reject weight="
461  << itR->second.weight() << " at index=" << itR->first
462  << " (pT2 approx. " << dkey(itR->first) << ")" << endl;
463  }
464  if ( itR->first < key(pT2) || itR->first-key(pT2) == 0) break;
465  }
466  }
467 
468  // Done.
469  return make_pair(acceptWt,rejectWt);
470 
471 }
472 
473 //--------------------------------------------------------------------------
474 
475 // Returns additional user-supplied enhancements factors.
476 
477 double DireWeightContainer::enhanceOverestimate( string name ) {
478  unordered_map<string, double>::iterator it = enhanceFactors.find(name );
479  if ( it == enhanceFactors.end() ) return 1.;
480  return it->second;
481 }
482 
483 //--------------------------------------------------------------------------
484 
485 double DireWeightContainer::getTrialEnhancement( double pT2key ) {
486  map<ulong,double>::iterator it = trialEnhancements.find(key(pT2key));
487  if ( it == trialEnhancements.end() ) return 1.;
488  return it->second;
489 }
490 
491 //--------------------------------------------------------------------------
492 
493 bool DireWeightContainer::hasME(const Event& event) {
494  if (hasMEs) return matrixElements.isAvailableMEDire(event);
495  return false;
496 }
497 
498 bool DireWeightContainer::hasME(vector <int> in_pdgs, vector<int> out_pdgs) {
499  if (hasMEs) return matrixElements.isAvailableMEDire(in_pdgs, out_pdgs);
500  return false;
501 }
502 
503 double DireWeightContainer::getME(const Event& event) {
504  if (hasMEs) return matrixElements.calcMEDire(event);
505  return 0.0;
506 }
507 
508 //==========================================================================
509 
510 } // end namespace Pythia8
Definition: AgUStep.h:26