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