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.getParameter<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>();
170 std::for_each(
runInfo->getHeaders().begin(),
174 std::for_each(
runInfo->getComments().begin(),
209 std::ostringstream eventStream;
211 args_.push_back(eventStream.str());
219 <<
"The ExternalLHEProducer module requires the RandomNumberGeneratorService\n"
220 "which is not present in the configuration file. You must add the service\n"
221 "in the configuration file if you want to run ExternalLHEProducer";
223 std::ostringstream randomStream;
224 randomStream << rng->
mySeed();
225 args_.push_back(randomStream.str());
227 for (
unsigned int iArg = 0; iArg <
args_.size() ; iArg++ ) {
228 LogDebug(
"LHEInputArgs") <<
"arg [" << iArg <<
"] = " <<
args_[iArg];
232 std::auto_ptr<std::string> localContents =
readOutput();
235 run.
put(p,
"LHEScriptOutput");
239 unsigned int skip = 0;
248 std::for_each(
runInfo->getHeaders().begin(),
252 std::for_each(
runInfo->getComments().begin(),
274 std::auto_ptr<LHERunInfoProduct> product(
runInfoProducts.pop_front().release());
290 if ((dir = opendir(
"/proc/self/fd"))) {
292 while ((dp = readdir (dir)) !=
NULL) {
293 if ((strcmp(dp->d_name,
".") == 0) || (strcmp(dp->d_name,
"..") == 0)) {
296 if (sscanf(dp->d_name,
"%d", &fd) != 1) {
312 for (fd=3; fd<maxfd+1; fd++) {
327 int filedes[2], fd_flags;
335 if ((fd_flags = fcntl(filedes[1], F_GETFD,
NULL)) == -1) {
336 throw cms::Exception(
"ExternalLHEProducer") <<
"Failed to get pipe file descriptor flags (errno=" << rc <<
", " << strerror(rc) <<
")";
338 if (fcntl(filedes[1], F_SETFD, fd_flags | FD_CLOEXEC) == -1) {
339 throw cms::Exception(
"ExternalLHEProducer") <<
"Failed to set pipe file descriptor flags (errno=" << rc <<
", " << strerror(rc) <<
")";
342 argc = 1 +
args_.size();
344 char **
argv =
new char *[argc+1];
346 for (
unsigned int i=1;
i<
argc;
i++) {
347 argv[
i] = strdup(
args_[
i-1].c_str());
355 execvp(argv[0], argv);
358 while ((
write(filedes[1], &rc,
sizeof(
int)) == -1) && (errno == EINTR)) {}
363 for (
unsigned int i=0;
i<
args_.size()+1;
i++) {
369 throw cms::Exception(
"ForkException") <<
"Unable to fork a child (errno=" << errno <<
", " << strerror(errno) <<
")";
374 while (((rc2 =
read(filedes[0], &rc,
sizeof(
int))) == -1) && (errno == EINTR)) { rc2 = 0; }
375 if ((rc2 ==
sizeof(
int)) && rc) {
376 throw cms::Exception(
"ExternalLHEProducer") <<
"Failed to execute script (errno=" << rc <<
", " << strerror(rc) <<
")";
383 if (waitpid(pid, &status, 0) < 0) {
384 if (errno == EINTR) {
387 throw cms::Exception(
"ExternalLHEProducer") <<
"Failed to read child status (errno=" << errno <<
", " << strerror(errno) <<
")";
390 if (WIFSIGNALED(status)) {
391 throw cms::Exception(
"ExternalLHEProducer") <<
"Child exited due to signal " << WTERMSIG(status) <<
".";
393 if (WIFEXITED(status)) {
394 rc = WEXITSTATUS(status);
399 throw cms::Exception(
"ExternalLHEProducer") <<
"Child failed with exit code " << rc <<
".";
412 if ((fd = open(
outputFile_.c_str(), O_RDONLY)) == -1) {
413 throw cms::Exception(
"OutputOpenError") <<
"Unable to open script output file " <<
outputFile_ <<
" (errno=" << errno <<
", " << strerror(errno) <<
").";
416 std::stringstream ss;
417 while ((n =
read(fd, buf,
BUFSIZE)) > 0 || (n == -1 && errno == EINTR)) {
422 throw cms::Exception(
"OutputOpenError") <<
"Unable to read from script output file " <<
outputFile_ <<
" (errno=" << errno <<
", " << strerror(errno) <<
").";
426 throw cms::Exception(
"OutputDeleteError") <<
"Unable to delete original script output file " <<
outputFile_ <<
" (errno=" << errno <<
", " << strerror(errno) <<
").";
429 return std::auto_ptr<std::string>(
new std::string(ss.str()));
438 desc.
setComment(
"Executes an external script and places its output file into an EDM collection");
443 desc.
add<std::vector<std::string> >(
"args");
444 desc.
add<uint32_t>(
"numberOfParameters");
445 desc.
add<uint32_t>(
"nEvents");
460 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)