CMS 3D CMS Logo

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  using namespace gen;
32  int dummy = 0;
33  double dummy2 = 0;
34  char* dummy3 = nullptr;
35  pyexec_();
36  pystat_(nullptr);
37  pyjoin_(dummy, &dummy);
38  py1ent_(dummy, dummy, dummy2, dummy2, dummy2);
39  pygive_(dummy3, dummy);
40  pycomp_(dummy);
41  pylist_(nullptr);
42  pyevnt_();
43  pyedit_();
44 }
45 
46 extern "C" {
47 void fioopn_(int* unit, const char* line, int length);
48 void fioopnw_(int* unit, const char* line, int length);
49 void fiocls_(int* unit);
50 void pyslha_(int*, int*, int*);
51 static int call_pyslha(int mupda, int kforig = 0) {
52  int iretrn = 0;
53  pyslha_(&mupda, &kforig, &iretrn);
54  return iretrn;
55 }
56 
57 void pyupda_(int*, int*);
58 static void call_pyupda(int opt, int iunit) { pyupda_(&opt, &iunit); }
59 
60 double gen::pyr_(int* idummy) {
61  // getInstance will throw if no one used enter/leave
62  // or this is the wrong caller class, like e.g. Herwig6Instance
63  Pythia6Service* service = FortranInstance::getInstance<Pythia6Service>();
64  return service->fRandomEngine->flat();
65 }
66 }
67 
68 using namespace gen;
69 using namespace edm;
70 
72 
73 Pythia6Service::Pythia6Service() : fRandomEngine(nullptr), fUnitSLHA(24), fUnitPYUPDA(25) {}
74 
75 Pythia6Service::Pythia6Service(const ParameterSet& ps) : fRandomEngine(nullptr), fUnitSLHA(24), fUnitPYUPDA(25) {
76  if (fPythia6Owner)
77  throw cms::Exception("PythiaError") << "Two Pythia6Service instances claiming Pythia6 ownership." << std::endl;
78 
79  fPythia6Owner = this;
80 
81  /*
82  ParameterCollector collector(ps.getParameter<edm::ParameterSet>("PythiaParameters"));
83 
84  fParamGeneral.clear();
85  fParamCSA.clear();
86  fParamSLHA.clear();
87 
88  fParamGeneral = std::vector<std::string>(collector.begin(), collector.end());
89  fParamCSA = std::vector<std::string>(collector.begin("CSAParameters"), collector.end());
90  fParamSLHA = std::vector<std::string>(collector.begin("SLHAParameters"), collector.end());
91 */
92 
93  // Set PYTHIA parameters in a single ParameterSet
94  //
95  edm::ParameterSet pythia_params = ps.getParameter<edm::ParameterSet>("PythiaParameters");
96 
97  // read and sort Pythia6 cards
98  //
99  std::vector<std::string> setNames = pythia_params.getParameter<std::vector<std::string> >("parameterSets");
100 
101  // std::vector<std::string> paramLines;
102  fParamGeneral.clear();
103  fParamCSA.clear();
104  fParamSLHA.clear();
105  fParamPYUPDA.clear();
106 
107  for (std::vector<std::string>::const_iterator iter = setNames.begin(); iter != setNames.end(); ++iter) {
108  std::vector<std::string> lines = pythia_params.getParameter<std::vector<std::string> >(*iter);
109 
110  for (std::vector<std::string>::const_iterator line = lines.begin(); line != lines.end(); ++line) {
111  if (line->substr(0, 7) == "MRPY(1)")
112  throw cms::Exception("PythiaError") << "Attempted to set random number"
113  " using Pythia command 'MRPY(1)'."
114  " Please use the"
115  " RandomNumberGeneratorService."
116  << std::endl;
117 
118  if (*iter == "CSAParameters") {
119  fParamCSA.push_back(*line);
120  } else if (*iter == "SLHAParameters") {
121  fParamSLHA.push_back(*line);
122  } else if (*iter == "PYUPDAParameters") {
123  fParamPYUPDA.push_back(*line);
124  } else {
125  fParamGeneral.push_back(*line);
126  }
127  }
128  }
129 }
130 
132  if (fPythia6Owner == this)
133  fPythia6Owner = nullptr;
134 
135  fParamGeneral.clear();
136  fParamCSA.clear();
137  fParamSLHA.clear();
138  fParamPYUPDA.clear();
139 }
140 
143 
144  if (!fPythia6Owner) {
145  edm::LogInfo("Generator|Pythia6Interface") << "gen::Pythia6Service is going to initialise Pythia, as no other "
146  "instace has done so yet, and Pythia service routines have been "
147  "requested by a dummy instance."
148  << std::endl;
149 
150  call_pygive("MSTU(12)=12345");
151  call_pyinit("NONE", "", "", 0.0);
152 
153  fPythia6Owner = this;
154  }
155 }
156 
158  // now pass general config cards
159  //
160  for (std::vector<std::string>::const_iterator iter = fParamGeneral.begin(); iter != fParamGeneral.end(); ++iter) {
161  if (!call_pygive(*iter))
162  throw cms::Exception("PythiaError") << "Pythia did not accept \"" << *iter << "\"." << std::endl;
163  }
164 
165  return;
166 }
167 
169 #define SETCSAPARBUFSIZE 514
170  char buf[SETCSAPARBUFSIZE];
171 
172  txgive_init_();
173  for (std::vector<std::string>::const_iterator iter = fParamCSA.begin(); iter != fParamCSA.end(); ++iter) {
174  // Null pad the string should not be needed because it uses
175  // read, which will look for \n, but just in case...
176  for (size_t i = 0; i < SETCSAPARBUFSIZE; ++i)
177  buf[i] = ' ';
178  // Skip empty parameters.
179  if (iter->length() <= 0)
180  continue;
181  // Limit the size of the string to something which fits the buffer.
182  size_t maxSize = iter->length() > (SETCSAPARBUFSIZE - 2) ? (SETCSAPARBUFSIZE - 2) : iter->length();
183  strncpy(buf, iter->c_str(), maxSize);
184  // Add extra \n if missing, otherwise "read" continues reading.
185  if (buf[maxSize - 1] != '\n') {
186  buf[maxSize] = '\n';
187  // Null terminate in case the string is passed back to C.
188  // Not sure that is actually needed.
189  buf[maxSize + 1] = 0;
190  }
191  txgive_(buf, iter->length());
192  }
193 
194  return;
195 #undef SETCSAPARBUFSIZE
196 }
197 
198 void Pythia6Service::openSLHA(const char* file) {
199  std::ostringstream pyCard1;
200  pyCard1 << "IMSS(21)=" << fUnitSLHA;
201  call_pygive(pyCard1.str());
202  std::ostringstream pyCard2;
203  pyCard2 << "IMSS(22)=" << fUnitSLHA;
204  call_pygive(pyCard2.str());
205 
206  fioopn_(&fUnitSLHA, file, strlen(file));
207 
208  return;
209 }
210 
211 void Pythia6Service::openPYUPDA(const char* file, bool write_file) {
212  if (write_file) {
213  std::cout << "=== WRITING PYUPDA FILE " << file << " ===" << std::endl;
214  fioopnw_(&fUnitPYUPDA, file, strlen(file));
215  // Write Pythia particle table to this card file.
217  } else {
218  std::cout << "=== READING PYUPDA FILE " << file << " ===" << std::endl;
219  fioopn_(&fUnitPYUPDA, file, strlen(file));
220  // Update Pythia particle table with this card file.
222  }
223 
224  return;
225 }
226 
228  fiocls_(&fUnitSLHA);
229 
230  return;
231 }
232 
235 
236  return;
237 }
238 
240  for (std::vector<std::string>::const_iterator iter = fParamSLHA.begin(); iter != fParamSLHA.end(); iter++) {
241  if (iter->find("SLHAFILE", 0) == std::string::npos)
242  continue;
243  std::string::size_type start = iter->find_first_of("=") + 1;
244  std::string::size_type end = iter->length() - 1;
245  std::string::size_type temp = iter->find_first_of("'", start);
246  if (temp != std::string::npos) {
247  start = temp + 1;
248  end = iter->find_last_of("'") - 1;
249  }
250  start = iter->find_first_not_of(" ", start);
251  end = iter->find_last_not_of(" ", end);
252  //std::cout << " start, end = " << start << " " << end << std::endl;
253  std::string shortfile = iter->substr(start, end - start + 1);
254  FileInPath f1(shortfile);
255  std::string file = f1.fullPath();
256 
257  /*
258  //
259  // override what might have be given via the external config
260  //
261  std::ostringstream pyCard ;
262  pyCard << "IMSS(21)=" << fUnitSLHA;
263  call_pygive( pyCard.str() );
264  pyCard << "IMSS(22)=" << fUnitSLHA;
265  call_pygive( pyCard.str() );
266 
267  fioopn_( &fUnitSLHA, file.c_str(), file.length() );
268 */
269 
270  openSLHA(file.c_str());
271  }
272 
273  return;
274 }
275 
276 void Pythia6Service::setPYUPDAParams(bool afterPyinit) {
277  std::string shortfile;
278  bool write_file = false;
279  bool usePostPyinit = false;
280 
281  // std::cout<<"=== CALLING setPYUPDAParams === "<<afterPyinit<<" "<<fParamPYUPDA.size()<<std::endl;
282 
283  // This assumes that PYUPDAFILE only appears once ...
284 
285  for (std::vector<std::string>::const_iterator iter = fParamPYUPDA.begin(); iter != fParamPYUPDA.end(); iter++) {
286  // std::cout<<"PYUPDA check "<<*iter<<std::endl;
287  if (iter->find("PYUPDAFILE", 0) != std::string::npos) {
288  std::string::size_type start = iter->find_first_of("=") + 1;
289  std::string::size_type end = iter->length() - 1;
290  std::string::size_type temp = iter->find_first_of("'", start);
291  if (temp != std::string::npos) {
292  start = temp + 1;
293  end = iter->find_last_of("'") - 1;
294  }
295  start = iter->find_first_not_of(" ", start);
296  end = iter->find_last_not_of(" ", end);
297  //std::cout << " start, end = " << start << " " << end << std::endl;
298  shortfile = iter->substr(start, end - start + 1);
299  } else if (iter->find("PYUPDAWRITE", 0) != std::string::npos) {
300  write_file = true;
301  } else if (iter->find("PYUPDApostPYINIT", 0) != std::string::npos) {
302  usePostPyinit = true;
303  }
304  }
305 
306  if (!shortfile.empty()) {
308  if (write_file) {
309  file = shortfile;
310  } else {
311  // If reading, get full path to file and require it to exist.
312  FileInPath f1(shortfile);
313  file = f1.fullPath();
314  }
315 
316  if (afterPyinit == usePostPyinit || (write_file && afterPyinit)) {
317  openPYUPDA(file.c_str(), write_file);
318  }
319  }
320 
321  return;
322 }
323 
324 void Pythia6Service::setSLHAFromHeader(const std::vector<std::string>& lines) {
325  std::set<std::string> blocks;
326  unsigned int model = 0, subModel = 0;
327 
328  std::string fnamest = boost::filesystem::unique_path().string();
329  const char* fname = fnamest.c_str();
332  for (std::vector<std::string>::const_iterator iter = lines.begin(); iter != lines.end(); ++iter) {
333  file << *iter;
334 
335  std::string line = *iter;
336  std::transform(line.begin(), line.end(), line.begin(), (int (*)(int))std::toupper);
337  std::string::size_type pos = line.find('#');
338  if (pos != std::string::npos)
339  line.resize(pos);
340 
341  if (line.empty())
342  continue;
343 
344  if (!boost::algorithm::is_space()(line[0])) {
345  std::vector<std::string> tokens;
346  boost::split(tokens, line, boost::algorithm::is_space(), boost::token_compress_on);
347  if (tokens.empty())
348  continue;
349  block.clear();
350  if (tokens.size() < 2)
351  continue;
352  if (tokens[0] == "BLOCK") {
353  block = tokens[1];
354  blocks.insert(block);
355  continue;
356  }
357 
358  if (tokens[0] == "DECAY") {
359  block = "DECAY";
360  blocks.insert(block);
361  }
362  } else if (block == "MODSEL") {
363  std::istringstream ss(line);
364  ss >> model >> subModel;
365  } else if (block == "SMINPUTS") {
366  std::istringstream ss(line);
367  int index;
368  double value;
369  ss >> index >> value;
370  switch (index) {
371  case 1:
372  pydat1_.paru[103 - 1] = 1.0 / value;
373  break;
374  case 2:
375  pydat1_.paru[105 - 1] = value;
376  break;
377  case 4:
378  pydat2_.pmas[0][23 - 1] = value;
379  break;
380  case 6:
381  pydat2_.pmas[0][6 - 1] = value;
382  break;
383  case 7:
384  pydat2_.pmas[0][15 - 1] = value;
385  break;
386  }
387  }
388  }
389  file.close();
390 
391  if (blocks.count("SMINPUTS"))
392  pydat1_.paru[102 - 1] =
393  0.5 - std::sqrt(0.25 - pydat1_.paru[0] * M_SQRT1_2 * pydat1_.paru[103 - 1] / pydat1_.paru[105 - 1] /
394  (pydat2_.pmas[0][23 - 1] * pydat2_.pmas[0][23 - 1]));
395 
396  /*
397  int unit = 24;
398  fioopn_(&unit, fname, std::strlen(fname));
399  std::remove(fname);
400 
401  call_pygive("IMSS(21)=24");
402  call_pygive("IMSS(22)=24");
403 */
404 
405  openSLHA(fname);
407 
408  if (model || blocks.count("HIGMIX") || blocks.count("SBOTMIX") || blocks.count("STOPMIX") ||
409  blocks.count("STAUMIX") || blocks.count("AMIX") || blocks.count("NMIX") || blocks.count("UMIX") ||
410  blocks.count("VMIX"))
411  call_pyslha(1);
412  if (model || blocks.count("QNUMBERS") || blocks.count("PARTICLE") || blocks.count("MINPAR") ||
413  blocks.count("EXTPAR") || blocks.count("SMINPUTS") || blocks.count("SMINPUTS"))
414  call_pyslha(0);
415  if (blocks.count("MASS"))
416  call_pyslha(5, 0);
417  if (blocks.count("DECAY"))
418  call_pyslha(2);
419 
420  return;
421 }
gen::txgive_init_
void txgive_init_(void)
gen::Pythia6Service::fParamCSA
std::vector< std::string > fParamCSA
Definition: Pythia6Service.h:56
gen::Pythia6Service::openSLHA
void openSLHA(const char *)
Definition: Pythia6Service.cc:198
service
Definition: service.py:1
mps_fire.i
i
Definition: mps_fire.py:355
start
Definition: start.py:1
gen::Pythia6Service::fParamGeneral
std::vector< std::string > fParamGeneral
Definition: Pythia6Service.h:55
MessageLogger.h
gen::FortranInstance::enter
virtual void enter()
Definition: FortranInstance.cc:43
gen::pycomp_
int pycomp_(int &)
SETCSAPARBUFSIZE
#define SETCSAPARBUFSIZE
gen::Pythia6Service::fPythia6Owner
static Pythia6Service * fPythia6Owner
Definition: Pythia6Service.h:62
pyslha_
void pyslha_(int *, int *, int *)
edm
HLT enums.
Definition: AlignableModifier.h:19
gen::pyr_
double pyr_(int *idummy)
Definition: Pythia6Service.cc:60
gather_cfg.cout
cout
Definition: gather_cfg.py:144
pos
Definition: PixelAliasList.h:18
edm::LogInfo
Definition: MessageLogger.h:254
Pythia6Declarations.h
gen::Pythia6Service::fUnitSLHA
int fUnitSLHA
Definition: Pythia6Service.h:59
gen::Pythia6Service::setPYUPDAParams
void setPYUPDAParams(bool afterPyinit)
Definition: Pythia6Service.cc:276
cms::dd::split
std::vector< std::string_view > split(std::string_view, const char *)
gen::Pythia6Service::setSLHAParams
void setSLHAParams()
Definition: Pythia6Service.cc:239
groupFilesInBlocks.temp
list temp
Definition: groupFilesInBlocks.py:142
gen::pydat1_
struct gen::@693 pydat1_
runTheMatrix.opt
opt
Definition: runTheMatrix.py:280
ReggeGribovPartonMC_EposLHC_2760GeV_PbPb_cfi.model
model
Definition: ReggeGribovPartonMC_EposLHC_2760GeV_PbPb_cfi.py:11
end
#define end
Definition: vmac.h:39
gen::Pythia6Service::setGeneralParams
void setGeneralParams()
Definition: Pythia6Service.cc:157
gen::Pythia6Service::openPYUPDA
void openPYUPDA(const char *, bool write_file)
Definition: Pythia6Service.cc:211
FileInPath.h
gen::pyexec_
void pyexec_()
gen::py1ent_
void py1ent_(int &ip, int &kf, double &pe, double &the, double &phi)
gen::Pythia6Service::closeSLHA
void closeSLHA()
Definition: Pythia6Service.cc:227
contentValuesCheck.ss
ss
Definition: contentValuesCheck.py:33
edm::FileInPath
Definition: FileInPath.h:64
trigger::size_type
uint16_t size_type
Definition: TriggerTypeDefs.h:18
gen::Pythia6Service::setCSAParams
void setCSAParams()
Definition: Pythia6Service.cc:168
mathSSE::sqrt
T sqrt(T t)
Definition: SSEVec.h:19
pyupda_
void pyupda_(int *, int *)
HcalDetIdTransform::transform
unsigned transform(const HcalDetId &id, unsigned transformCode)
Definition: HcalDetIdTransform.cc:7
gen::pyjoin_
void pyjoin_(int &njoin, int ijoin[])
gen
Definition: PythiaDecays.h:13
gen::Pythia6Service::enter
void enter() override
Definition: Pythia6Service.cc:141
AlCaHLTBitMon_QueryRunRegistry.string
string
Definition: AlCaHLTBitMon_QueryRunRegistry.py:256
edm::ParameterSet
Definition: ParameterSet.h:36
__attribute__
__attribute__((visibility("hidden"))) void dummy()
Definition: Pythia6Service.cc:30
groupFilesInBlocks.lines
lines
Definition: groupFilesInBlocks.py:95
pyedit_
void pyedit_(void)
createfilelist.int
int
Definition: createfilelist.py:10
FrontierConditions_GlobalTag_cff.file
file
Definition: FrontierConditions_GlobalTag_cff.py:13
gen::Pythia6Service::fParamSLHA
std::vector< std::string > fParamSLHA
Definition: Pythia6Service.h:57
gen::Pythia6Service::fParamPYUPDA
std::vector< std::string > fParamPYUPDA
Definition: Pythia6Service.h:58
fioopn_
void fioopn_(int *unit, const char *line, int length)
groupFilesInBlocks.block
block
Definition: groupFilesInBlocks.py:150
fioopnw_
void fioopnw_(int *unit, const char *line, int length)
visDQMUpload.buf
buf
Definition: visDQMUpload.py:154
unit
Basic3DVector unit() const
Definition: Basic3DVectorLD.h:162
call_pyupda
static void call_pyupda(int opt, int iunit)
Definition: Pythia6Service.cc:58
alignmentValidation.fname
string fname
main script
Definition: alignmentValidation.py:959
edm::ParameterSet::getParameter
T getParameter(std::string const &) const
gen::Pythia6Service::fUnitPYUPDA
int fUnitPYUPDA
Definition: Pythia6Service.h:60
gen::pylist_
void pylist_(int *)
reco_skim_cfg_mod.maxSize
maxSize
Definition: reco_skim_cfg_mod.py:154
gen::Pythia6Service::closePYUPDA
void closePYUPDA()
Definition: Pythia6Service.cc:233
relativeConstraints.value
value
Definition: relativeConstraints.py:53
Exception
Definition: hltDiff.cc:246
MatrixUtil.remove
def remove(d, key, TELL=False)
Definition: MatrixUtil.py:212
call_pyslha
static int call_pyslha(int mupda, int kforig=0)
Definition: Pythia6Service.cc:51
Pythia6Service.h
gen::Pythia6Service::setSLHAFromHeader
void setSLHAFromHeader(const std::vector< std::string > &lines)
Definition: Pythia6Service.cc:324
AlignmentPI::index
index
Definition: AlignmentPayloadInspectorHelper.h:46
funct::void
TEMPL(T2) struct Divides void
Definition: Factorize.h:29
fiocls_
void fiocls_(int *unit)
MillePedeFileConverter_cfg.out
out
Definition: MillePedeFileConverter_cfg.py:31
gen::txgive_
void txgive_(const char *, int)
cms::Exception
Definition: Exception.h:70
gen::Pythia6Service
Definition: Pythia6Service.h:24
ParameterSet.h
dummy
Definition: DummySelector.h:38
DeadROC_duringRun.f1
f1
Definition: DeadROC_duringRun.py:219
mps_splice.line
line
Definition: mps_splice.py:76
pileupReCalc_HLTpaths.trunc
trunc
Definition: pileupReCalc_HLTpaths.py:144
gen::pygive_
void pygive_(const char *, int)
gen::call_pygive
bool call_pygive(const std::string &line)
Definition: ExhumeHadronizer.cc:64
gather_cfg.blocks
blocks
Definition: gather_cfg.py:90
gen::Pythia6Service::Pythia6Service
Pythia6Service()
Definition: Pythia6Service.cc:73
gen::Pythia6Service::~Pythia6Service
~Pythia6Service() override
Definition: Pythia6Service.cc:131