30 #include "boost/bind.hpp"
31 #include "boost/shared_ptr.hpp"
32 #include "boost/ptr_container/ptr_deque.hpp"
65 edm::EndRunProducer> {
75 virtual void endJob()
override;
95 boost::shared_ptr<lhef::LHERunInfo>
runInfo;
126 scriptName_((iConfig.getParameter<edm::
FileInPath>(
"scriptName")).
fullPath().c_str()),
127 outputFile_(iConfig.getParameter<std::
string>(
"outputFile")),
128 args_(iConfig.getParameter<std::vector<std::
string> >(
"args")),
129 npars_(iConfig.getParameter<uint32_t>(
"numberOfParameters")),
130 nEvents_(iConfig.getUntrackedParameter<uint32_t>(
"nEvents"))
133 throw cms::Exception(
"ExternalLHEProducer") <<
"Problem with configuration: " <<
args_.size() <<
" script arguments given, expected " <<
npars_;
134 produces<LHEXMLStringProduct, edm::InRun>(
"LHEScriptOutput");
136 produces<LHEEventProduct>();
137 produces<LHERunInfoProduct, edm::InRun>();
158 std::auto_ptr<LHEEventProduct> product(
181 std::for_each(
runInfo->getHeaders().begin(),
185 std::for_each(
runInfo->getComments().begin(),
220 std::ostringstream eventStream;
222 args_.push_back(eventStream.str());
230 <<
"The ExternalLHEProducer module requires the RandomNumberGeneratorService\n"
231 "which is not present in the configuration file. You must add the service\n"
232 "in the configuration file if you want to run ExternalLHEProducer";
234 std::ostringstream randomStream;
235 randomStream << rng->
mySeed();
236 args_.push_back(randomStream.str());
238 for (
unsigned int iArg = 0; iArg <
args_.size() ; iArg++ ) {
239 LogDebug(
"LHEInputArgs") <<
"arg [" << iArg <<
"] = " <<
args_[iArg];
243 std::auto_ptr<std::string> localContents =
readOutput();
246 run.
put(p,
"LHEScriptOutput");
250 unsigned int skip = 0;
259 std::for_each(
runInfo->getHeaders().begin(),
263 std::for_each(
runInfo->getComments().begin(),
285 std::auto_ptr<LHERunInfoProduct> product(
runInfoProducts.pop_front().release());
301 if ((dir = opendir(
"/proc/self/fd"))) {
303 while ((dp = readdir (dir)) !=
NULL) {
304 if ((strcmp(dp->d_name,
".") == 0) || (strcmp(dp->d_name,
"..") == 0)) {
307 if (sscanf(dp->d_name,
"%d", &fd) != 1) {
323 for (fd=3; fd<maxfd+1; fd++) {
338 int filedes[2], fd_flags;
346 if ((fd_flags = fcntl(filedes[1], F_GETFD,
NULL)) == -1) {
347 throw cms::Exception(
"ExternalLHEProducer") <<
"Failed to get pipe file descriptor flags (errno=" << rc <<
", " << strerror(rc) <<
")";
349 if (fcntl(filedes[1], F_SETFD, fd_flags | FD_CLOEXEC) == -1) {
350 throw cms::Exception(
"ExternalLHEProducer") <<
"Failed to set pipe file descriptor flags (errno=" << rc <<
", " << strerror(rc) <<
")";
353 argc = 1 +
args_.size();
355 char **
argv =
new char *[argc+1];
357 for (
unsigned int i=1;
i<
argc;
i++) {
358 argv[
i] = strdup(
args_[
i-1].c_str());
366 execvp(argv[0], argv);
369 while ((
write(filedes[1], &rc,
sizeof(
int)) == -1) && (errno == EINTR)) {}
374 for (
unsigned int i=0;
i<
args_.size()+1;
i++) {
380 throw cms::Exception(
"ForkException") <<
"Unable to fork a child (errno=" << errno <<
", " << strerror(errno) <<
")";
385 while (((rc2 =
read(filedes[0], &rc,
sizeof(
int))) == -1) && (errno == EINTR)) { rc2 = 0; }
386 if ((rc2 ==
sizeof(
int)) && rc) {
387 throw cms::Exception(
"ExternalLHEProducer") <<
"Failed to execute script (errno=" << rc <<
", " << strerror(rc) <<
")";
394 if (waitpid(pid, &status, 0) < 0) {
395 if (errno == EINTR) {
398 throw cms::Exception(
"ExternalLHEProducer") <<
"Failed to read child status (errno=" << errno <<
", " << strerror(errno) <<
")";
401 if (WIFSIGNALED(status)) {
402 throw cms::Exception(
"ExternalLHEProducer") <<
"Child exited due to signal " << WTERMSIG(status) <<
".";
404 if (WIFEXITED(status)) {
405 rc = WEXITSTATUS(status);
410 throw cms::Exception(
"ExternalLHEProducer") <<
"Child failed with exit code " << rc <<
".";
423 if ((fd = open(
outputFile_.c_str(), O_RDONLY)) == -1) {
424 throw cms::Exception(
"OutputOpenError") <<
"Unable to open script output file " <<
outputFile_ <<
" (errno=" << errno <<
", " << strerror(errno) <<
").";
427 std::stringstream
ss;
428 while ((n =
read(fd, buf,
BUFSIZE)) > 0 || (n == -1 && errno == EINTR)) {
433 throw cms::Exception(
"OutputOpenError") <<
"Unable to read from script output file " <<
outputFile_ <<
" (errno=" << errno <<
", " << strerror(errno) <<
").";
437 throw cms::Exception(
"OutputDeleteError") <<
"Unable to delete original script output file " <<
outputFile_ <<
" (errno=" << errno <<
", " << strerror(errno) <<
").";
440 return std::auto_ptr<std::string>(
new std::string(ss.str()));
449 desc.
setComment(
"Executes an external script and places its output file into an EDM collection");
454 desc.
add<std::vector<std::string> >(
"args");
455 desc.
add<uint32_t>(
"numberOfParameters");
471 boost::shared_ptr<lhef::LHERunInfo> runInfoThis =
partonLevel->getRunInfo();
boost::shared_ptr< lhef::LHEEvent > partonLevel
std::auto_ptr< std::string > readOutput()
virtual void beginRunProduce(edm::Run &run, edm::EventSetup const &es) override
virtual void endRunProduce(edm::Run &, edm::EventSetup const &) override
ParameterDescriptionBase * addUntracked(U const &iLabel, T const &value)
void addHeader(const Header &header)
void addComment(const std::string &line)
#define DEFINE_FWK_MODULE(type)
virtual void produce(edm::Event &, const edm::EventSetup &) override
void addWeight(const WGT &wgt)
std::vector< std::string > args_
static void fillDescriptions(edm::ConfigurationDescriptions &descriptions)
std::auto_ptr< lhef::LHEReader > reader_
boost::shared_ptr< lhef::LHERunInfo > runInfoLast
void setComment(std::string const &value)
int closeDescriptors(int preserve)
void addDefault(ParameterSetDescription const &psetDescription)
virtual std::uint32_t mySeed() const =0
OrphanHandle< PROD > put(std::auto_ptr< PROD > product)
Put a new product.
ParameterDescriptionBase * add(U const &iLabel, T const &value)
std::string outputContents_
virtual void endJob() override
boost::shared_ptr< lhef::LHERunInfo > runInfo
void addComment(const std::string &line)
virtual ~ExternalLHEProducer()
void put(std::auto_ptr< PROD > product)
Put a new product.
boost::ptr_deque< LHERunInfoProduct > runInfoProducts
ExternalLHEProducer(const edm::ParameterSet &iConfig)