test
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 #include <boost/filesystem.hpp>
14 
15 #include "CLHEP/Random/RandomEngine.h"
16 
18 
21 
24 // #include "GeneratorInterface/Core/interface/ParameterCollector.h"
25 
26 // This will force the symbols below to be kept, even in the case pythia6
27 // is an archive library.
28 //extern "C" void pyexec_(void);
29 extern "C" void pyedit_(void);
30 __attribute__((visibility("hidden"))) void dummy()
31 {
32  using namespace gen;
33  int dummy = 0;
34  double dummy2 = 0;
35  char * dummy3 = 0;
36  pyexec_();
37  pystat_(0);
38  pyjoin_(dummy, &dummy);
39  py1ent_(dummy, dummy, dummy2, dummy2, dummy2);
40  pygive_(dummy3, dummy);
41  pycomp_(dummy);
42  pylist_(0);
43  pyevnt_();
44  pyedit_();
45 }
46 
47 extern "C"
48 {
49  void fioopn_( int* unit, const char* line, int length );
50  void fioopnw_( int* unit, const char* line, int length );
51  void fiocls_( int* unit );
52  void pyslha_( int*, int*, int* );
53  static int call_pyslha(int mupda, int kforig = 0)
54  {
55  int iretrn = 0;
56  pyslha_(&mupda, &kforig, &iretrn);
57  return iretrn;
58  }
59 
60  void pyupda_(int*, int*);
61  static void call_pyupda( int opt, int iunit ){
62  pyupda_( &opt, &iunit );
63  }
64 
65  double gen::pyr_(int *idummy)
66  {
67  // getInstance will throw if no one used enter/leave
68  // or this is the wrong caller class, like e.g. Herwig6Instance
69  Pythia6Service* service = FortranInstance::getInstance<Pythia6Service>();
70  return service->fRandomEngine->flat();
71  }
72 }
73 
74 using namespace gen;
75 using namespace edm;
76 
78 
80  : fRandomEngine(nullptr), fUnitSLHA(24), fUnitPYUPDA(25)
81 {
82 }
83 
85  : fRandomEngine(nullptr), fUnitSLHA(24), fUnitPYUPDA(25)
86 {
87  if (fPythia6Owner)
88  throw cms::Exception("PythiaError") <<
89  "Two Pythia6Service instances claiming Pythia6 ownership." <<
90  std::endl;
91 
92  fPythia6Owner = this;
93 
94 /*
95  ParameterCollector collector(ps.getParameter<edm::ParameterSet>("PythiaParameters"));
96 
97  fParamGeneral.clear();
98  fParamCSA.clear();
99  fParamSLHA.clear();
100 
101  fParamGeneral = std::vector<std::string>(collector.begin(), collector.end());
102  fParamCSA = std::vector<std::string>(collector.begin("CSAParameters"), collector.end());
103  fParamSLHA = std::vector<std::string>(collector.begin("SLHAParameters"), collector.end());
104 */
105 
106 
107  // Set PYTHIA parameters in a single ParameterSet
108  //
109  edm::ParameterSet pythia_params =
110  ps.getParameter<edm::ParameterSet>("PythiaParameters") ;
111 
112  // read and sort Pythia6 cards
113  //
114  std::vector<std::string> setNames =
115  pythia_params.getParameter<std::vector<std::string> >("parameterSets");
116 
117  // std::vector<std::string> paramLines;
118  fParamGeneral.clear();
119  fParamCSA.clear();
120  fParamSLHA.clear();
121  fParamPYUPDA.clear();
122 
123 
124  for(std::vector<std::string>::const_iterator iter = setNames.begin();
125  iter != setNames.end(); ++iter)
126  {
127  std::vector<std::string> lines =
128  pythia_params.getParameter< std::vector<std::string> >(*iter);
129 
130  for(std::vector<std::string>::const_iterator line = lines.begin();
131  line != lines.end(); ++line )
132  {
133  if (line->substr(0, 7) == "MRPY(1)")
134  throw cms::Exception("PythiaError") <<
135  "Attempted to set random number"
136  " using Pythia command 'MRPY(1)'."
137  " Please use the"
138  " RandomNumberGeneratorService." <<
139  std::endl;
140 
141  if ( *iter == "CSAParameters" )
142  {
143  fParamCSA.push_back(*line);
144  }
145  else if ( *iter == "SLHAParameters" )
146  {
147  fParamSLHA.push_back(*line);
148  }
149  else if ( *iter == "PYUPDAParameters" )
150  {
151  fParamPYUPDA.push_back(*line);
152  }
153  else
154  {
155  fParamGeneral.push_back(*line);
156  }
157  }
158  }
159 }
160 
162 {
163  if (fPythia6Owner == this)
164  fPythia6Owner = 0;
165 
166  fParamGeneral.clear();
167  fParamCSA.clear();
168  fParamSLHA.clear();
169  fParamPYUPDA.clear();
170 }
171 
173 {
175 
176  if (!fPythia6Owner) {
177  edm::LogInfo("Generator|Pythia6Interface") <<
178  "gen::Pythia6Service is going to initialise Pythia, as no other "
179  "instace has done so yet, and Pythia service routines have been "
180  "requested by a dummy instance." << std::endl;
181 
182  call_pygive("MSTU(12)=12345");
183  call_pyinit("NONE", "", "", 0.0);
184 
185  fPythia6Owner = this;
186  }
187 }
188 
190 {
191  // now pass general config cards
192  //
193  for(std::vector<std::string>::const_iterator iter = fParamGeneral.begin();
194  iter != fParamGeneral.end(); ++iter)
195  {
196  if (!call_pygive(*iter))
197  throw cms::Exception("PythiaError")
198  << "Pythia did not accept \""
199  << *iter << "\"." << std::endl;
200  }
201 
202  return ;
203 }
204 
206 {
207 #define SETCSAPARBUFSIZE 514
208  char buf[SETCSAPARBUFSIZE];
209 
210  txgive_init_();
211  for(std::vector<std::string>::const_iterator iter = fParamCSA.begin();
212  iter != fParamCSA.end(); ++iter)
213  {
214  // Null pad the string should not be needed because it uses
215  // read, which will look for \n, but just in case...
216  for (size_t i = 0; i < SETCSAPARBUFSIZE; ++i)
217  buf[i] = ' ';
218  // Skip empty parameters.
219  if (iter->length() <= 0)
220  continue;
221  // Limit the size of the string to something which fits the buffer.
222  size_t maxSize = iter->length() > (SETCSAPARBUFSIZE-2) ? (SETCSAPARBUFSIZE-2) : iter->length();
223  strncpy(buf, iter->c_str(), maxSize);
224  // Add extra \n if missing, otherwise "read" continues reading.
225  if (buf[maxSize-1] != '\n')
226  {
227  buf[maxSize] = '\n';
228  // Null terminate in case the string is passed back to C.
229  // Not sure that is actually needed.
230  buf[maxSize + 1] = 0;
231  }
232  txgive_(buf, iter->length() );
233  }
234 
235  return ;
236 #undef SETCSAPARBUFSIZE
237 }
238 
239 void Pythia6Service::openSLHA( const char* file )
240 {
241 
242  std::ostringstream pyCard1 ;
243  pyCard1 << "IMSS(21)=" << fUnitSLHA;
244  call_pygive( pyCard1.str() );
245  std::ostringstream pyCard2 ;
246  pyCard2 << "IMSS(22)=" << fUnitSLHA;
247  call_pygive( pyCard2.str() );
248 
249  fioopn_( &fUnitSLHA, file, strlen(file) );
250 
251  return;
252 
253 }
254 
255 void Pythia6Service::openPYUPDA( const char* file, bool write_file )
256 {
257 
258  if (write_file) {
259  std::cout<<"=== WRITING PYUPDA FILE "<<file<<" ==="<<std::endl;
260  fioopnw_( &fUnitPYUPDA, file, strlen(file) );
261  // Write Pythia particle table to this card file.
263  } else {
264  std::cout<<"=== READING PYUPDA FILE "<<file<<" ==="<<std::endl;
265  fioopn_( &fUnitPYUPDA, file, strlen(file) );
266  // Update Pythia particle table with this card file.
268  }
269 
270  return;
271 
272 }
273 
275 {
276 
277  fiocls_(&fUnitSLHA);
278 
279  return;
280 }
281 
283 {
284 
286 
287  return;
288 
289 }
290 
292 {
293  for (std::vector<std::string>::const_iterator iter = fParamSLHA.begin();
294  iter != fParamSLHA.end(); iter++ )
295  {
296 
297  if( iter->find( "SLHAFILE", 0 ) == std::string::npos ) continue;
298  std::string::size_type start = iter->find_first_of( "=" ) + 1;
299  std::string::size_type end = iter->length() - 1;
300  std::string::size_type temp = iter->find_first_of( "'", start );
301  if( temp != std::string::npos ) {
302  start = temp + 1;
303  end = iter->find_last_of( "'" ) - 1;
304  }
305  start = iter->find_first_not_of( " ", start );
306  end = iter->find_last_not_of( " ", end );
307  //std::cout << " start, end = " << start << " " << end << std::endl;
308  std::string shortfile = iter->substr( start, end - start + 1 );
309  FileInPath f1( shortfile );
310  std::string file = f1.fullPath();
311 
312 /*
313  //
314  // override what might have be given via the external config
315  //
316  std::ostringstream pyCard ;
317  pyCard << "IMSS(21)=" << fUnitSLHA;
318  call_pygive( pyCard.str() );
319  pyCard << "IMSS(22)=" << fUnitSLHA;
320  call_pygive( pyCard.str() );
321 
322  fioopn_( &fUnitSLHA, file.c_str(), file.length() );
323 */
324 
325  openSLHA( file.c_str() );
326 
327  }
328 
329  return;
330 }
331 
332 void Pythia6Service::setPYUPDAParams(bool afterPyinit)
333 {
334  std::string shortfile;
335  bool write_file = false;
336  bool usePostPyinit = false;
337 
338  // std::cout<<"=== CALLING setPYUPDAParams === "<<afterPyinit<<" "<<fParamPYUPDA.size()<<std::endl;
339 
340  // This assumes that PYUPDAFILE only appears once ...
341 
342  for (std::vector<std::string>::const_iterator iter = fParamPYUPDA.begin();
343  iter != fParamPYUPDA.end(); iter++ )
344  {
345  // std::cout<<"PYUPDA check "<<*iter<<std::endl;
346  if( iter->find( "PYUPDAFILE", 0 ) != std::string::npos ) {
347  std::string::size_type start = iter->find_first_of( "=" ) + 1;
348  std::string::size_type end = iter->length() - 1;
349  std::string::size_type temp = iter->find_first_of( "'", start );
350  if( temp != std::string::npos ) {
351  start = temp + 1;
352  end = iter->find_last_of( "'" ) - 1;
353  }
354  start = iter->find_first_not_of( " ", start );
355  end = iter->find_last_not_of( " ", end );
356  //std::cout << " start, end = " << start << " " << end << std::endl;
357  shortfile = iter->substr( start, end - start + 1 );
358  } else if ( iter->find( "PYUPDAWRITE", 0 ) != std::string::npos ) {
359  write_file = true;
360  } else if ( iter->find( "PYUPDApostPYINIT", 0 ) != std::string::npos ) {
361  usePostPyinit = true;
362  }
363  }
364 
365  if (!shortfile.empty()) {
367  if (write_file) {
368  file = shortfile;
369  } else {
370  // If reading, get full path to file and require it to exist.
371  FileInPath f1( shortfile );
372  file = f1.fullPath();
373  }
374 
375  if (afterPyinit == usePostPyinit || (write_file && afterPyinit)) {
376  openPYUPDA( file.c_str(), write_file );
377  }
378  }
379 
380  return;
381 }
382 
383 void Pythia6Service::setSLHAFromHeader( const std::vector<std::string> &lines )
384 {
385 
386  std::set<std::string> blocks;
387  unsigned int model = 0, subModel = 0;
388 
389  std::string fnamest = boost::filesystem::unique_path().string();
390  const char *fname = fnamest.c_str();
391  std::ofstream file(fname, std::fstream::out | std::fstream::trunc);
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
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)
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_()