ECCE @ EIC Software
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
PHPythia8.cc
Go to the documentation of this file. Or view the newest version in sPHENIX GitHub for file PHPythia8.cc
1 #include "PHPythia8.h"
2 
3 #include "PHPy8GenTrigger.h"
4 
5 #include <phhepmc/PHGenIntegral.h> // for PHGenIntegral
7 #include <phhepmc/PHHepMCGenHelper.h> // for PHHepMCGenHelper
8 
9 #include <fun4all/Fun4AllBase.h> // for Fun4AllBase::VERBO...
11 #include <fun4all/SubsysReco.h> // for SubsysReco
12 
13 #include <phool/PHCompositeNode.h>
14 #include <phool/PHIODataNode.h>
15 #include <phool/PHNode.h> // for PHNode
16 #include <phool/PHNodeIterator.h> // for PHNodeIterator
17 #include <phool/PHObject.h> // for PHObject
18 #include <phool/PHRandomSeed.h>
19 #include <phool/getClass.h>
20 #include <phool/phool.h> // for PHWHERE
21 
22 #include <HepMC/GenEvent.h>
23 #include <HepMC/Units.h> // for GEV, MM
24 
25 #include <Pythia8/Event.h> // for Event
26 #include <Pythia8/Info.h> // for Info
27 #include <Pythia8/Pythia.h>
28 #include <Pythia8Plugins/HepMC2.h>
29 
30 #include <boost/format.hpp>
31 
32 #include <cassert>
33 #include <cstdlib>
34 #include <iostream> // for operator<<, endl
35 
36 class PHHepMCGenEvent;
37 
38 using namespace std;
39 
40 PHPythia8::PHPythia8(const std::string &name)
41  : SubsysReco(name)
42  , m_EventCount(0)
43  , m_TriggersOR(true)
44  , m_TriggersAND(false)
45  , m_Pythia8(nullptr)
46  , m_ConfigFileName("phpythia8.cfg")
47  , m_Pythia8ToHepMC(nullptr)
48  , m_SaveEventWeightFlag(true)
49  , m_SaveIntegratedLuminosityFlag(true)
50  , m_IntegralNode(nullptr)
51 {
52  char *charPath = getenv("PYTHIA8");
53  if (!charPath)
54  {
55  cout << "PHPythia8::Could not find $PYTHIA8 path!" << endl;
56  return;
57  }
58 
59  std::string thePath(charPath);
60  thePath += "/xmldoc/";
61  m_Pythia8 = new Pythia8::Pythia(thePath.c_str());
62 
63  m_Pythia8ToHepMC = new HepMC::Pythia8ToHepMC();
64  m_Pythia8ToHepMC->set_store_proc(true);
65  m_Pythia8ToHepMC->set_store_pdf(true);
66  m_Pythia8ToHepMC->set_store_xsec(true);
67 
68  PHHepMCGenHelper::set_embedding_id(1); // default embedding ID to 1
69 }
70 
72 {
73  delete m_Pythia8;
74  delete m_Pythia8ToHepMC;
75 }
76 
78 {
80  for (unsigned int j = 0; j < m_Commands.size(); j++)
81  {
82  m_Pythia8->readString(m_Commands[j]);
83  }
84 
85  create_node_tree(topNode);
86 
87  // PYTHIA8 has very specific requires for its random number range
88  // I map the designated unique seed from recoconst into something
89  // acceptable for PYTHIA8
90 
91  unsigned int seed = PHRandomSeed();
92 
93  if (seed > 900000000)
94  {
95  seed = seed % 900000000;
96  }
97 
98  if ((seed > 0) && (seed <= 900000000))
99  {
100  m_Pythia8->readString("Random:setSeed = on");
101  m_Pythia8->readString(str(boost::format("Random:seed = %1%") % seed));
102  }
103  else
104  {
105  cout << PHWHERE << " ERROR: seed " << seed << " is not valid" << endl;
106  exit(1);
107  }
108  // print out seed so we can make this is reproducible
109  cout << "PHPythia8 random seed: " << seed << endl;
110 
111  m_Pythia8->init();
112 
114 }
115 
117 {
118  if (Verbosity() >= VERBOSITY_MORE) cout << "PHPythia8::End - I'm here!" << endl;
119 
120  if (Verbosity() >= VERBOSITY_SOME)
121  {
122  //-* dump out closing info (cross-sections, etc)
123  m_Pythia8->stat();
124 
125  //match pythia printout
126  cout << " | "
127  << " | " << endl;
128  cout << " PHPythia8::End - " << m_EventCount
129  << " events passed trigger" << endl;
130  cout << " Fraction passed: " << m_EventCount
131  << "/" << m_Pythia8->info.nAccepted()
132  << " = " << m_EventCount / float(m_Pythia8->info.nAccepted()) << endl;
133  cout << " *------- End PYTHIA Trigger Statistics ------------------------"
134  << "-------------------------------------------------* " << endl;
135 
136  if (m_IntegralNode)
137  {
138  cout << "Integral information on stored on node RUN/PHGenIntegral:" << endl;
140  cout << " *------- End PYTHIA Integral Node Print ------------------------"
141  << "-------------------------------------------------* " << endl;
142  }
143  }
144 
146 }
147 
148 //__________________________________________________________
149 int PHPythia8::read_config(const string &cfg_file)
150 {
151  m_ConfigFileName = cfg_file;
152 
153  if (Verbosity() >= VERBOSITY_SOME)
154  cout << "PHPythia8::read_config - Reading " << m_ConfigFileName << endl;
155 
156  ifstream infile(m_ConfigFileName);
157  if (infile.fail())
158  {
159  cout << "PHPythia8::read_config - Failed to open file " << m_ConfigFileName << endl;
160  exit(2);
161  }
162 
163  m_Pythia8->readFile(m_ConfigFileName);
164 
166 }
167 
168 //-* print pythia config info
170 {
171  m_Pythia8->info.list();
172 }
173 
175 {
176  if (Verbosity() >= VERBOSITY_MORE) cout << "PHPythia8::process_event - event: " << m_EventCount << endl;
177 
178  bool passedGen = false;
179  bool passedTrigger = false;
180  int genCounter = 0;
181 
182  while (!passedTrigger)
183  {
184  ++genCounter;
185 
186  // generate another pythia event
187  while (!passedGen)
188  {
189  passedGen = m_Pythia8->next();
190  }
191 
192  // test trigger logic
193 
194  bool andScoreKeeper = true;
196  {
197  cout << "PHPythia8::process_event - triggersize: " << m_RegisteredTriggers.size() << endl;
198  }
199 
200  for (unsigned int tr = 0; tr < m_RegisteredTriggers.size(); tr++)
201  {
202  bool trigResult = m_RegisteredTriggers[tr]->Apply(m_Pythia8);
203 
205  {
206  cout << "PHPythia8::process_event trigger: "
207  << m_RegisteredTriggers[tr]->GetName() << " " << trigResult << endl;
208  }
209 
210  if (m_TriggersOR && trigResult)
211  {
212  passedTrigger = true;
213  break;
214  }
215  else if (m_TriggersAND)
216  {
217  andScoreKeeper &= trigResult;
218  }
219 
220  if (Verbosity() >= VERBOSITY_EVEN_MORE && !passedTrigger)
221  {
222  cout << "PHPythia8::process_event - failed trigger: "
223  << m_RegisteredTriggers[tr]->GetName() << endl;
224  }
225  }
226 
227  if ((andScoreKeeper && m_TriggersAND) || (m_RegisteredTriggers.size() == 0))
228  {
229  passedTrigger = true;
230  genCounter = 0;
231  }
232 
233  passedGen = false;
234  }
235 
236  // fill HepMC object with event & pass to
237 
238  HepMC::GenEvent *genevent = new HepMC::GenEvent(HepMC::Units::GEV, HepMC::Units::MM);
239  m_Pythia8ToHepMC->fill_next_event(*m_Pythia8, genevent, m_EventCount);
240  // Enable continuous reweighting by storing additional reweighting factor
242  {
243  genevent->weights().push_back(m_Pythia8->info.weight());
244  }
245 
246  /* pass HepMC to PHNode*/
247  PHHepMCGenEvent *success = PHHepMCGenHelper::insert_event(genevent);
248  if (!success)
249  {
250  cout << "PHPythia8::process_event - Failed to add event to HepMC record!" << endl;
252  }
253 
254  // print outs
255 
256  if (Verbosity() >= VERBOSITY_MORE) cout << "PHPythia8::process_event - FINISHED WHOLE EVENT" << endl;
257  if (m_EventCount < 2 && Verbosity() >= VERBOSITY_SOME) m_Pythia8->event.list();
258  if (m_EventCount >= 2 && Verbosity() >= VERBOSITY_A_LOT) m_Pythia8->event.list();
259 
260  ++m_EventCount;
261 
262  // save statistics
263  if (m_IntegralNode)
264  {
267  m_IntegralNode->set_Sum_Of_Weight(m_Pythia8->info.weightSum());
268  m_IntegralNode->set_Integrated_Lumi(m_Pythia8->info.nAccepted() / (m_Pythia8->info.sigmaGen() * 1e9));
269  }
270 
272 }
273 
275 {
276  // HepMC IO
278 
279  PHNodeIterator iter(topNode);
280  PHCompositeNode *sumNode = dynamic_cast<PHCompositeNode *>(iter.findFirst("PHCompositeNode", "RUN"));
281  if (!sumNode)
282  {
283  cout << PHWHERE << "RUN Node missing doing nothing" << endl;
285  }
287  {
288  m_IntegralNode = findNode::getClass<PHGenIntegral>(sumNode, "PHGenIntegral");
289  if (!m_IntegralNode)
290  {
291  m_IntegralNode = new PHGenIntegralv1("PHPythia8 with embedding ID of " + std::to_string(PHHepMCGenHelper::get_embedding_id()));
292  PHIODataNode<PHObject> *newmapnode = new PHIODataNode<PHObject>(m_IntegralNode, "PHGenIntegral", "PHObject");
293  sumNode->addNode(newmapnode);
294  }
295  else
296  {
297  cout << "PHPythia8::create_node_tree - Fatal Error - "
298  << "RUN/PHGenIntegral node already exist. "
299  << "It is messy to overwrite integrated luminosities. Please turn off this function in the macro with " << endl;
300  cout << " PHPythia8::save_integrated_luminosity(false);" << endl;
301  cout << "The current RUN/PHGenIntegral node is ";
302  m_IntegralNode->identify(cout);
303 
304  exit(EXIT_FAILURE);
305  }
306  assert(m_IntegralNode);
307  }
309 }
310 
312 {
313  if (Verbosity() >= VERBOSITY_MORE) cout << "PHPythia8::registerTrigger - trigger " << theTrigger->GetName() << " registered" << endl;
314  m_RegisteredTriggers.push_back(theTrigger);
315 }