CMS 3D CMS Logo

 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Pages
List of all members | Classes | Public Member Functions | Static Public Member Functions | Private Member Functions | Private Attributes
ExternalLHEProducer Class Reference

#include <Example/ExternalLHEProducer/src/ExternalLHEProducer.cc>

Inheritance diagram for ExternalLHEProducer:
edm::EDProducer edm::ProducerBase edm::ProductRegistryHelper

Classes

class  FileCloseSentry
 

Public Member Functions

 ExternalLHEProducer (const edm::ParameterSet &iConfig)
 
 ~ExternalLHEProducer ()
 
- Public Member Functions inherited from edm::EDProducer
 EDProducer ()
 
virtual ~EDProducer ()
 
- Public Member Functions inherited from edm::ProducerBase
 ProducerBase ()
 
void registerProducts (ProducerBase *, ProductRegistry *, ModuleDescription const &)
 
boost::function< void(const
BranchDescription &)> 
registrationCallback () const
 used by the fwk to register list of products More...
 
virtual ~ProducerBase ()
 

Static Public Member Functions

static void fillDescriptions (edm::ConfigurationDescriptions &descriptions)
 
- Static Public Member Functions inherited from edm::EDProducer
static const std::string & baseType ()
 
static void fillDescriptions (ConfigurationDescriptions &descriptions)
 
static void prevalidate (ConfigurationDescriptions &descriptions)
 

Private Member Functions

virtual void beginJob ()
 
virtual void beginLuminosityBlock (edm::LuminosityBlock &, edm::EventSetup const &)
 
virtual void beginRun (edm::Run &run, edm::EventSetup const &es)
 
int closeDescriptors (int preserve)
 
virtual void endJob ()
 
virtual void endLuminosityBlock (edm::LuminosityBlock &, edm::EventSetup const &)
 
virtual void endRun (edm::Run &, edm::EventSetup const &)
 
void executeScript ()
 
virtual void nextEvent ()
 
virtual void produce (edm::Event &, const edm::EventSetup &)
 
std::auto_ptr< std::string > readOutput ()
 

Private Attributes

std::vector< std::string > args_
 
uint32_t nEvents_
 
uint32_t npars_
 
std::string outputContents_
 
std::string outputFile_
 
boost::shared_ptr< lhef::LHEEventpartonLevel
 
std::auto_ptr< lhef::LHEReaderreader_
 
boost::shared_ptr
< lhef::LHERunInfo
runInfo
 
boost::shared_ptr
< lhef::LHERunInfo
runInfoLast
 
boost::ptr_deque
< LHERunInfoProduct
runInfoProducts
 
std::string scriptName_
 
bool wasMerged
 

Additional Inherited Members

- Public Types inherited from edm::EDProducer
typedef EDProducer ModuleType
 
typedef WorkerT< EDProducerWorkerType
 
- Public Types inherited from edm::ProducerBase
typedef
ProductRegistryHelper::TypeLabelList 
TypeLabelList
 
- Protected Member Functions inherited from edm::EDProducer
CurrentProcessingContext const * currentContext () const
 
- Protected Member Functions inherited from edm::ProducerBase
template<class TProducer , class TMethod >
void callWhenNewProductsRegistered (TProducer *iProd, TMethod iMethod)
 

Detailed Description

Description: [one line class summary]

Implementation: [Notes on implementation]

Definition at line 64 of file ExternalLHEProducer.cc.

Constructor & Destructor Documentation

ExternalLHEProducer::ExternalLHEProducer ( const edm::ParameterSet iConfig)
explicit

Definition at line 128 of file ExternalLHEProducer.cc.

References args_, and npars_.

128  :
129  scriptName_((iConfig.getParameter<edm::FileInPath>("scriptName")).fullPath().c_str()),
130  outputFile_(iConfig.getParameter<std::string>("outputFile")),
131  args_(iConfig.getParameter<std::vector<std::string> >("args")),
132  npars_(iConfig.getParameter<uint32_t>("numberOfParameters")),
133  nEvents_(iConfig.getParameter<uint32_t>("nEvents"))
134 {
135  if (npars_ != args_.size())
136  throw cms::Exception("ExternalLHEProducer") << "Problem with configuration: " << args_.size() << " script arguments given, expected " << npars_;
137  produces<LHEXMLStringProduct, edm::InRun>("LHEScriptOutput");
138 
139  produces<LHEEventProduct>();
140  produces<LHERunInfoProduct, edm::InRun>();
141 }
T getParameter(std::string const &) const
std::vector< std::string > args_
ExternalLHEProducer::~ExternalLHEProducer ( )

Definition at line 144 of file ExternalLHEProducer.cc.

145 {
146 }

Member Function Documentation

void ExternalLHEProducer::beginJob ( void  )
privatevirtual

Reimplemented from edm::EDProducer.

Definition at line 203 of file ExternalLHEProducer.cc.

204 {
205 }
void ExternalLHEProducer::beginLuminosityBlock ( edm::LuminosityBlock lumi,
edm::EventSetup const &   
)
privatevirtual

Reimplemented from edm::EDProducer.

Definition at line 447 of file ExternalLHEProducer.cc.

448 {
449 }
void ExternalLHEProducer::beginRun ( edm::Run run,
edm::EventSetup const &  es 
)
privatevirtual

Reimplemented from edm::EDProducer.

Definition at line 217 of file ExternalLHEProducer.cc.

References LHERunInfoProduct::addComment(), LHERunInfoProduct::addHeader(), args_, edm::hlt::Exception, executeScript(), edm::Service< T >::isAvailable(), LogDebug, edm::RandomNumberGenerator::mySeed(), nEvents_, nextEvent(), outputContents_, AlCaHLTBitMon_ParallelJobs::p, edm::Run::put(), reader_, readOutput(), runInfo, runInfoLast, runInfoProducts, createPayload::skip, and wasMerged.

218 {
219 
220  // pass the number of events as previous to last argument
221 
222  std::ostringstream eventStream;
223  eventStream << nEvents_;
224  args_.push_back(eventStream.str());
225 
226  // pass the random number generator seed as last argument
227 
229 
230  if ( ! rng.isAvailable()) {
231  throw cms::Exception("Configuration")
232  << "The ExternalLHEProducer module requires the RandomNumberGeneratorService\n"
233  "which is not present in the configuration file. You must add the service\n"
234  "in the configuration file if you want to run ExternalLHEProducer";
235  }
236  std::ostringstream randomStream;
237  randomStream << rng->mySeed();
238  args_.push_back(randomStream.str());
239 
240  for ( unsigned int iArg = 0; iArg < args_.size() ; iArg++ ) {
241  LogDebug("LHEInputArgs") << "arg [" << iArg << "] = " << args_[iArg];
242  }
243 
244  executeScript();
245  std::auto_ptr<std::string> localContents = readOutput();
246  outputContents_ = *localContents;
247  std::auto_ptr<LHEXMLStringProduct> p(new LHEXMLStringProduct(*localContents));
248  run.put(p, "LHEScriptOutput");
249 
250  // LHE C++ classes translation
251 
252  unsigned int skip = 0;
253  std::auto_ptr<lhef::LHEReader> thisRead( new lhef::LHEReader(outputContents_, skip ) );
254  reader_ = thisRead;
255 
256  nextEvent();
257  if (runInfoLast) {
259 
260  std::auto_ptr<LHERunInfoProduct> product(new LHERunInfoProduct(*runInfo->getHEPRUP()));
261  std::for_each(runInfo->getHeaders().begin(),
262  runInfo->getHeaders().end(),
263  boost::bind(&LHERunInfoProduct::addHeader,
264  product.get(), _1));
265  std::for_each(runInfo->getComments().begin(),
266  runInfo->getComments().end(),
267  boost::bind(&LHERunInfoProduct::addComment,
268  product.get(), _1));
269 
270  // keep a copy around in case of merging
271  runInfoProducts.push_back(new LHERunInfoProduct(*product));
272  wasMerged = false;
273 
274  run.put(product);
275 
276  runInfo.reset();
277  }
278 
279 }
#define LogDebug(id)
std::auto_ptr< std::string > readOutput()
void addHeader(const Header &header)
std::vector< std::string > args_
std::auto_ptr< lhef::LHEReader > reader_
boost::shared_ptr< lhef::LHERunInfo > runInfoLast
bool isAvailable() const
Definition: Service.h:47
boost::shared_ptr< lhef::LHERunInfo > runInfo
void addComment(const std::string &line)
void put(std::auto_ptr< PROD > product)
Put a new product.
Definition: Run.h:81
boost::ptr_deque< LHERunInfoProduct > runInfoProducts
virtual uint32_t mySeed() const =0
Exists for backward compatibility.
int ExternalLHEProducer::closeDescriptors ( int  preserve)
private

Definition at line 295 of file ExternalLHEProducer.cc.

References dir, linker::DIR, and NULL.

Referenced by executeScript().

296 {
297  int maxfd = 1024;
298  int fd;
299 #ifdef __linux__
300  DIR * dir;
301  struct dirent *dp;
302  maxfd = preserve;
303  if ((dir = opendir("/proc/self/fd"))) {
304  errno = 0;
305  while ((dp = readdir (dir)) != NULL) {
306  if ((strcmp(dp->d_name, ".") == 0) || (strcmp(dp->d_name, "..") == 0)) {
307  continue;
308  }
309  if (sscanf(dp->d_name, "%d", &fd) != 1) {
310  //throw cms::Exception("closeDescriptors") << "Found unexpected filename in /proc/self/fd: " << dp->d_name;
311  return -1;
312  }
313  if (fd > maxfd) {
314  maxfd = fd;
315  }
316  }
317  if (errno) {
318  //throw cms::Exception("closeDescriptors") << "Unable to determine the number of fd (errno=" << errno << ", " << strerror(errno) << ").";
319  return errno;
320  }
321  closedir(dir);
322  }
323 #endif
324  // TODO: assert for an unreasonable number of fds?
325  for (fd=3; fd<maxfd+1; fd++) {
326  if (fd != preserve)
327  close(fd);
328  }
329  return 0;
330 }
#define NULL
Definition: scimark2.h:8
list DIR
Definition: linker.py:124
dbl *** dir
Definition: mlp_gen.cc:35
void ExternalLHEProducer::endJob ( void  )
privatevirtual

Reimplemented from edm::EDProducer.

Definition at line 209 of file ExternalLHEProducer.cc.

References reader_.

209  {
210 
211  reader_.reset();
212 
213 }
std::auto_ptr< lhef::LHEReader > reader_
void ExternalLHEProducer::endLuminosityBlock ( edm::LuminosityBlock ,
edm::EventSetup const &   
)
privatevirtual

Reimplemented from edm::EDProducer.

Definition at line 453 of file ExternalLHEProducer.cc.

454 {
455 }
void ExternalLHEProducer::endRun ( edm::Run run,
edm::EventSetup const &  es 
)
privatevirtual

Reimplemented from edm::EDProducer.

Definition at line 283 of file ExternalLHEProducer.cc.

References edm::Run::put(), and runInfoProducts.

284 {
285 
286  if (!runInfoProducts.empty()) {
287  std::auto_ptr<LHERunInfoProduct> product(runInfoProducts.pop_front().release());
288  run.put(product);
289  }
290 
291 }
void put(std::auto_ptr< PROD > product)
Put a new product.
Definition: Run.h:81
boost::ptr_deque< LHERunInfoProduct > runInfoProducts
void ExternalLHEProducer::executeScript ( )
private

Definition at line 334 of file ExternalLHEProducer.cc.

References dir2webdir::argc, args_, dirstructure::argv, closeDescriptors(), edm::hlt::Exception, i, NULL, evf::utils::pid, pipe::pipe(), SiPixelLorentzAngle_cfi::read, scriptName_, ntuplemaker::status, and TablePrint::write.

Referenced by beginRun().

335 {
336 
337  // Fork a script, wait until it finishes.
338 
339  int rc = 0, rc2 = 0;
340  int filedes[2], fd_flags;
341  unsigned int argc;
342 
343  if (pipe(filedes)) {
344  throw cms::Exception("Unable to create a new pipe");
345  }
346  FileCloseSentry sentry1(filedes[0]), sentry2(filedes[1]);
347 
348  if ((fd_flags = fcntl(filedes[1], F_GETFD, NULL)) == -1) {
349  throw cms::Exception("ExternalLHEProducer") << "Failed to get pipe file descriptor flags (errno=" << rc << ", " << strerror(rc) << ")";
350  }
351  if (fcntl(filedes[1], F_SETFD, fd_flags | FD_CLOEXEC) == -1) {
352  throw cms::Exception("ExternalLHEProducer") << "Failed to set pipe file descriptor flags (errno=" << rc << ", " << strerror(rc) << ")";
353  }
354 
355  argc = 1 + args_.size();
356  // TODO: assert that we have a reasonable number of arguments
357  char **argv = new char *[argc+1];
358  argv[0] = strdup(scriptName_.c_str());
359  for (unsigned int i=1; i<argc; i++) {
360  argv[i] = strdup(args_[i-1].c_str());
361  }
362  argv[argc] = NULL;
363 
364  pid_t pid = fork();
365  if (pid == 0) {
366  // The child process
367  if (!(rc = closeDescriptors(filedes[1]))) {
368  execvp(argv[0], argv); // If execv returns, we have an error.
369  rc = errno;
370  }
371  while ((write(filedes[1], &rc, sizeof(int)) == -1) && (errno == EINTR)) {}
372  _exit(1);
373  }
374 
375  // Free the arg vector ASAP
376  for (unsigned int i=0; i<args_.size()+1; i++) {
377  free(argv[i]);
378  }
379  delete [] argv;
380 
381  if (pid == -1) {
382  throw cms::Exception("ForkException") << "Unable to fork a child (errno=" << errno << ", " << strerror(errno) << ")";
383  }
384 
385  close(filedes[1]);
386  // If the exec succeeds, the read will fail.
387  while (((rc2 = read(filedes[0], &rc, sizeof(int))) == -1) && (errno == EINTR)) { rc2 = 0; }
388  if ((rc2 == sizeof(int)) && rc) {
389  throw cms::Exception("ExternalLHEProducer") << "Failed to execute script (errno=" << rc << ", " << strerror(rc) << ")";
390  }
391  close(filedes[0]);
392 
393  int status = 0;
394  errno = 0;
395  do {
396  if (waitpid(pid, &status, 0) < 0) {
397  if (errno == EINTR) {
398  continue;
399  } else {
400  throw cms::Exception("ExternalLHEProducer") << "Failed to read child status (errno=" << errno << ", " << strerror(errno) << ")";
401  }
402  }
403  if (WIFSIGNALED(status)) {
404  throw cms::Exception("ExternalLHEProducer") << "Child exited due to signal " << WTERMSIG(status) << ".";
405  }
406  if (WIFEXITED(status)) {
407  rc = WEXITSTATUS(status);
408  break;
409  }
410  } while (true);
411  if (rc) {
412  throw cms::Exception("ExternalLHEProducer") << "Child failed with exit code " << rc << ".";
413  }
414 
415 }
int i
Definition: DBlmapReader.cc:9
def pipe
Definition: pipe.py:5
#define NULL
Definition: scimark2.h:8
std::vector< std::string > args_
int closeDescriptors(int preserve)
tuple argc
Definition: dir2webdir.py:41
tuple status
Definition: ntuplemaker.py:245
void ExternalLHEProducer::fillDescriptions ( edm::ConfigurationDescriptions descriptions)
static

Definition at line 459 of file ExternalLHEProducer.cc.

References edm::ParameterSetDescription::add(), edm::ConfigurationDescriptions::addDefault(), and edm::ParameterSetDescription::setComment().

459  {
460  //The following says we do not know what parameters are allowed so do no validation
461  // Please change this to state exactly what you do use, even if it is no parameters
463  desc.setComment("Executes an external script and places its output file into an EDM collection");
464 
465  edm::FileInPath thePath;
466  desc.add<edm::FileInPath>("scriptName", thePath);
467  desc.add<std::string>("outputFile", "myoutput");
468  desc.add<std::vector<std::string> >("args");
469  desc.add<uint32_t>("numberOfParameters");
470  desc.add<uint32_t>("nEvents");
471 
472  descriptions.addDefault(desc);
473 }
void setComment(std::string const &value)
void addDefault(ParameterSetDescription const &psetDescription)
ParameterDescriptionBase * add(U const &iLabel, T const &value)
void ExternalLHEProducer::nextEvent ( )
privatevirtual

Definition at line 475 of file ExternalLHEProducer.cc.

References partonLevel, reader_, runInfo, and runInfoLast.

Referenced by beginRun(), and produce().

476 {
477 
478  if (partonLevel)
479  return;
480 
481  partonLevel = reader_->next();
482  if (!partonLevel)
483  return;
484 
485  boost::shared_ptr<lhef::LHERunInfo> runInfoThis = partonLevel->getRunInfo();
486  if (runInfoThis != runInfoLast) {
487  runInfo = runInfoThis;
488  runInfoLast = runInfoThis;
489  }
490 }
boost::shared_ptr< lhef::LHEEvent > partonLevel
std::auto_ptr< lhef::LHEReader > reader_
boost::shared_ptr< lhef::LHERunInfo > runInfoLast
boost::shared_ptr< lhef::LHERunInfo > runInfo
void ExternalLHEProducer::produce ( edm::Event iEvent,
const edm::EventSetup iSetup 
)
privatevirtual

Implements edm::EDProducer.

Definition at line 155 of file ExternalLHEProducer.cc.

References LHEEventProduct::addComment(), LHERunInfoProduct::addComment(), LHERunInfoProduct::addHeader(), nextEvent(), partonLevel, edm::Event::put(), runInfo, runInfoProducts, and wasMerged.

156 {
157  nextEvent();
158  if (!partonLevel)
159  return;
160 
161  std::auto_ptr<LHEEventProduct> product(
162  new LHEEventProduct(*partonLevel->getHEPEUP(),
163  partonLevel->originalXWGTUP())
164  );
165  if (partonLevel->getPDF())
166  product->setPDF(*partonLevel->getPDF());
167  std::for_each(partonLevel->getComments().begin(),
168  partonLevel->getComments().end(),
169  boost::bind(&LHEEventProduct::addComment,
170  product.get(), _1));
171 
172  iEvent.put(product);
173 
174  if (runInfo) {
175  std::auto_ptr<LHERunInfoProduct> product(new LHERunInfoProduct(*runInfo->getHEPRUP()));
176  std::for_each(runInfo->getHeaders().begin(),
177  runInfo->getHeaders().end(),
178  boost::bind(&LHERunInfoProduct::addHeader,
179  product.get(), _1));
180  std::for_each(runInfo->getComments().begin(),
181  runInfo->getComments().end(),
182  boost::bind(&LHERunInfoProduct::addComment,
183  product.get(), _1));
184 
185  if (!runInfoProducts.empty()) {
186  runInfoProducts.front().mergeProduct(*product);
187  if (!wasMerged) {
188  runInfoProducts.pop_front();
189  runInfoProducts.push_front(product);
190  wasMerged = true;
191  }
192  }
193 
194  runInfo.reset();
195  }
196 
197  partonLevel.reset();
198  return;
199 }
boost::shared_ptr< lhef::LHEEvent > partonLevel
void addHeader(const Header &header)
void addComment(const std::string &line)
OrphanHandle< PROD > put(std::auto_ptr< PROD > product)
Put a new product.
Definition: Event.h:85
boost::shared_ptr< lhef::LHERunInfo > runInfo
void addComment(const std::string &line)
boost::ptr_deque< LHERunInfoProduct > runInfoProducts
std::auto_ptr< std::string > ExternalLHEProducer::readOutput ( )
private

Definition at line 419 of file ExternalLHEProducer.cc.

References BUFSIZE, edm::hlt::Exception, n, outputFile_, and SiPixelLorentzAngle_cfi::read.

Referenced by beginRun().

420 {
421  int fd;
422  ssize_t n;
423  char buf[BUFSIZE];
424 
425  if ((fd = open(outputFile_.c_str(), O_RDONLY)) == -1) {
426  throw cms::Exception("OutputOpenError") << "Unable to open script output file " << outputFile_ << " (errno=" << errno << ", " << strerror(errno) << ").";
427  }
428 
429  std::stringstream ss;
430  while ((n = read(fd, buf, BUFSIZE)) > 0 || (n == -1 && errno == EINTR)) {
431  if (n > 0)
432  ss.write(buf, n);
433  }
434  if (n == -1) {
435  throw cms::Exception("OutputOpenError") << "Unable to read from script output file " << outputFile_ << " (errno=" << errno << ", " << strerror(errno) << ").";
436  }
437 
438  if (unlink(outputFile_.c_str())) {
439  throw cms::Exception("OutputDeleteError") << "Unable to delete original script output file " << outputFile_ << " (errno=" << errno << ", " << strerror(errno) << ").";
440  }
441 
442  return std::auto_ptr<std::string>(new std::string(ss.str()));
443 }
#define BUFSIZE

Member Data Documentation

std::vector<std::string> ExternalLHEProducer::args_
private
uint32_t ExternalLHEProducer::nEvents_
private

Definition at line 93 of file ExternalLHEProducer.cc.

Referenced by beginRun().

uint32_t ExternalLHEProducer::npars_
private

Definition at line 92 of file ExternalLHEProducer.cc.

Referenced by ExternalLHEProducer().

std::string ExternalLHEProducer::outputContents_
private

Definition at line 94 of file ExternalLHEProducer.cc.

Referenced by beginRun().

std::string ExternalLHEProducer::outputFile_
private

Definition at line 90 of file ExternalLHEProducer.cc.

Referenced by readOutput().

boost::shared_ptr<lhef::LHEEvent> ExternalLHEProducer::partonLevel
private

Definition at line 99 of file ExternalLHEProducer.cc.

Referenced by nextEvent(), and produce().

std::auto_ptr<lhef::LHEReader> ExternalLHEProducer::reader_
private

Definition at line 96 of file ExternalLHEProducer.cc.

Referenced by beginRun(), endJob(), and nextEvent().

boost::shared_ptr<lhef::LHERunInfo> ExternalLHEProducer::runInfo
private

Definition at line 98 of file ExternalLHEProducer.cc.

Referenced by beginRun(), nextEvent(), and produce().

boost::shared_ptr<lhef::LHERunInfo> ExternalLHEProducer::runInfoLast
private

Definition at line 97 of file ExternalLHEProducer.cc.

Referenced by beginRun(), and nextEvent().

boost::ptr_deque<LHERunInfoProduct> ExternalLHEProducer::runInfoProducts
private

Definition at line 100 of file ExternalLHEProducer.cc.

Referenced by beginRun(), endRun(), and produce().

std::string ExternalLHEProducer::scriptName_
private

Definition at line 89 of file ExternalLHEProducer.cc.

Referenced by executeScript().

bool ExternalLHEProducer::wasMerged
private

Definition at line 101 of file ExternalLHEProducer.cc.

Referenced by beginRun(), and produce().