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(
172 std::for_each(
runInfo->getHeaders().begin(),
176 std::for_each(
runInfo->getComments().begin(),
211 std::ostringstream eventStream;
213 args_.push_back(eventStream.str());
221 <<
"The ExternalLHEProducer module requires the RandomNumberGeneratorService\n"
222 "which is not present in the configuration file. You must add the service\n"
223 "in the configuration file if you want to run ExternalLHEProducer";
225 std::ostringstream randomStream;
226 randomStream << rng->
mySeed();
227 args_.push_back(randomStream.str());
229 for (
unsigned int iArg = 0; iArg <
args_.size() ; iArg++ ) {
230 LogDebug(
"LHEInputArgs") <<
"arg [" << iArg <<
"] = " <<
args_[iArg];
234 std::auto_ptr<std::string> localContents =
readOutput();
237 run.
put(p,
"LHEScriptOutput");
241 unsigned int skip = 0;
250 std::for_each(
runInfo->getHeaders().begin(),
254 std::for_each(
runInfo->getComments().begin(),
276 std::auto_ptr<LHERunInfoProduct> product(
runInfoProducts.pop_front().release());
292 if ((dir = opendir(
"/proc/self/fd"))) {
294 while ((dp = readdir (dir)) !=
NULL) {
295 if ((strcmp(dp->d_name,
".") == 0) || (strcmp(dp->d_name,
"..") == 0)) {
298 if (sscanf(dp->d_name,
"%d", &fd) != 1) {
314 for (fd=3; fd<maxfd+1; fd++) {
329 int filedes[2], fd_flags;
337 if ((fd_flags = fcntl(filedes[1], F_GETFD,
NULL)) == -1) {
338 throw cms::Exception(
"ExternalLHEProducer") <<
"Failed to get pipe file descriptor flags (errno=" << rc <<
", " << strerror(rc) <<
")";
340 if (fcntl(filedes[1], F_SETFD, fd_flags | FD_CLOEXEC) == -1) {
341 throw cms::Exception(
"ExternalLHEProducer") <<
"Failed to set pipe file descriptor flags (errno=" << rc <<
", " << strerror(rc) <<
")";
344 argc = 1 +
args_.size();
346 char **
argv =
new char *[argc+1];
348 for (
unsigned int i=1;
i<
argc;
i++) {
349 argv[
i] = strdup(
args_[
i-1].c_str());
357 execvp(argv[0], argv);
360 while ((
write(filedes[1], &rc,
sizeof(
int)) == -1) && (errno == EINTR)) {}
365 for (
unsigned int i=0;
i<
args_.size()+1;
i++) {
371 throw cms::Exception(
"ForkException") <<
"Unable to fork a child (errno=" << errno <<
", " << strerror(errno) <<
")";
376 while (((rc2 =
read(filedes[0], &rc,
sizeof(
int))) == -1) && (errno == EINTR)) { rc2 = 0; }
377 if ((rc2 ==
sizeof(
int)) && rc) {
378 throw cms::Exception(
"ExternalLHEProducer") <<
"Failed to execute script (errno=" << rc <<
", " << strerror(rc) <<
")";
385 if (waitpid(pid, &status, 0) < 0) {
386 if (errno == EINTR) {
389 throw cms::Exception(
"ExternalLHEProducer") <<
"Failed to read child status (errno=" << errno <<
", " << strerror(errno) <<
")";
392 if (WIFSIGNALED(status)) {
393 throw cms::Exception(
"ExternalLHEProducer") <<
"Child exited due to signal " << WTERMSIG(status) <<
".";
395 if (WIFEXITED(status)) {
396 rc = WEXITSTATUS(status);
401 throw cms::Exception(
"ExternalLHEProducer") <<
"Child failed with exit code " << rc <<
".";
414 if ((fd = open(
outputFile_.c_str(), O_RDONLY)) == -1) {
415 throw cms::Exception(
"OutputOpenError") <<
"Unable to open script output file " <<
outputFile_ <<
" (errno=" << errno <<
", " << strerror(errno) <<
").";
418 std::stringstream ss;
419 while ((n =
read(fd, buf,
BUFSIZE)) > 0 || (n == -1 && errno == EINTR)) {
424 throw cms::Exception(
"OutputOpenError") <<
"Unable to read from script output file " <<
outputFile_ <<
" (errno=" << errno <<
", " << strerror(errno) <<
").";
428 throw cms::Exception(
"OutputDeleteError") <<
"Unable to delete original script output file " <<
outputFile_ <<
" (errno=" << errno <<
", " << strerror(errno) <<
").";
431 return std::auto_ptr<std::string>(
new std::string(ss.str()));
440 desc.
setComment(
"Executes an external script and places its output file into an EDM collection");
445 desc.
add<std::vector<std::string> >(
"args");
446 desc.
add<uint32_t>(
"numberOfParameters");
447 desc.
add<uint32_t>(
"nEvents");
462 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
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)
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
virtual uint32_t mySeed() const =0
Exists for backward compatibility.
ExternalLHEProducer(const edm::ParameterSet &iConfig)