CMS 3D CMS Logo

 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Pages
Herwig6Instance.cc
Go to the documentation of this file.
1 #include <iostream>
2 #include <sstream>
3 #include <cstdlib>
4 #include <cstring>
5 #include <cctype>
6 #include <string>
7 #include <cassert>
8 
9 #ifdef _POSIX_C_SOURCE
10 # include <sys/time.h>
11 # include <signal.h>
12 # include <setjmp.h>
13 #endif
14 
15 #include <CLHEP/Random/RandomEngine.h>
16 
17 #include <HepMC/HerwigWrapper.h>
18 
22 
25 
26 #include "params.inc"
27 
28 extern "C" void jminit_();
29 __attribute__((visibility("hidden"))) void dummy()
30 {
31  int dummyInt = 0;
32  jminit_();
33  jimmin_();
34  jminit_();
35  hwmsct_(&dummyInt);
36  jmefin_();
37 }
38 
39 // Added for reading in the paremeter files (orig. L. Sonnenschein)
40 extern "C" void lunread_(const char filename[], const int length);
41 
42 using namespace gen;
43 
44 // implementation for the Fortran callbacks from Herwig
45 
46 // this gets a random number from the currently running instance
47 // so, if the have separate instances for let's say decayers based on
48 // Herwig than the Herwig pp collision instance, we get independent
49 // random numbers. Also true for FastSim, since FastSim uses its own
50 // random numbers. This means FastSim needs take a Herwig6Instance
51 // instance of its own instead of calling into Herwig directly.
52 double gen::hwrgen_(int *idummy)
53 {
54  Herwig6Instance *instance = FortranInstance::getInstance<Herwig6Instance>();
55  assert(instance != 0);
56  assert(instance->randomEngine != 0);
57  return instance->randomEngine->flat();
58 }
59 
60 void gen::cms_hwwarn_(char fn[6], int *code, int *exit)
61 {
62  std::string function(fn, fn + sizeof fn);
63  *exit = FortranInstance::getInstance<Herwig6Instance>()->hwwarn(function, *code);
64 }
65 
66 extern "C" {
67  void hwaend_()
68  {}
69 
70  void cmsending_(int *ecode)
71  {
72  throw cms::Exception("Herwig6Error")
73  << "Herwig6 stopped run with error code " << *ecode
74  << "." << std::endl;
75  }
76 }
77 
78 // Herwig6Instance methods
79 
82  timeoutPrivate(0)
83 {
84 }
85 
87 {
88 }
89 
90 // timeout tool
91 
92 #ifdef _POSIX_C_SOURCE
93 // some deep POSIX hackery to catch HERWIG sometimes (O(10k events) with
94 // complicated topologies) getting caught in and endless loop :-(
95 
97 {
98  Herwig6Instance *instance = FortranInstance::getInstance<Herwig6Instance>();
99  assert(instance != 0);
100  assert(instance->timeoutPrivate != 0);
101  siglongjmp(*(sigjmp_buf*)instance->timeoutPrivate, 1);
102 }
103 
104 bool Herwig6Instance::timeout(unsigned int secs, void (*fn)())
105 {
106  if (timeoutPrivate)
107  throw cms::Exception("ReentrancyProblem")
108  << "Herwig6Instance::timeout() called recursively."
109  << std::endl;
110  struct sigaction saOld;
111  std::memset(&saOld, 0, sizeof saOld);
112 
113  struct itimerval itv;
114  timerclear(&itv.it_value);
115  timerclear(&itv.it_interval);
116  itv.it_value.tv_sec = 0;
117  itv.it_interval.tv_sec = 0;
118  setitimer(ITIMER_VIRTUAL, &itv, NULL);
119 
120  sigset_t ss;
121  sigemptyset(&ss);
122  sigaddset(&ss, SIGVTALRM);
123 
124  sigprocmask(SIG_UNBLOCK, &ss, NULL);
125  sigprocmask(SIG_BLOCK, &ss, NULL);
126 
127  timeoutPrivate = new sigjmp_buf;
128  if (sigsetjmp(*(sigjmp_buf*)timeoutPrivate, 1)) {
129  delete (sigjmp_buf*)timeoutPrivate;
130  timeoutPrivate = 0;
131 
132  itv.it_value.tv_sec = 0;
133  itv.it_interval.tv_sec = 0;
134  setitimer(ITIMER_VIRTUAL, &itv, NULL);
135  sigprocmask(SIG_UNBLOCK, &ss, NULL);
136  return true;
137  }
138 
139  itv.it_value.tv_sec = secs;
140  itv.it_interval.tv_sec = secs;
141  setitimer(ITIMER_VIRTUAL, &itv, NULL);
142 
143  struct sigaction sa;
144  std::memset(&sa, 0, sizeof sa);
145  sa.sa_handler = &Herwig6Instance::_timeout_sighandler;
146  sa.sa_flags = SA_ONESHOT;
147  sigemptyset(&sa.sa_mask);
148 
149  sigaction(SIGVTALRM, &sa, &saOld);
150  sigprocmask(SIG_UNBLOCK, &ss, NULL);
151 
152  try {
153  fn();
154  } catch(...) {
155  delete (sigjmp_buf*)timeoutPrivate;
156  timeoutPrivate = 0;
157 
158  itv.it_value.tv_sec = 0;
159  itv.it_interval.tv_sec = 0;
160  setitimer(ITIMER_VIRTUAL, &itv, NULL);
161 
162  sigaction(SIGVTALRM, &saOld, NULL);
163 
164  throw;
165  }
166 
167  delete (sigjmp_buf*)timeoutPrivate;
168  timeoutPrivate = 0;
169 
170  itv.it_value.tv_sec = 0;
171  itv.it_interval.tv_sec = 0;
172  setitimer(ITIMER_VIRTUAL, &itv, NULL);
173 
174  sigaction(SIGVTALRM, &saOld, NULL);
175 
176  return false;
177 }
178 #else
179 bool Herwig6Instance::timeout(unsigned int secs, void (*fn)())
180 {
181  fn();
182  return false;
183 }
184 #endif
185 
186 bool Herwig6Instance::hwwarn(const std::string &fn, int code)
187 {
188  return false;
189 }
190 
191 // regular Herwig6Instance methods
192 
194 {
195  typedef std::istringstream::traits_type traits;
196 
197  const char *p = line.c_str(), *q;
198  p += std::strspn(p, " \t\r\n");
199 
200  for(q = p; std::isalnum(*q); q++);
201  std::string name(p, q - p);
202 
203  const ConfigParam *param;
204  for(param = configParams; param->name; param++)
205  if (name == param->name)
206  break;
207  if (!param->name)
208  return false;
209 
210  p = q + std::strspn(q, " \t\r\n");
211 
212  std::size_t pos = 0;
213  std::size_t mult = 1;
214  for(unsigned int i = 0; i < 3; i++) {
215  if (!param->dim[i].size)
216  break;
217 
218  if (*p++ != (i ? ',' : '('))
219  return false;
220 
221  p += std::strspn(p, " \t\r\n");
222 
223  for(q = p; std::isdigit(*q); q++);
224  std::istringstream ss(std::string(p, q - p));
225  std::size_t index;
226  ss >> index;
227  if (ss.bad() || ss.peek() != traits::eof())
228  return false;
229 
230  if (index < param->dim[i].offset)
231  return false;
232  index -= param->dim[i].offset;
233  if (index >= param->dim[i].size)
234  return false;
235 
236  p = q + std::strspn(q, " \t\r\n");
237 
238  pos += mult * index;
239  mult *= param->dim[i].size;
240  }
241 
242  if (param->dim[0].size) {
243  if (*p++ != ')')
244  return false;
245  p += std::strspn(p, " \t\r\n");
246  }
247 
248  if (*p++ != '=')
249  return false;
250  p += std::strspn(p, " \t\r\n");
251 
252  for(q = p; *q && (std::isalnum(*q) || std::strchr(".-+", *q)); q++);
253  std::istringstream ss(std::string(p, q - p));
254 
255  p = q + std::strspn(q, " \t\r\n");
256  if (*p && *p != '!')
257  return false;
258 
259  switch(param->type) {
260  case kInt: {
261  int value;
262  ss >> value;
263  if (ss.bad() || ss.peek() != traits::eof())
264  return false;
265 
266  ((int*)param->ptr)[pos] = value;
267  break;
268  }
269  case kDouble: {
270  double value;
271  ss >> value;
272  if (ss.bad() || ss.peek() != traits::eof())
273  return false;
274 
275  ((double*)param->ptr)[pos] = value;
276  break;
277  }
278  case kLogical: {
279  std::string value_;
280  ss >> value_;
281  if (ss.bad() || ss.peek() != traits::eof())
282  return false;
283 
284  for(std::string::iterator iter = value_.begin();
285  iter != value_.end(); ++iter)
286  *iter = std::tolower(*iter);
287  bool value;
288  if (value_ == "yes" || value_ == "true" || value_ == "1")
289  value = true;
290  else if (value_ == "no" || value_ == "false" || value_ == "0")
291  value = false;
292  else
293  return false;
294 
295  ((int*)param->ptr)[pos] = value;
296  break;
297  }
298  }
299 
300  return true;
301 }
302 
304 
305  edm::FileInPath fileAndPath( fileName );
306  // WARING : This will call HWWARN if file does not exist.
307  lunread_( fileAndPath.fullPath().c_str(),strlen(fileAndPath.fullPath().c_str()) );
308 
309  return;
310 }
311 
312 
CLHEP::HepRandomEngine * randomEngine
Definition: Dummies.cc:7
int i
Definition: DBlmapReader.cc:9
static PFTauRenderPlugin instance
void jmefin_(void)
bool timeout(unsigned int secs, void(*fn)())
static void _timeout_sighandler(int signr)
void openParticleSpecFile(const std::string fileName)
#define NULL
Definition: scimark2.h:8
#define nullptr
double p[5][pyjets_maxn]
void jminit_(void)
void cmsending_(int *ecode)
Definition: Dummies.cc:12
unsigned int offset(bool)
void hwaend_()
Definition: Dummies.cc:10
bool give(const std::string &line)
void jimmin_(void)
void cms_hwwarn_(char fn[6], int *, int *)
float __attribute__((vector_size(8))) float32x2_t
Definition: ExtVec.h:6
double hwmsct_(int *)
virtual bool hwwarn(const std::string &fn, int code)
tuple filename
Definition: lut2db_cfg.py:20
CLHEP::HepRandomEngine * randomEngine
void lunread_(const char filename[], const int length)
std::string fullPath() const
Definition: FileInPath.cc:165
double hwrgen_(int *)