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