#include <Example/ExternalLHEProducer/src/ExternalLHEProducer.cc>
Classes | |
class | FileCloseSentry |
Public Member Functions | |
ExternalLHEProducer (const edm::ParameterSet &iConfig) | |
~ExternalLHEProducer () | |
Static Public Member Functions | |
static void | fillDescriptions (edm::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_ |
std::string | outputContents_ |
std::string | outputFile_ |
boost::shared_ptr< lhef::LHEEvent > | partonLevel |
std::auto_ptr< lhef::LHEReader > | reader_ |
boost::shared_ptr < lhef::LHERunInfo > | runInfo |
boost::shared_ptr < lhef::LHERunInfo > | runInfoLast |
boost::ptr_deque < LHERunInfoProduct > | runInfoProducts |
std::string | scriptName_ |
bool | wasMerged |
Description: [one line class summary]
Implementation: [Notes on implementation]
Definition at line 63 of file ExternalLHEProducer.cc.
ExternalLHEProducer::ExternalLHEProducer | ( | const edm::ParameterSet & | iConfig | ) | [explicit] |
Definition at line 126 of file ExternalLHEProducer.cc.
: scriptName_((iConfig.getParameter<edm::FileInPath>("scriptName")).fullPath().c_str()), outputFile_(iConfig.getParameter<std::string>("outputFile")), args_(iConfig.getParameter<std::vector<std::string> >("args")), nEvents_(iConfig.getParameter<uint32_t>("nEvents")) { produces<std::string, edm::InRun>("LHEScriptOutput"); produces<LHEEventProduct>(); produces<LHERunInfoProduct, edm::InRun>(); }
ExternalLHEProducer::~ExternalLHEProducer | ( | ) |
Definition at line 139 of file ExternalLHEProducer.cc.
{ }
void ExternalLHEProducer::beginJob | ( | void | ) | [private, virtual] |
void ExternalLHEProducer::beginLuminosityBlock | ( | edm::LuminosityBlock & | lumi, |
edm::EventSetup const & | |||
) | [private, virtual] |
void ExternalLHEProducer::beginRun | ( | edm::Run & | run, |
edm::EventSetup const & | es | ||
) | [private, virtual] |
Reimplemented from edm::EDProducer.
Definition at line 209 of file ExternalLHEProducer.cc.
References LHERunInfoProduct::addComment(), LHERunInfoProduct::addHeader(), args_, Exception, executeScript(), edm::Service< T >::isAvailable(), LogDebug, nEvents_, nextEvent(), outputContents_, edm::Run::put(), reader_, readOutput(), runInfo, runInfoLast, runInfoProducts, createPayload::skip, and wasMerged.
{ // pass the number of events as previous to last argument std::ostringstream eventStream; eventStream << nEvents_; args_.push_back(eventStream.str()); // pass the random number generator seed as last argument edm::Service<edm::RandomNumberGenerator> rng; if ( ! rng.isAvailable()) { throw cms::Exception("Configuration") << "The ExternalLHEProducer module requires the RandomNumberGeneratorService\n" "which is not present in the configuration file. You must add the service\n" "in the configuration file if you want to run ExternalLHEProducer"; } std::ostringstream randomStream; randomStream << rng->mySeed(); args_.push_back(randomStream.str()); for ( unsigned int iArg = 0; iArg < args_.size() ; iArg++ ) { LogDebug("LHEInputArgs") << "arg [" << iArg << "] = " << args_[iArg]; } executeScript(); std::auto_ptr<std::string> localContents = readOutput(); outputContents_ = *localContents; run.put(localContents, "LHEScriptOutput"); // LHE C++ classes translation unsigned int skip = 0; std::auto_ptr<lhef::LHEReader> thisRead( new lhef::LHEReader(outputContents_, skip ) ); reader_ = thisRead; nextEvent(); if (runInfoLast) { runInfo = runInfoLast; std::auto_ptr<LHERunInfoProduct> product(new LHERunInfoProduct(*runInfo->getHEPRUP())); std::for_each(runInfo->getHeaders().begin(), runInfo->getHeaders().end(), boost::bind(&LHERunInfoProduct::addHeader, product.get(), _1)); std::for_each(runInfo->getComments().begin(), runInfo->getComments().end(), boost::bind(&LHERunInfoProduct::addComment, product.get(), _1)); // keep a copy around in case of merging runInfoProducts.push_back(new LHERunInfoProduct(*product)); wasMerged = false; run.put(product); runInfo.reset(); } }
int ExternalLHEProducer::closeDescriptors | ( | int | preserve | ) | [private] |
Definition at line 287 of file ExternalLHEProducer.cc.
References linker::DIR, dir, and NULL.
Referenced by executeScript().
{ int maxfd = 1024; int fd; #ifdef __linux__ DIR * dir; struct dirent *dp; maxfd = preserve; if ((dir = opendir("/proc/self/fd"))) { errno = 0; while ((dp = readdir (dir)) != NULL) { if ((strcmp(dp->d_name, ".") == 0) || (strcmp(dp->d_name, "..") == 0)) { continue; } if (sscanf(dp->d_name, "%d", &fd) != 1) { //throw cms::Exception("closeDescriptors") << "Found unexpected filename in /proc/self/fd: " << dp->d_name; return -1; } if (fd > maxfd) { maxfd = fd; } } if (errno) { //throw cms::Exception("closeDescriptors") << "Unable to determine the number of fd (errno=" << errno << ", " << strerror(errno) << ")."; return errno; } closedir(dir); } #endif // TODO: assert for an unreasonable number of fds? for (fd=3; fd<maxfd+1; fd++) { if (fd != preserve) close(fd); } return 0; }
void ExternalLHEProducer::endJob | ( | void | ) | [private, virtual] |
Reimplemented from edm::EDProducer.
Definition at line 201 of file ExternalLHEProducer.cc.
References reader_.
{ reader_.reset(); }
void ExternalLHEProducer::endLuminosityBlock | ( | edm::LuminosityBlock & | , |
edm::EventSetup const & | |||
) | [private, virtual] |
void ExternalLHEProducer::endRun | ( | edm::Run & | run, |
edm::EventSetup const & | es | ||
) | [private, virtual] |
Reimplemented from edm::EDProducer.
Definition at line 275 of file ExternalLHEProducer.cc.
References edm::Run::put(), and runInfoProducts.
{ if (!runInfoProducts.empty()) { std::auto_ptr<LHERunInfoProduct> product(runInfoProducts.pop_front().release()); run.put(product); } }
void ExternalLHEProducer::executeScript | ( | ) | [private] |
Definition at line 326 of file ExternalLHEProducer.cc.
References args_, closeDescriptors(), Exception, i, NULL, evf::utils::pid, testRegParams::pipe, SiPixelLorentzAngle_cfi::read, scriptName_, ntuplemaker::status, and TablePrint::write.
Referenced by beginRun().
{ // Fork a script, wait until it finishes. int rc = 0, rc2 = 0; int filedes[2], fd_flags; unsigned int argc; if (pipe(filedes)) { throw cms::Exception("Unable to create a new pipe"); } FileCloseSentry sentry1(filedes[0]), sentry2(filedes[1]); if ((fd_flags = fcntl(filedes[1], F_GETFD, NULL)) == -1) { throw cms::Exception("ExternalLHEProducer") << "Failed to get pipe file descriptor flags (errno=" << rc << ", " << strerror(rc) << ")"; } if (fcntl(filedes[1], F_SETFD, fd_flags | FD_CLOEXEC) == -1) { throw cms::Exception("ExternalLHEProducer") << "Failed to set pipe file descriptor flags (errno=" << rc << ", " << strerror(rc) << ")"; } argc = 1 + args_.size(); // TODO: assert that we have a reasonable number of arguments char **argv = new char *[argc+1]; argv[0] = strdup(scriptName_.c_str()); for (unsigned int i=1; i<argc; i++) { argv[i] = strdup(args_[i-1].c_str()); } argv[argc] = NULL; pid_t pid = fork(); if (pid == 0) { // The child process if (!(rc = closeDescriptors(filedes[1]))) { execvp(argv[0], argv); // If execv returns, we have an error. rc = errno; } while ((write(filedes[1], &rc, sizeof(int)) == -1) && (errno == EINTR)) {} _exit(1); } // Free the arg vector ASAP for (unsigned int i=0; i<args_.size()+1; i++) { free(argv[i]); } delete [] argv; if (pid == -1) { throw cms::Exception("ForkException") << "Unable to fork a child (errno=" << errno << ", " << strerror(errno) << ")"; } close(filedes[1]); // If the exec succeeds, the read will fail. while (((rc2 = read(filedes[0], &rc, sizeof(int))) == -1) && (errno == EINTR)) { rc2 = 0; } if ((rc2 == sizeof(int)) && rc) { throw cms::Exception("ExternalLHEProducer") << "Failed to execute script (errno=" << rc << ", " << strerror(rc) << ")"; } close(filedes[0]); int status = 0; errno = 0; do { if (waitpid(pid, &status, 0) < 0) { if (errno == EINTR) { continue; } else { throw cms::Exception("ExternalLHEProducer") << "Failed to read child status (errno=" << errno << ", " << strerror(errno) << ")"; } } if (WIFSIGNALED(status)) { throw cms::Exception("ExternalLHEProducer") << "Child exited due to signal " << WTERMSIG(status) << "."; } if (WIFEXITED(status)) { rc = WEXITSTATUS(status); break; } } while (true); if (rc) { throw cms::Exception("ExternalLHEProducer") << "Child failed with exit code " << rc << "."; } }
void ExternalLHEProducer::fillDescriptions | ( | edm::ConfigurationDescriptions & | descriptions | ) | [static] |
Reimplemented from edm::EDProducer.
Definition at line 451 of file ExternalLHEProducer.cc.
References edm::ParameterSetDescription::add(), edm::ConfigurationDescriptions::addDefault(), and edm::ParameterSetDescription::setComment().
{ //The following says we do not know what parameters are allowed so do no validation // Please change this to state exactly what you do use, even if it is no parameters edm::ParameterSetDescription desc; desc.setComment("Executes an external script and places its output file into an EDM collection"); edm::FileInPath thePath; desc.add<edm::FileInPath>("scriptName", thePath); desc.add<std::string>("outputFile", "myoutput"); desc.add<std::vector<std::string> >("args"); desc.add<uint32_t>("nEvents"); descriptions.addDefault(desc); }
void ExternalLHEProducer::nextEvent | ( | ) | [private, virtual] |
Definition at line 466 of file ExternalLHEProducer.cc.
References partonLevel, reader_, runInfo, and runInfoLast.
Referenced by beginRun(), and produce().
{ if (partonLevel) return; partonLevel = reader_->next(); if (!partonLevel) return; boost::shared_ptr<lhef::LHERunInfo> runInfoThis = partonLevel->getRunInfo(); if (runInfoThis != runInfoLast) { runInfo = runInfoThis; runInfoLast = runInfoThis; } }
void ExternalLHEProducer::produce | ( | edm::Event & | iEvent, |
const edm::EventSetup & | iSetup | ||
) | [private, virtual] |
Implements edm::EDProducer.
Definition at line 150 of file ExternalLHEProducer.cc.
References LHERunInfoProduct::addComment(), LHEEventProduct::addComment(), LHERunInfoProduct::addHeader(), nextEvent(), partonLevel, edm::Event::put(), runInfo, runInfoProducts, and wasMerged.
{ nextEvent(); if (!partonLevel) return; std::auto_ptr<LHEEventProduct> product(new LHEEventProduct(*partonLevel->getHEPEUP())); if (partonLevel->getPDF()) product->setPDF(*partonLevel->getPDF()); std::for_each(partonLevel->getComments().begin(), partonLevel->getComments().end(), boost::bind(&LHEEventProduct::addComment, product.get(), _1)); iEvent.put(product); if (runInfo) { std::auto_ptr<LHERunInfoProduct> product(new LHERunInfoProduct(*runInfo->getHEPRUP())); std::for_each(runInfo->getHeaders().begin(), runInfo->getHeaders().end(), boost::bind(&LHERunInfoProduct::addHeader, product.get(), _1)); std::for_each(runInfo->getComments().begin(), runInfo->getComments().end(), boost::bind(&LHERunInfoProduct::addComment, product.get(), _1)); if (!runInfoProducts.empty()) { runInfoProducts.front().mergeProduct(*product); if (!wasMerged) { runInfoProducts.pop_front(); runInfoProducts.push_front(product); wasMerged = true; } } runInfo.reset(); } partonLevel.reset(); return; }
std::auto_ptr< std::string > ExternalLHEProducer::readOutput | ( | ) | [private] |
Definition at line 411 of file ExternalLHEProducer.cc.
References BUFSIZE, Exception, n, outputFile_, and SiPixelLorentzAngle_cfi::read.
Referenced by beginRun().
{ int fd; ssize_t n; char buf[BUFSIZE]; if ((fd = open(outputFile_.c_str(), O_RDONLY)) == -1) { throw cms::Exception("OutputOpenError") << "Unable to open script output file " << outputFile_ << " (errno=" << errno << ", " << strerror(errno) << ")."; } std::stringstream ss; while ((n = read(fd, buf, BUFSIZE)) > 0 || (n == -1 && errno == EINTR)) { if (n > 0) ss.write(buf, n); } if (n == -1) { throw cms::Exception("OutputOpenError") << "Unable to read from script output file " << outputFile_ << " (errno=" << errno << ", " << strerror(errno) << ")."; } if (unlink(outputFile_.c_str())) { throw cms::Exception("OutputDeleteError") << "Unable to delete original script output file " << outputFile_ << " (errno=" << errno << ", " << strerror(errno) << ")."; } return std::auto_ptr<std::string>(new std::string(ss.str())); }
std::vector<std::string> ExternalLHEProducer::args_ [private] |
Definition at line 90 of file ExternalLHEProducer.cc.
Referenced by beginRun(), and executeScript().
uint32_t ExternalLHEProducer::nEvents_ [private] |
Definition at line 91 of file ExternalLHEProducer.cc.
Referenced by beginRun().
std::string ExternalLHEProducer::outputContents_ [private] |
Definition at line 92 of file ExternalLHEProducer.cc.
Referenced by beginRun().
std::string ExternalLHEProducer::outputFile_ [private] |
Definition at line 89 of file ExternalLHEProducer.cc.
Referenced by readOutput().
boost::shared_ptr<lhef::LHEEvent> ExternalLHEProducer::partonLevel [private] |
Definition at line 97 of file ExternalLHEProducer.cc.
Referenced by nextEvent(), and produce().
std::auto_ptr<lhef::LHEReader> ExternalLHEProducer::reader_ [private] |
Definition at line 94 of file ExternalLHEProducer.cc.
Referenced by beginRun(), endJob(), and nextEvent().
boost::shared_ptr<lhef::LHERunInfo> ExternalLHEProducer::runInfo [private] |
Definition at line 96 of file ExternalLHEProducer.cc.
Referenced by beginRun(), nextEvent(), and produce().
boost::shared_ptr<lhef::LHERunInfo> ExternalLHEProducer::runInfoLast [private] |
Definition at line 95 of file ExternalLHEProducer.cc.
Referenced by beginRun(), and nextEvent().
boost::ptr_deque<LHERunInfoProduct> ExternalLHEProducer::runInfoProducts [private] |
Definition at line 98 of file ExternalLHEProducer.cc.
Referenced by beginRun(), endRun(), and produce().
std::string ExternalLHEProducer::scriptName_ [private] |
Definition at line 88 of file ExternalLHEProducer.cc.
Referenced by executeScript().
bool ExternalLHEProducer::wasMerged [private] |
Definition at line 99 of file ExternalLHEProducer.cc.
Referenced by beginRun(), and produce().