30 #include <boost/shared_ptr.hpp>
31 #include <boost/ptr_container/ptr_deque.hpp>
64 edm::EndRunProducer> {
74 virtual void endJob()
override;
94 boost::shared_ptr<lhef::LHERunInfo>
runInfo;
125 scriptName_((iConfig.getParameter<edm::
FileInPath>(
"scriptName")).
fullPath().c_str()),
126 outputFile_(iConfig.getParameter<std::
string>(
"outputFile")),
127 args_(iConfig.getParameter<std::vector<std::
string> >(
"args")),
128 npars_(iConfig.getParameter<uint32_t>(
"numberOfParameters")),
129 nEvents_(iConfig.getParameter<uint32_t>(
"nEvents"))
132 throw cms::Exception(
"ExternalLHEProducer") <<
"Problem with configuration: " <<
args_.size() <<
" script arguments given, expected " <<
npars_;
133 produces<LHEXMLStringProduct, edm::InRun>(
"LHEScriptOutput");
135 produces<LHEEventProduct>();
136 produces<LHERunInfoProduct, edm::InRun>();
157 std::auto_ptr<LHEEventProduct> product(
180 std::for_each(
runInfo->getHeaders().begin(),
184 std::for_each(
runInfo->getComments().begin(),
219 std::ostringstream eventStream;
221 args_.push_back(eventStream.str());
229 <<
"The ExternalLHEProducer module requires the RandomNumberGeneratorService\n"
230 "which is not present in the configuration file. You must add the service\n"
231 "in the configuration file if you want to run ExternalLHEProducer";
233 std::ostringstream randomStream;
234 randomStream << rng->
mySeed();
235 args_.push_back(randomStream.str());
237 for (
unsigned int iArg = 0; iArg <
args_.size() ; iArg++ ) {
238 LogDebug(
"LHEInputArgs") <<
"arg [" << iArg <<
"] = " <<
args_[iArg];
242 std::auto_ptr<std::string> localContents =
readOutput();
245 run.
put(p,
"LHEScriptOutput");
249 unsigned int skip = 0;
258 std::for_each(
runInfo->getHeaders().begin(),
262 std::for_each(
runInfo->getComments().begin(),
284 std::auto_ptr<LHERunInfoProduct> product(
runInfoProducts.pop_front().release());
300 if ((dir = opendir(
"/proc/self/fd"))) {
302 while ((dp = readdir (dir)) !=
NULL) {
303 if ((strcmp(dp->d_name,
".") == 0) || (strcmp(dp->d_name,
"..") == 0)) {
306 if (sscanf(dp->d_name,
"%d", &fd) != 1) {
322 for (fd=3; fd<maxfd+1; fd++) {
337 int filedes[2], fd_flags;
345 if ((fd_flags = fcntl(filedes[1], F_GETFD,
NULL)) == -1) {
346 throw cms::Exception(
"ExternalLHEProducer") <<
"Failed to get pipe file descriptor flags (errno=" << rc <<
", " << strerror(rc) <<
")";
348 if (fcntl(filedes[1], F_SETFD, fd_flags | FD_CLOEXEC) == -1) {
349 throw cms::Exception(
"ExternalLHEProducer") <<
"Failed to set pipe file descriptor flags (errno=" << rc <<
", " << strerror(rc) <<
")";
352 argc = 1 +
args_.size();
354 char **
argv =
new char *[argc+1];
356 for (
unsigned int i=1;
i<
argc;
i++) {
357 argv[
i] = strdup(
args_[
i-1].c_str());
365 execvp(argv[0], argv);
368 while ((
write(filedes[1], &rc,
sizeof(
int)) == -1) && (errno == EINTR)) {}
373 for (
unsigned int i=0;
i<
args_.size()+1;
i++) {
379 throw cms::Exception(
"ForkException") <<
"Unable to fork a child (errno=" << errno <<
", " << strerror(errno) <<
")";
384 while (((rc2 =
read(filedes[0], &rc,
sizeof(
int))) == -1) && (errno == EINTR)) { rc2 = 0; }
385 if ((rc2 ==
sizeof(
int)) && rc) {
386 throw cms::Exception(
"ExternalLHEProducer") <<
"Failed to execute script (errno=" << rc <<
", " << strerror(rc) <<
")";
393 if (waitpid(pid, &status, 0) < 0) {
394 if (errno == EINTR) {
397 throw cms::Exception(
"ExternalLHEProducer") <<
"Failed to read child status (errno=" << errno <<
", " << strerror(errno) <<
")";
400 if (WIFSIGNALED(status)) {
401 throw cms::Exception(
"ExternalLHEProducer") <<
"Child exited due to signal " << WTERMSIG(status) <<
".";
403 if (WIFEXITED(status)) {
404 rc = WEXITSTATUS(status);
409 throw cms::Exception(
"ExternalLHEProducer") <<
"Child failed with exit code " << rc <<
".";
422 if ((fd = open(
outputFile_.c_str(), O_RDONLY)) == -1) {
423 throw cms::Exception(
"OutputOpenError") <<
"Unable to open script output file " <<
outputFile_ <<
" (errno=" << errno <<
", " << strerror(errno) <<
").";
426 std::stringstream
ss;
427 while ((n =
read(fd, buf,
BUFSIZE)) > 0 || (n == -1 && errno == EINTR)) {
432 throw cms::Exception(
"OutputOpenError") <<
"Unable to read from script output file " <<
outputFile_ <<
" (errno=" << errno <<
", " << strerror(errno) <<
").";
436 throw cms::Exception(
"OutputDeleteError") <<
"Unable to delete original script output file " <<
outputFile_ <<
" (errno=" << errno <<
", " << strerror(errno) <<
").";
439 return std::auto_ptr<std::string>(
new std::string(ss.str()));
448 desc.
setComment(
"Executes an external script and places its output file into an EDM collection");
453 desc.
add<std::vector<std::string> >(
"args");
454 desc.
add<uint32_t>(
"numberOfParameters");
455 desc.
add<uint32_t>(
"nEvents");
470 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
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)