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