Analysis Software
Documentation for sPHENIX simulation software
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
PHPythia6.C
Go to the documentation of this file. Or view the newest version in sPHENIX GitHub for file PHPythia6.C
1 #include "PHPythia6.h"
2 #include "PHPy6GenTrigger.h"
3 
6 
8 
9 #include <phool/getClass.h>
10 #include <phool/recoConsts.h>
11 #include <phool/PHIODataNode.h>
12 #include <phool/PHDataNode.h>
13 #include <phool/PHObject.h>
14 #include <phool/PHCompositeNode.h>
15 #include <phool/PHNodeIterator.h>
16 #include <phool/PHNodeReset.h>
17 #include <phool/PHTimeStamp.h>
18 #include <phool/PHRandomSeed.h>
19 
20 #include <HepMC/PythiaWrapper.h>
21 #include <HepMC/IO_HEPEVT.h>
22 #include <HepMC/IO_GenEvent.h>
23 #include <HepMC/IO_AsciiParticles.h>
24 #include <HepMC/GenEvent.h>
25 
26 #include <gsl/gsl_randist.h>
27 
28 #include <iostream>
29 #include <iomanip>
30 #include <fstream>
31 #include <sstream>
32 #include <cstdlib>
33 #include <stdlib.h>
34 #include <ctime>
35 #include <sys/time.h>
36 #include <algorithm>
37 #include <cctype>
38 
39 #define pytune pytune_
40 extern "C" int pytune(int *itune);
41 
42 using namespace std;
43 
45 
47  SubsysReco(name),
48  _eventcount(0),
49  _geneventcount(0),
50  _configFile("phpythia6.cfg"),
51  _save_ascii( false ),
52  _filename_ascii("pythia_hepmc.dat"),
53  _registeredTriggers(),
54  _triggersOR(true),
55  _triggersAND(false){
56 
57  PHHepMCGenHelper::set_embedding_id(1); // default embedding ID to 1
58 }
59 
61  //gsl_rng_free (RandomGenerator);
62 }
63 
65 
66  /* Create node tree */
67  CreateNodeTree(topNode);
68 
69  /* event numbering will start from 1 */
70  _eventcount = 0;
71 
72  /* HepMC/example_MyPythia.cc:
73  *
74  * Pythia 6.1 uses HEPEVT with 4000 entries and 8-byte floating point
75  * numbers. We need to explicitly pass this information to the
76  * HEPEVT_Wrapper.
77  */
78  HepMC::HEPEVT_Wrapper::set_max_number_entries(4000);
79  HepMC::HEPEVT_Wrapper::set_sizeof_real(8);
80 
81  /* set pythia random number seed (mandatory!) */
82  int fSeed = PHRandomSeed();
83  fSeed = abs(fSeed)%900000000;
84 
85  if ( (fSeed>=0) && (fSeed<=900000000) ) {
86  pydatr.mrpy[0] = fSeed; // set seed
87  pydatr.mrpy[1] = 0; // use new seed
88  } else {
89  cout << PHWHERE << " ERROR: seed " << fSeed << " is not valid" << endl;
90  exit(2);
91  }
92 
93  /* read pythia configuration and initialize */
94  if (!_configFile.empty()) ReadConfig( _configFile );
95 
96  /* Initialization done */
98 }
99 
101 
102  //........................................TERMINATION
103  // write out some information from Pythia to the screen
104  call_pystat( 1 );
105 
106  //match pythia printout
107  cout << " | "
108  << " | " << endl;
109  cout << " PHPythia6::End - " << _eventcount
110  << " events passed trigger" << endl;
111  cout << " Fraction passed: " << _eventcount
112  << "/" << _geneventcount
113  << " = " << _eventcount/float(_geneventcount) << endl;
114  cout << " *------- End PYTHIA Trigger Statistics ------------------------"
115  << "-------------------------------------------------* " << endl;
116 
118 }
119 
120 //__________________________________________________________
121 int PHPythia6::ReadConfig(const string cfg_file) {
122 
123  if ( cfg_file != "" ) _configFile = cfg_file;
124  cout << "PHPythia6::read_config - Reading " << _configFile << endl;
125 
126  ifstream infile( _configFile );
127  if (infile.fail ()) {
128  cout << "PHPythia6::read_config - Failed to open file " << _configFile << endl;
129  exit(2);
130  }
131 
132  // initialize variables
133  Int_t _nevents(0);
134  Float_t _roots(0);
135  string _proj;
136  string _targ;
137  string _frame;
138 
139  string FullLine; // a complete line in the config file
140  string label; // the label
141 
142  int index = 999999;
143  double value = 1e9;
144 
145  // get one line first
146  getline(infile, FullLine);
147  while ( !infile.eof() )
148  {
149 
150  // skip lines that begin with #, or "//"
151  if ( FullLine[0]=='#' || FullLine.substr(0, 2) == "//" )
152  {
153  getline(infile,FullLine);
154  continue;
155  }
156 
157  // make FullLine an istringstream
158  istringstream line( FullLine.c_str() );
159 
160  // get label
161  line >> label;
162 
163  // to lower case
164  std::transform(label.begin(), label.end(), label.begin(), (int(*)(int)) std::tolower);
165 
166  // based on label, fill correct item
167  if ( label == "nevents" )
168  {
169  line >> _nevents;
170  cout << "nevents\t" << _nevents << endl;
171  }
172  else if ( label == "roots" )
173  {
174  line >> _roots;
175  cout << "roots\t" << _roots << endl;
176  }
177  else if ( label == "proj" )
178  {
179  line >> _proj;
180  cout << "proj\t" << _proj << endl;
181  }
182  else if ( label == "targ" )
183  {
184  line >> _targ;
185  cout << "targ\t" << _targ << endl;
186  }
187  else if ( label == "frame" )
188  {
189  line >> _frame;
190  cout << "frame\t" << _frame << endl;
191  }
192  else if ( label == "p1" || label == "p2")
193  {
194  if (label == "p1") //Momentum of Projectile Beam (e- for e-p)
195  {
196  line >> index >> value;
197  //Index Options(3MOM): 1 = x-momentum; 2 = y-momentum; 3 = z-momentum
198  pyjets.p[index-1][0] = value;
199  cout << "p1\t" << index << " " << value << endl;
200  }
201  if (label == "p2") //Momentum of Target Beam (p for e-p)
202  {
203  line >> index >> value;
204  //Index Options(3MOM): 1 = x-momentum; 2 = y-momentum; 3 = z-momentum
205  pyjets.p[index-1][1] = value;
206  cout << "p2\t" << index << " " << value << endl;
207  }
208  /*
209  int entry = 0;
210  if ( label=="p1") entry = 1;
211  else if ( label=="p2") entry = 2;
212 
213  char temp_line[10000];
214  strcpy(temp_line,FullLine.c_str());
215  char *sptr = strtok(temp_line," \t"); // skip first word
216  sptr = strtok(NULL," \t");
217  cout << label;
218  int index = 1;
219  while ( sptr != NULL )
220  {
221  double val = atof(sptr);
222  cout << "Entry: " << entry << endl;
223  index++;
224  cout << "\t" << val;
225  sptr = strtok(NULL," \t");
226  }
227  cout << endl;*/
228  }
229  else if ( label == "msel" )
230  {
231  line >> value;
232  pysubs.msel= (int) value;
233  cout << "msel\t" << value << endl;
234  IntegerTest(value);
235  }
236  else if ( label == "msub" )
237  {
238  line >> index >> value;
239  // careful with C/F77 differences: arrays in C start at 0, F77 at 1,
240  // so we need to subtract 1 from the process #)
241  pysubs.msub[index-1] = (int) value;
242  cout << "msub\t" << index << " " << value << endl;
243  IntegerTest(value);
244  }
245  else if ( label == "mstp" )
246  {
247  line >> index >> value;
248  pypars.mstp[index-1] = (int) value;
249  cout << "mstp\t" << index << " " << value << endl;
250  IntegerTest(value);
251  }
252  else if ( label == "mstj" )
253  {
254  line >> index >> value;
255  pydat1.mstj[index-1] = (int) value;
256  cout << "mstj\t" << index << " " << value << endl;
257  IntegerTest(value);
258  }
259  else if ( label == "mstu" )
260  {
261  line >> index >> value;
262  pydat1.mstu[index-1] = (int) value;
263  cout << "mstu\t" << index << " " << value << endl;
264  IntegerTest(value);
265  }
266  else if ( label == "ckin" )
267  {
268  line >> index >> value;
269  pysubs.ckin[index-1] =value;
270  cout << "ckin\t" << index << " " << value << endl;
271  }
272  else if ( label == "parp" )
273  {
274  line >> index >> value;
275  pypars.parp[index-1] = value;
276  cout << "parp\t" << index << " " << value << endl;
277  }
278  else if ( label == "parj" )
279  {
280  line >> index >> value;
281  pydat1.parj[index-1] = value;
282  cout << "parj\t" << index << " " << value << endl;
283  }
284  else if ( label == "paru" )
285  {
286  line >> index >> value;
287  pydat1.paru[index-1] = value;
288  cout << "paru\t" << index << " " << value << endl;
289  }
290  else if ( label == "parf" )
291  {
292  line >> index >> value;
293  pydat2.parf[index-1] = value;
294  cout << "parf\t" << index << " " << value << endl;
295  }
296  else if ( label == "mdme" )
297  {
298  int idc = 0; // decay channel
299  line >> idc >> index >> value;
300 
301  // if (ivalue==1/0) turn on/off decay channel idc
302  pydat3.mdme[index-1][idc-1] = value;
303  cout << "mdme\t" << idc << " " << index << " " << value << endl;
304  }
305  else if ( label == "pmas" )
306  {
307  int idc = 0;
308  line >> idc >> index >> value;
309 
310  pydat2.pmas[index-1][idc-1] = value;
311  cout << "pmas\t" << idc << " " << index << " " << value << endl;
312  }
313  else if ( label == "pytune" )
314  {
315  int ivalue;
316  line >> ivalue;
317  pytune(&ivalue);
318  cout << "pytune\t" << ivalue << endl;
319  }
320  else
321  {
322  // label was not understood
323  cout << "************************************************************" << endl;
324  cout << "PHPythia6::ReadConfig(), ERROR this option is not supported: " << FullLine << endl;
325  cout << "************************************************************" << endl;
326  }
327 
328  // get next line in file
329  getline( infile, FullLine );
330  }
331 
332  // Call pythia initialization
333  call_pyinit( _frame.c_str(), _proj.c_str(), _targ.c_str(), _roots );
334 
335  //call_pylist(12);
336 
337  infile.close();
338 
339  return _nevents;
340 }
341 
342 //-* print pythia config info
344 }
345 
347 
348  if (verbosity > 1) cout << "PHPythia6::process_event - event: " << _eventcount << endl;
349 
350  bool passedTrigger = false;
351  std::vector<bool> theTriggerResults;
352  int genCounter = 0;
353 
354  /* based on HepMC/example_MyPythia.cc
355  *........................................HepMC INITIALIZATIONS
356  *
357  * Instantiate an IO strategy for reading from HEPEVT. */
358  HepMC::IO_HEPEVT hepevtio;
359  HepMC::GenEvent* evt;
360 
361  while (!passedTrigger) {
362  ++genCounter;
363 
364  call_pyevnt(); // generate one event with Pythia
365  _geneventcount++;
366  // pythia pyhepc routine converts common PYJETS in common HEPEVT
367  call_pyhepc( 1 );
368  evt = hepevtio.read_next_event();
369 
370  // define the units (Pythia uses GeV and mm)
371  evt->use_units(HepMC::Units::GEV, HepMC::Units::MM);
372 
373  // add some information to the event
374  evt->set_event_number(_eventcount);
375 
376  /* process ID from pythia */
377  evt->set_signal_process_id(pypars.msti[1-1]);
378 
379  // set number of multi parton interactions
380  evt->set_mpi( pypars.msti[31-1] );
381 
382  // set cross section information
383  evt->set_cross_section( HepMC::getPythiaCrossSection() );
384 
385  // Set the PDF information
386  HepMC::PdfInfo pdfinfo;
387  pdfinfo.set_x1(pypars.pari[33-1]);
388  pdfinfo.set_x2(pypars.pari[34-1]);
389  pdfinfo.set_scalePDF(pypars.pari[22-1]);
390  pdfinfo.set_id1(pypars.msti[15-1]);
391  pdfinfo.set_id2(pypars.msti[16-1]);
392  evt->set_pdf_info(pdfinfo);
393 
394  // test trigger logic
395 
396  bool andScoreKeeper = true;
397  if (verbosity > 2) {
398  cout << "PHPythia6::process_event - triggersize: " << _registeredTriggers.size() << endl;
399  }
400 
401  for (unsigned int tr = 0; tr < _registeredTriggers.size(); tr++) {
402  bool trigResult = _registeredTriggers[tr]->Apply(evt);
403 
404  if (verbosity > 2) {
405  cout << "PHPythia6::process_event trigger: "
406  << _registeredTriggers[tr]->GetName() << " " << trigResult << endl;
407  }
408 
409  if (_triggersOR && trigResult) {
410  passedTrigger = true;
411  break;
412  } else if (_triggersAND) {
413  andScoreKeeper &= trigResult;
414  }
415 
416  if (verbosity > 2 && !passedTrigger) {
417  cout << "PHPythia8::process_event - failed trigger: "
418  << _registeredTriggers[tr]->GetName() << endl;
419  }
420  }
421 
422  if ((andScoreKeeper && _triggersAND) || (_registeredTriggers.size() == 0)) {
423  passedTrigger = true;
424  genCounter = 0;
425  }
426 
427  // delete failed events
428  if(!passedTrigger) delete evt;
429 
430  }
431 
432  /* write the event out to the ascii files */
433  if ( _save_ascii )
434  {
435  HepMC::IO_GenEvent ascii_io(_filename_ascii.c_str(),std::ios::out);
436  ascii_io << evt;
437  }
438 
439  /* pass HepMC to PHNode*/
440 
442  if (!success) {
443  cout << "PHPythia6::process_event - Failed to add event to HepMC record!" << endl;
445  }
446  /* print outs*/
447  if (verbosity > 2) cout << "PHPythia6::process_event - FINISHED WHOLE EVENT" << endl;
448 
449  ++_eventcount;
451 }
452 
453 
454 
455 void PHPythia6::IntegerTest(double number ) {
456 
457  if (fmod(number, 1.0) != 0) {
458  cout << "Warning: Value " << number << " is not an integer." << endl;
459  cout << "This parameter requires an integer value." << endl;
460  cout << "Value of parameter truncated to " << (int) number << endl;
461 
462  //...End simulation if a double value is input for an integer parameter
463  // throw Fun4AllReturnCodes::ABORTRUN;
464  }
465  return;
466 }
467 
470 }
471 
473  if(verbosity > 1) cout << "PHPythia6::registerTrigger - trigger " << theTrigger->GetName() << " registered" << endl;
474  _registeredTriggers.push_back(theTrigger);
475 }