CMS 3D CMS Logo

 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Pages
Pythia6Service.cc
Go to the documentation of this file.
1 #include <algorithm>
2 #include <functional>
3 #include <iostream>
4 #include <sstream>
5 #include <fstream>
6 #include <cmath>
7 #include <string>
8 #include <set>
9 
10 #include <boost/bind.hpp>
11 #include <boost/algorithm/string/classification.hpp>
12 #include <boost/algorithm/string/split.hpp>
13 
14 #include <CLHEP/Random/RandomEngine.h>
15 
17 
20 
22 
25 // #include "GeneratorInterface/Core/interface/ParameterCollector.h"
26 
27 // This will force the symbols below to be kept, even in the case pythia6
28 // is an archive library.
29 //extern "C" void pyexec_(void);
30 extern "C" void pyedit_(void);
31 __attribute__((visibility("hidden"))) void dummy()
32 {
33  using namespace gen;
34  int dummy = 0;
35  double dummy2 = 0;
36  char * dummy3 = 0;
37  pyexec_();
38  pystat_(0);
39  pyjoin_(dummy, &dummy);
40  py1ent_(dummy, dummy, dummy2, dummy2, dummy2);
41  pygive_(dummy3, dummy);
42  pycomp_(dummy);
43  pylist_(0);
44  pyevnt_();
45  pyedit_();
46 }
47 
48 extern "C"
49 {
50  void fioopn_( int* unit, const char* line, int length );
51  void fioopnw_( int* unit, const char* line, int length );
52  void fiocls_( int* unit );
53  void pyslha_( int*, int*, int* );
54  static int call_pyslha(int mupda, int kforig = 0)
55  {
56  int iretrn = 0;
57  pyslha_(&mupda, &kforig, &iretrn);
58  return iretrn;
59  }
60 
61  void pyupda_(int*, int*);
62  static void call_pyupda( int opt, int iunit ){
63  pyupda_( &opt, &iunit );
64  }
65 
66  double gen::pyr_(int *idummy)
67  {
68  // getInstance will throw if no one used enter/leave
69  // or this is the wrong caller class, like e.g. Herwig6Instance
70  Pythia6Service* service = FortranInstance::getInstance<Pythia6Service>();
71  return service->fRandomEngine->flat();
72  }
73 }
74 
75 using namespace gen;
76 using namespace edm;
77 
79 
81  : fRandomEngine(&getEngineReference()), fUnitSLHA(24), fUnitPYUPDA(25)
82 {
83 }
84 
86  : fRandomEngine(&getEngineReference()), fUnitSLHA(24), fUnitPYUPDA(25)
87 {
88  if (fPythia6Owner)
89  throw cms::Exception("PythiaError") <<
90  "Two Pythia6Service instances claiming Pythia6 ownership." <<
91  std::endl;
92 
93  fPythia6Owner = this;
94 
95 /*
96  ParameterCollector collector(ps.getParameter<edm::ParameterSet>("PythiaParameters"));
97 
98  fParamGeneral.clear();
99  fParamCSA.clear();
100  fParamSLHA.clear();
101 
102  fParamGeneral = std::vector<std::string>(collector.begin(), collector.end());
103  fParamCSA = std::vector<std::string>(collector.begin("CSAParameters"), collector.end());
104  fParamSLHA = std::vector<std::string>(collector.begin("SLHAParameters"), collector.end());
105 */
106 
107 
108  // Set PYTHIA parameters in a single ParameterSet
109  //
110  edm::ParameterSet pythia_params =
111  ps.getParameter<edm::ParameterSet>("PythiaParameters") ;
112 
113  // read and sort Pythia6 cards
114  //
115  std::vector<std::string> setNames =
116  pythia_params.getParameter<std::vector<std::string> >("parameterSets");
117 
118  // std::vector<std::string> paramLines;
119  fParamGeneral.clear();
120  fParamCSA.clear();
121  fParamSLHA.clear();
122  fParamPYUPDA.clear();
123 
124 
125  for(std::vector<std::string>::const_iterator iter = setNames.begin();
126  iter != setNames.end(); ++iter)
127  {
128  std::vector<std::string> lines =
129  pythia_params.getParameter< std::vector<std::string> >(*iter);
130 
131  for(std::vector<std::string>::const_iterator line = lines.begin();
132  line != lines.end(); ++line )
133  {
134  if (line->substr(0, 7) == "MRPY(1)")
135  throw cms::Exception("PythiaError") <<
136  "Attempted to set random number"
137  " using Pythia command 'MRPY(1)'."
138  " Please use the"
139  " RandomNumberGeneratorService." <<
140  std::endl;
141 
142  if ( *iter == "CSAParameters" )
143  {
144  fParamCSA.push_back(*line);
145  }
146  else if ( *iter == "SLHAParameters" )
147  {
148  fParamSLHA.push_back(*line);
149  }
150  else if ( *iter == "PYUPDAParameters" )
151  {
152  fParamPYUPDA.push_back(*line);
153  }
154  else
155  {
156  fParamGeneral.push_back(*line);
157  }
158  }
159  }
160 }
161 
163 {
164  if (fPythia6Owner == this)
165  fPythia6Owner = 0;
166 
167  fParamGeneral.clear();
168  fParamCSA.clear();
169  fParamSLHA.clear();
170  fParamPYUPDA.clear();
171 }
172 
174 {
176 
177  if (!fPythia6Owner) {
178  edm::LogInfo("Generator|Pythia6Interface") <<
179  "gen::Pythia6Service is going to initialise Pythia, as no other "
180  "instace has done so yet, and Pythia service routines have been "
181  "requested by a dummy instance." << std::endl;
182 
183  call_pygive("MSTU(12)=12345");
184  call_pyinit("NONE", "", "", 0.0);
185 
186  fPythia6Owner = this;
187  }
188 }
189 
191 {
192  // now pass general config cards
193  //
194  for(std::vector<std::string>::const_iterator iter = fParamGeneral.begin();
195  iter != fParamGeneral.end(); ++iter)
196  {
197  if (!call_pygive(*iter))
198  throw cms::Exception("PythiaError")
199  << "Pythia did not accept \""
200  << *iter << "\"." << std::endl;
201  }
202 
203  return ;
204 }
205 
207 {
208 #define SETCSAPARBUFSIZE 514
209  char buf[SETCSAPARBUFSIZE];
210 
211  txgive_init_();
212  for(std::vector<std::string>::const_iterator iter = fParamCSA.begin();
213  iter != fParamCSA.end(); ++iter)
214  {
215  // Null pad the string should not be needed because it uses
216  // read, which will look for \n, but just in case...
217  for (size_t i = 0; i < SETCSAPARBUFSIZE; ++i)
218  buf[i] = ' ';
219  // Skip empty parameters.
220  if (iter->length() <= 0)
221  continue;
222  // Limit the size of the string to something which fits the buffer.
223  size_t maxSize = iter->length() > (SETCSAPARBUFSIZE-2) ? (SETCSAPARBUFSIZE-2) : iter->length();
224  strncpy(buf, iter->c_str(), maxSize);
225  // Add extra \n if missing, otherwise "read" continues reading.
226  if (buf[maxSize-1] != '\n')
227  {
228  buf[maxSize] = '\n';
229  // Null terminate in case the string is passed back to C.
230  // Not sure that is actually needed.
231  buf[maxSize + 1] = 0;
232  }
233  txgive_(buf, iter->length() );
234  }
235 
236  return ;
237 #undef SETCSAPARBUFSIZE
238 }
239 
240 void Pythia6Service::openSLHA( const char* file )
241 {
242 
243  std::ostringstream pyCard1 ;
244  pyCard1 << "IMSS(21)=" << fUnitSLHA;
245  call_pygive( pyCard1.str() );
246  std::ostringstream pyCard2 ;
247  pyCard2 << "IMSS(22)=" << fUnitSLHA;
248  call_pygive( pyCard2.str() );
249 
250  fioopn_( &fUnitSLHA, file, strlen(file) );
251 
252  return;
253 
254 }
255 
256 void Pythia6Service::openPYUPDA( const char* file, bool write_file )
257 {
258 
259  if (write_file) {
260  std::cout<<"=== WRITING PYUPDA FILE "<<file<<" ==="<<std::endl;
261  fioopnw_( &fUnitPYUPDA, file, strlen(file) );
262  // Write Pythia particle table to this card file.
264  } else {
265  std::cout<<"=== READING PYUPDA FILE "<<file<<" ==="<<std::endl;
266  fioopn_( &fUnitPYUPDA, file, strlen(file) );
267  // Update Pythia particle table with this card file.
269  }
270 
271  return;
272 
273 }
274 
276 {
277 
278  fiocls_(&fUnitSLHA);
279 
280  return;
281 }
282 
284 {
285 
287 
288  return;
289 
290 }
291 
293 {
294  for (std::vector<std::string>::const_iterator iter = fParamSLHA.begin();
295  iter != fParamSLHA.end(); iter++ )
296  {
297 
298  if( iter->find( "SLHAFILE", 0 ) == std::string::npos ) continue;
299  std::string::size_type start = iter->find_first_of( "=" ) + 1;
300  std::string::size_type end = iter->length() - 1;
301  std::string::size_type temp = iter->find_first_of( "'", start );
302  if( temp != std::string::npos ) {
303  start = temp + 1;
304  end = iter->find_last_of( "'" ) - 1;
305  }
306  start = iter->find_first_not_of( " ", start );
307  end = iter->find_last_not_of( " ", end );
308  //std::cout << " start, end = " << start << " " << end << std::endl;
309  std::string shortfile = iter->substr( start, end - start + 1 );
310  FileInPath f1( shortfile );
311  std::string file = f1.fullPath();
312 
313 /*
314  //
315  // override what might have be given via the external config
316  //
317  std::ostringstream pyCard ;
318  pyCard << "IMSS(21)=" << fUnitSLHA;
319  call_pygive( pyCard.str() );
320  pyCard << "IMSS(22)=" << fUnitSLHA;
321  call_pygive( pyCard.str() );
322 
323  fioopn_( &fUnitSLHA, file.c_str(), file.length() );
324 */
325 
326  openSLHA( file.c_str() );
327 
328  }
329 
330  return;
331 }
332 
333 void Pythia6Service::setPYUPDAParams(bool afterPyinit)
334 {
335  std::string shortfile;
336  bool write_file = false;
337  bool usePostPyinit = false;
338 
339  // std::cout<<"=== CALLING setPYUPDAParams === "<<afterPyinit<<" "<<fParamPYUPDA.size()<<std::endl;
340 
341  // This assumes that PYUPDAFILE only appears once ...
342 
343  for (std::vector<std::string>::const_iterator iter = fParamPYUPDA.begin();
344  iter != fParamPYUPDA.end(); iter++ )
345  {
346  // std::cout<<"PYUPDA check "<<*iter<<std::endl;
347  if( iter->find( "PYUPDAFILE", 0 ) != std::string::npos ) {
348  std::string::size_type start = iter->find_first_of( "=" ) + 1;
349  std::string::size_type end = iter->length() - 1;
350  std::string::size_type temp = iter->find_first_of( "'", start );
351  if( temp != std::string::npos ) {
352  start = temp + 1;
353  end = iter->find_last_of( "'" ) - 1;
354  }
355  start = iter->find_first_not_of( " ", start );
356  end = iter->find_last_not_of( " ", end );
357  //std::cout << " start, end = " << start << " " << end << std::endl;
358  shortfile = iter->substr( start, end - start + 1 );
359  } else if ( iter->find( "PYUPDAWRITE", 0 ) != std::string::npos ) {
360  write_file = true;
361  } else if ( iter->find( "PYUPDApostPYINIT", 0 ) != std::string::npos ) {
362  usePostPyinit = true;
363  }
364  }
365 
366  if (!shortfile.empty()) {
367  std::string file;
368  if (write_file) {
369  file = shortfile;
370  } else {
371  // If reading, get full path to file and require it to exist.
372  FileInPath f1( shortfile );
373  file = f1.fullPath();
374  }
375 
376  if (afterPyinit == usePostPyinit || (write_file && afterPyinit)) {
377  openPYUPDA( file.c_str(), write_file );
378  }
379  }
380 
381  return;
382 }
383 
384 void Pythia6Service::setSLHAFromHeader( const std::vector<std::string> &lines )
385 {
386 
387  std::set<std::string> blocks;
388  unsigned int model = 0, subModel = 0;
389 
390  const char *fname = std::tmpnam(NULL);
391  std::ofstream file(fname, std::fstream::out | std::fstream::trunc);
392  std::string block;
393  for(std::vector<std::string>::const_iterator iter = lines.begin();
394  iter != lines.end(); ++iter) {
395  file << *iter;
396 
397  std::string line = *iter;
398  std::transform(line.begin(), line.end(),
399  line.begin(), (int(*)(int))std::toupper);
400  std::string::size_type pos = line.find('#');
401  if (pos != std::string::npos)
402  line.resize(pos);
403 
404  if (line.empty())
405  continue;
406 
407  if (!boost::algorithm::is_space()(line[0])) {
408  std::vector<std::string> tokens;
409  boost::split(tokens, line,
410  boost::algorithm::is_space(),
411  boost::token_compress_on);
412  if (!tokens.size())
413  continue;
414  block.clear();
415  if (tokens.size() < 2)
416  continue;
417  if (tokens[0] == "BLOCK") {
418  block = tokens[1];
419  blocks.insert(block);
420  continue;
421  }
422 
423  if (tokens[0] == "DECAY") {
424  block = "DECAY";
425  blocks.insert(block);
426  }
427  } else if (block == "MODSEL") {
428  std::istringstream ss(line);
429  ss >> model >> subModel;
430  } else if (block == "SMINPUTS") {
431  std::istringstream ss(line);
432  int index;
433  double value;
434  ss >> index >> value;
435  switch(index) {
436  case 1:
437  pydat1_.paru[103 - 1] = 1.0 / value;
438  break;
439  case 2:
440  pydat1_.paru[105 - 1] = value;
441  break;
442  case 4:
443  pydat2_.pmas[0][23 - 1] = value;
444  break;
445  case 6:
446  pydat2_.pmas[0][6 - 1] = value;
447  break;
448  case 7:
449  pydat2_.pmas[0][15 - 1] = value;
450  break;
451  }
452  }
453  }
454  file.close();
455 
456  if (blocks.count("SMINPUTS"))
457  pydat1_.paru[102 - 1] = 0.5 - std::sqrt(0.25 -
458  pydat1_.paru[0] * M_SQRT1_2 *
459  pydat1_.paru[103 - 1] / pydat1_.paru[105 - 1] /
460  (pydat2_.pmas[0][23 - 1] * pydat2_.pmas[0][23 - 1]));
461 
462 /*
463  int unit = 24;
464  fioopn_(&unit, fname, std::strlen(fname));
465  std::remove(fname);
466 
467  call_pygive("IMSS(21)=24");
468  call_pygive("IMSS(22)=24");
469 */
470 
471  openSLHA( fname ) ;
472  std::remove( fname );
473 
474  if (model ||
475  blocks.count("HIGMIX") ||
476  blocks.count("SBOTMIX") ||
477  blocks.count("STOPMIX") ||
478  blocks.count("STAUMIX") ||
479  blocks.count("AMIX") ||
480  blocks.count("NMIX") ||
481  blocks.count("UMIX") ||
482  blocks.count("VMIX"))
483  call_pyslha(1);
484  if (model ||
485  blocks.count("QNUMBERS") ||
486  blocks.count("PARTICLE") ||
487  blocks.count("MINPAR") ||
488  blocks.count("EXTPAR") ||
489  blocks.count("SMINPUTS") ||
490  blocks.count("SMINPUTS"))
491  call_pyslha(0);
492  if (blocks.count("MASS"))
493  call_pyslha(5, 0);
494  if (blocks.count("DECAY"))
495  call_pyslha(2);
496 
497  return ;
498 
499 }
T getParameter(std::string const &) const
static void call_pyupda(int opt, int iunit)
int i
Definition: DBlmapReader.cc:9
void pyupda_(int *, int *)
void fioopn_(int *unit, const char *line, int length)
void fiocls_(int *unit)
bool call_pygive(const std::string &line)
#define NULL
Definition: scimark2.h:8
void pyjoin_(int &njoin, int ijoin[])
void pylist_(int *)
uint16_t size_type
void pygive_(const char *, int)
void fioopnw_(int *unit, const char *line, int length)
CLHEP::HepRandomEngine & getEngineReference()
void pyslha_(int *, int *, int *)
tuple maxSize
&#39;/store/data/Commissioning08/BeamHalo/RECO/StuffAlmostToP5_v1/000/061/642/10A0FE34-A67D-DD11-AD05-000...
string unit
Definition: csvLumiCalc.py:46
T sqrt(T t)
Definition: SSEVec.h:46
void setSLHAFromHeader(const std::vector< std::string > &lines)
std::vector< std::string > fParamPYUPDA
static int call_pyslha(int mupda, int kforig=0)
virtual void enter()
virtual void enter()
void setPYUPDAParams(bool afterPyinit)
#define end
Definition: vmac.h:38
std::vector< std::string > fParamGeneral
static Pythia6Service * fPythia6Owner
#define SETCSAPARBUFSIZE
tuple out
Definition: dbtoconf.py:99
void txgive_init_(void)
int pycomp_(int &)
CLHEP::HepRandomEngine * fRandomEngine
std::vector< std::string > fParamCSA
void openSLHA(const char *)
list blocks
Definition: gather_cfg.py:90
struct gen::@402 pydat1_
string fname
main script
void py1ent_(int &ip, int &kf, double &pe, double &the, double &phi)
void openPYUPDA(const char *, bool write_file)
tuple cout
Definition: gather_cfg.py:121
std::vector< std::string > fParamSLHA
std::string fullPath() const
Definition: FileInPath.cc:171
double pyr_(int *idummy)
void pyedit_(int *mode)
void txgive_(const char *, int)
class Geom::Polar2Cartesian __attribute__
double split
Definition: MVATrainer.cc:139
void pyexec_()