CMS 3D CMS Logo

List of all members | Classes | Public Member Functions | Static Public Member Functions | Private Member Functions | Private Attributes
ExternalLHEProducer Class Reference

#include <Example/ExternalLHEProducer/src/ExternalLHEProducer.cc>

Inheritance diagram for ExternalLHEProducer:
edm::one::EDProducer< edm::BeginRunProducer, edm::one::WatchRuns > edm::one::EDProducerBase edm::ProducerBase edm::EDConsumerBase edm::ProductRegistryHelper

Classes

class  FileCloseSentry
 

Public Member Functions

 ExternalLHEProducer (const edm::ParameterSet &iConfig)
 
- Public Member Functions inherited from edm::one::EDProducer< edm::BeginRunProducer, edm::one::WatchRuns >
 EDProducer ()=default
 
 EDProducer (const EDProducer &)=delete
 
SerialTaskQueueglobalLuminosityBlocksQueue () final
 
SerialTaskQueueglobalRunsQueue () final
 
bool hasAbilityToProduceInBeginLumis () const final
 
bool hasAbilityToProduceInBeginProcessBlocks () const final
 
bool hasAbilityToProduceInBeginRuns () const final
 
bool hasAbilityToProduceInEndLumis () const final
 
bool hasAbilityToProduceInEndProcessBlocks () const final
 
bool hasAbilityToProduceInEndRuns () const final
 
const EDProduceroperator= (const EDProducer &)=delete
 
bool wantsGlobalLuminosityBlocks () const final
 
bool wantsGlobalRuns () const final
 
bool wantsInputProcessBlocks () const final
 
bool wantsProcessBlocks () const final
 
- Public Member Functions inherited from edm::one::EDProducerBase
 EDProducerBase ()
 
ModuleDescription const & moduleDescription () const
 
bool wantsStreamLuminosityBlocks () const
 
bool wantsStreamRuns () const
 
 ~EDProducerBase () override
 
- Public Member Functions inherited from edm::ProducerBase
void callWhenNewProductsRegistered (std::function< void(BranchDescription const &)> const &func)
 
std::vector< edm::ProductResolverIndex > const & indiciesForPutProducts (BranchType iBranchType) const
 
 ProducerBase ()
 
std::vector< edm::ProductResolverIndex > const & putTokenIndexToProductResolverIndex () const
 
std::vector< bool > const & recordProvenanceList () const
 
void registerProducts (ProducerBase *, ProductRegistry *, ModuleDescription const &)
 
std::function< void(BranchDescription const &)> registrationCallback () const
 used by the fwk to register list of products More...
 
void resolvePutIndicies (BranchType iBranchType, ModuleToResolverIndicies const &iIndicies, std::string const &moduleLabel)
 
TypeLabelList const & typeLabelList () const
 used by the fwk to register the list of products of this module More...
 
 ~ProducerBase () noexcept(false) override
 
- Public Member Functions inherited from edm::EDConsumerBase
std::vector< ConsumesInfoconsumesInfo () const
 
void convertCurrentProcessAlias (std::string const &processName)
 Convert "@currentProcess" in InputTag process names to the actual current process name. More...
 
 EDConsumerBase ()
 
 EDConsumerBase (EDConsumerBase const &)=delete
 
 EDConsumerBase (EDConsumerBase &&)=default
 
ESResolverIndex const * esGetTokenIndices (edm::Transition iTrans) const
 
std::vector< ESResolverIndex > const & esGetTokenIndicesVector (edm::Transition iTrans) const
 
std::vector< ESRecordIndex > const & esGetTokenRecordIndicesVector (edm::Transition iTrans) const
 
ProductResolverIndexAndSkipBit indexFrom (EDGetToken, BranchType, TypeID const &) const
 
void itemsMayGet (BranchType, std::vector< ProductResolverIndexAndSkipBit > &) const
 
void itemsToGet (BranchType, std::vector< ProductResolverIndexAndSkipBit > &) const
 
std::vector< ProductResolverIndexAndSkipBit > const & itemsToGetFrom (BranchType iType) const
 
void labelsForToken (EDGetToken iToken, Labels &oLabels) const
 
void modulesWhoseProductsAreConsumed (std::array< std::vector< ModuleDescription const *> *, NumBranchTypes > &modulesAll, std::vector< ModuleProcessName > &modulesInPreviousProcesses, ProductRegistry const &preg, std::map< std::string, ModuleDescription const *> const &labelsToDesc, std::string const &processName) const
 
EDConsumerBase const & operator= (EDConsumerBase const &)=delete
 
EDConsumerBaseoperator= (EDConsumerBase &&)=default
 
bool registeredToConsume (ProductResolverIndex, bool, BranchType) const
 
void selectInputProcessBlocks (ProductRegistry const &productRegistry, ProcessBlockHelperBase const &processBlockHelperBase)
 
ProductResolverIndexAndSkipBit uncheckedIndexFrom (EDGetToken) const
 
void updateLookup (BranchType iBranchType, ProductResolverIndexHelper const &, bool iPrefetchMayGet)
 
void updateLookup (eventsetup::ESRecordsToProductResolverIndices const &)
 
virtual ~EDConsumerBase () noexcept(false)
 

Static Public Member Functions

static void fillDescriptions (edm::ConfigurationDescriptions &descriptions)
 
- Static Public Member Functions inherited from edm::one::EDProducerBase
static const std::string & baseType ()
 
static void fillDescriptions (ConfigurationDescriptions &descriptions)
 
static void prevalidate (ConfigurationDescriptions &descriptions)
 

Private Member Functions

void beginRun (edm::Run const &, edm::EventSetup const &) override
 
void beginRunProduce (edm::Run &run, edm::EventSetup const &es) override
 
int closeDescriptors (int preserve) const
 
void endRun (edm::Run const &, edm::EventSetup const &) override
 
void executeScript (std::vector< std::string > const &args, int id, bool isPost) const
 
std::unique_ptr< LHERunInfoProductgenerateRunInfo (std::vector< std::string > const &files) const
 
std::vector< std::string > makeArgs (uint32_t nEvents, unsigned int nThreads, std::uint32_t seed) const
 
void nextEvent ()
 
void preallocThreads (unsigned int) override
 
void produce (edm::Event &, const edm::EventSetup &) override
 

Private Attributes

const std::vector< std::string > args_
 
edm::EDPutTokenT< LHERunInfoProductbeginRunPutToken_
 
edm::EDPutTokenT< LHEEventProducteventPutToken_
 
bool generateConcurrently_ {false}
 
uint32_t nEvents_
 
uint32_t npars_
 
std::map< unsigned, std::pair< unsigned, unsigned > > nPartonMapping_ {}
 
unsigned int nThreads_ {1}
 
std::string outputContents_
 
std::string outputFile_
 
std::shared_ptr< lhef::LHEEventpartonLevel_
 
const std::vector< std::string > postGenerationCommand_
 
std::unique_ptr< lhef::LHEReaderreader_
 
std::string scriptName_
 
bool storeXML_
 
bool wasMerged_
 
edm::EDPutTokenT< LHEXMLStringProductxmlPutToken_
 

Additional Inherited Members

- Public Types inherited from edm::one::EDProducerBase
typedef EDProducerBase ModuleType
 
- Public Types inherited from edm::ProducerBase
template<typename T >
using BranchAliasSetterT = ProductRegistryHelper::BranchAliasSetterT< T >
 
using ModuleToResolverIndicies = std::unordered_multimap< std::string, std::tuple< edm::TypeID const *, const char *, edm::ProductResolverIndex > >
 
typedef ProductRegistryHelper::TypeLabelList TypeLabelList
 
- Public Types inherited from edm::EDConsumerBase
typedef ProductLabels Labels
 
- Protected Member Functions inherited from edm::ProducerBase
template<Transition Tr = Transition::Event>
auto produces (std::string instanceName) noexcept
 declare what type of product will make and with which optional label More...
 
template<Transition B>
BranchAliasSetter produces (const TypeID &id, std::string instanceName=std::string(), bool recordProvenance=true)
 
template<BranchType B>
BranchAliasSetter produces (const TypeID &id, std::string instanceName=std::string(), bool recordProvenance=true)
 
BranchAliasSetter produces (const TypeID &id, std::string instanceName=std::string(), bool recordProvenance=true)
 
template<typename ProductType , Transition B>
BranchAliasSetterT< ProductType > produces (std::string instanceName)
 
template<class ProductType >
BranchAliasSetterT< ProductType > produces ()
 
template<typename ProductType , BranchType B>
BranchAliasSetterT< ProductType > produces (std::string instanceName)
 
template<typename ProductType , BranchType B>
BranchAliasSetterT< ProductType > produces ()
 
template<class ProductType >
BranchAliasSetterT< ProductType > produces (std::string instanceName)
 
template<typename ProductType , Transition B>
BranchAliasSetterT< ProductType > produces ()
 
template<Transition Tr = Transition::Event>
auto produces () noexcept
 
ProducesCollector producesCollector ()
 
- Protected Member Functions inherited from edm::EDConsumerBase
template<typename ProductType , BranchType B = InEvent>
EDGetTokenT< ProductType > consumes (edm::InputTag const &tag)
 
template<BranchType B = InEvent>
EDConsumerBaseAdaptor< Bconsumes (edm::InputTag tag) noexcept
 
EDGetToken consumes (const TypeToGet &id, edm::InputTag const &tag)
 
template<BranchType B>
EDGetToken consumes (TypeToGet const &id, edm::InputTag const &tag)
 
ConsumesCollector consumesCollector ()
 Use a ConsumesCollector to gather consumes information from helper functions. More...
 
template<typename ESProduct , typename ESRecord , Transition Tr = Transition::Event>
auto esConsumes ()
 
template<typename ESProduct , typename ESRecord , Transition Tr = Transition::Event>
auto esConsumes (ESInputTag const &tag)
 
template<Transition Tr = Transition::Event>
constexpr auto esConsumes ()
 
template<Transition Tr = Transition::Event>
auto esConsumes (ESInputTag tag)
 
template<Transition Tr = Transition::Event>
ESGetTokenGeneric esConsumes (eventsetup::EventSetupRecordKey const &iRecord, eventsetup::DataKey const &iKey)
 Used with EventSetupRecord::doGet. More...
 
template<typename ProductType , BranchType B = InEvent>
EDGetTokenT< ProductType > mayConsume (edm::InputTag const &tag)
 
EDGetToken mayConsume (const TypeToGet &id, edm::InputTag const &tag)
 
template<BranchType B>
EDGetToken mayConsume (const TypeToGet &id, edm::InputTag const &tag)
 
void resetItemsToGetFrom (BranchType iType)
 

Detailed Description

Description: [one line class summary]

Implementation: [Notes on implementation]

Definition at line 69 of file ExternalLHEProducer.cc.

Constructor & Destructor Documentation

◆ ExternalLHEProducer()

ExternalLHEProducer::ExternalLHEProducer ( const edm::ParameterSet iConfig)
explicit

Definition at line 129 of file ExternalLHEProducer.cc.

References args_, beginRunPutToken_, looper::cfg, eventPutToken_, Exception, edm::ParameterSet::exists(), edm::ParameterSet::getParameterSetVector(), np, npars_, nPartonMapping_, eventshapeDQM_cfi::order, AlCaHLTBitMon_QueryRunRegistry::string, and xmlPutToken_.

130  : scriptName_((iConfig.getParameter<edm::FileInPath>("scriptName")).fullPath()),
131  outputFile_(iConfig.getParameter<std::string>("outputFile")),
132  args_(iConfig.getParameter<std::vector<std::string>>("args")),
133  npars_(iConfig.getParameter<uint32_t>("numberOfParameters")),
134  nEvents_(iConfig.getUntrackedParameter<uint32_t>("nEvents")),
135  storeXML_(iConfig.getUntrackedParameter<bool>("storeXML")),
136  generateConcurrently_(iConfig.getUntrackedParameter<bool>("generateConcurrently")),
137  postGenerationCommand_(iConfig.getUntrackedParameter<std::vector<std::string>>("postGenerationCommand")) {
138  if (npars_ != args_.size())
139  throw cms::Exception("ExternalLHEProducer")
140  << "Problem with configuration: " << args_.size() << " script arguments given, expected " << npars_;
141 
142  if (iConfig.exists("nPartonMapping")) {
143  auto& processMap(iConfig.getParameterSetVector("nPartonMapping"));
144  for (auto& cfg : processMap) {
145  unsigned processId(cfg.getParameter<unsigned>("idprup"));
146 
147  auto orderStr(cfg.getParameter<std::string>("order"));
148  unsigned order(0);
149  if (orderStr == "LO")
150  order = 0;
151  else if (orderStr == "NLO")
152  order = 1;
153  else
154  throw cms::Exception("ExternalLHEProducer")
155  << "Invalid order specification for process " << processId << ": " << orderStr;
156 
157  unsigned np(cfg.getParameter<unsigned>("np"));
158 
159  nPartonMapping_.emplace(processId, std::make_pair(order, np));
160  }
161  }
162 
163  xmlPutToken_ = produces<LHEXMLStringProduct, edm::Transition::BeginRun>("LHEScriptOutput");
164 
165  eventPutToken_ = produces<LHEEventProduct>();
166  beginRunPutToken_ = produces<LHERunInfoProduct, edm::Transition::BeginRun>();
167 }
T getParameter(std::string const &) const
Definition: ParameterSet.h:307
bool exists(std::string const &parameterName) const
checks if a parameter exists
edm::EDPutTokenT< LHERunInfoProduct > beginRunPutToken_
edm::EDPutTokenT< LHEEventProduct > eventPutToken_
T getUntrackedParameter(std::string const &, T const &) const
int np
Definition: AMPTWrapper.h:43
edm::EDPutTokenT< LHEXMLStringProduct > xmlPutToken_
std::map< unsigned, std::pair< unsigned, unsigned > > nPartonMapping_
const std::vector< std::string > args_
const std::vector< std::string > postGenerationCommand_
VParameterSet const & getParameterSetVector(std::string const &name) const

Member Function Documentation

◆ beginRun()

void ExternalLHEProducer::beginRun ( edm::Run const &  run,
edm::EventSetup const &  es 
)
overrideprivate

Definition at line 343 of file ExternalLHEProducer.cc.

343 {}

◆ beginRunProduce()

void ExternalLHEProducer::beginRunProduce ( edm::Run run,
edm::EventSetup const &  es 
)
overrideprivate

Definition at line 238 of file ExternalLHEProducer.cc.

References beginRunPutToken_, CMS_SA_ALLOW, MillePedeFileConverter_cfg::e, Exception, executeScript(), geometryDiff::file, edm::FileInPath::fullPath(), generateConcurrently_, generateRunInfo(), watchdog::group, edm::Service< T >::isAvailable(), makeArgs(), eostools::move(), edm::RandomNumberGenerator::mySeed(), createIOVlist::nEvents, nEvents_, nextEvent(), nThreads_, MillePedeFileConverter_cfg::out, outputFile_, AlCaHLTBitMon_ParallelJobs::p, castor_dqm_sourceclient_file_cfg::path, postGenerationCommand_, reader_, writedatasetfile::run, submitPVValidationJobs::runInfo, alignCSCRings::s, fileCollector::seed, optionsL1T::skip, storeXML_, AlCaHLTBitMon_QueryRunRegistry::string, submitPVValidationJobs::t, to_string(), and xmlPutToken_.

238  {
239  // pass the number of events as previous to last argument
240 
241  // pass the random number generator seed as last argument
242 
244 
245  if (!rng.isAvailable()) {
246  throw cms::Exception("Configuration")
247  << "The ExternalLHEProducer module requires the RandomNumberGeneratorService\n"
248  "which is not present in the configuration file. You must add the service\n"
249  "in the configuration file if you want to run ExternalLHEProducer";
250  }
251 
252  std::vector<std::string> infiles;
253  auto const seed = rng->mySeed();
254  if (generateConcurrently_) {
255  infiles.resize(nThreads_);
256  auto const nEventsAve = nEvents_ / nThreads_;
257  unsigned int const overflow = nThreads_ - (nEvents_ % nThreads_);
258  std::exception_ptr except;
259  std::atomic<char> exceptSet{0};
260 
261  tbb::this_task_arena::isolate([this, &except, &infiles, &exceptSet, nEventsAve, overflow, seed]() {
262  tbb::task_group group;
263  for (unsigned int t = 0; t < nThreads_; ++t) {
264  uint32_t nEvents = nEventsAve;
265  if (nEvents_ % nThreads_ != 0 and t >= overflow) {
266  nEvents += 1;
267  }
268  group.run([t, this, &infiles, seed, nEvents, &except, &exceptSet]() {
269  CMS_SA_ALLOW try {
270  using namespace std::filesystem;
271  using namespace std::string_literals;
272  auto out = path("thread"s + std::to_string(t)) / path(outputFile_);
273  infiles[t] = out.native();
274  executeScript(makeArgs(nEvents, 1, seed + t), t, false);
275  } catch (...) {
276  char expected = 0;
277  if (exceptSet.compare_exchange_strong(expected, 1)) {
278  except = std::current_exception();
279  exceptSet.store(2);
280  }
281  }
282  });
283  }
284  group.wait();
285  });
286  if (exceptSet != 0) {
287  std::rethrow_exception(except);
288  }
289  } else {
290  infiles = std::vector<std::string>(1, outputFile_);
292  }
293 
294  //run post-generation command if specified
295  if (!postGenerationCommand_.empty()) {
296  std::vector<std::string> postcmd = postGenerationCommand_;
297  try {
298  postcmd[0] = edm::FileInPath(postcmd[0]).fullPath();
299  } catch (const edm::Exception& e) {
300  edm::LogWarning("ExternalLHEProducer") << postcmd[0] << " is not a relative path. Run it as a shell command.";
301  }
302  executeScript(postcmd, 0, true);
303  }
304 
305  //fill LHEXMLProduct (streaming read directly into compressed buffer to save memory)
306  std::unique_ptr<LHEXMLStringProduct> p(new LHEXMLStringProduct);
307 
308  //store the XML file only if explictly requested
309  if (storeXML_) {
311  if (generateConcurrently_) {
312  using namespace std::filesystem;
313  file = (path("thread0") / path(outputFile_)).native();
314  } else {
315  file = outputFile_;
316  }
317  std::ifstream instream(file);
318  if (!instream) {
319  throw cms::Exception("OutputOpenError") << "Unable to open script output file " << outputFile_ << ".";
320  }
321  instream.seekg(0, instream.end);
322  int insize = instream.tellg();
323  instream.seekg(0, instream.beg);
324  p->fillCompressedContent(instream, 0.25 * insize);
325  instream.close();
326  }
327  run.put(xmlPutToken_, std::move(p));
328 
329  //Read the beginning of each file to get the run info in order to do the merge
330  auto runInfo = generateRunInfo(infiles);
331  if (runInfo) {
333  }
334 
335  // LHE C++ classes translation
336  // (read back uncompressed file from disk in streaming mode again to save memory)
337  unsigned int skip = 0;
338  reader_ = std::make_unique<lhef::LHEReader>(infiles, skip);
339 
340  nextEvent();
341 }
#define CMS_SA_ALLOW
std::string fullPath() const
Definition: FileInPath.cc:161
edm::EDPutTokenT< LHERunInfoProduct > beginRunPutToken_
static std::string to_string(const XMLCh *ch)
std::unique_ptr< LHERunInfoProduct > generateRunInfo(std::vector< std::string > const &files) const
virtual std::uint32_t mySeed() const =0
edm::EDPutTokenT< LHEXMLStringProduct > xmlPutToken_
std::unique_ptr< lhef::LHEReader > reader_
void executeScript(std::vector< std::string > const &args, int id, bool isPost) const
std::vector< std::string > makeArgs(uint32_t nEvents, unsigned int nThreads, std::uint32_t seed) const
const std::vector< std::string > postGenerationCommand_
bool isAvailable() const
Definition: Service.h:40
Log< level::Warning, false > LogWarning
def move(src, dest)
Definition: eostools.py:511

◆ closeDescriptors()

int ExternalLHEProducer::closeDescriptors ( int  preserve) const
private

Definition at line 401 of file ExternalLHEProducer.cc.

References dqmPostProcessing_online::DIR, DeadROC_duringRun::dir, Calorimetry_cff::dp, and ztee::fd.

Referenced by executeScript().

401  {
402  int maxfd = 1024;
403  int fd;
404 #ifdef __linux__
405  DIR* dir;
406  struct dirent* dp;
407  maxfd = preserve;
408  if ((dir = opendir("/proc/self/fd"))) {
409  errno = 0;
410  while ((dp = readdir(dir)) != nullptr) {
411  if ((strcmp(dp->d_name, ".") == 0) || (strcmp(dp->d_name, "..") == 0)) {
412  continue;
413  }
414  if (sscanf(dp->d_name, "%d", &fd) != 1) {
415  //throw cms::Exception("closeDescriptors") << "Found unexpected filename in /proc/self/fd: " << dp->d_name;
416  return -1;
417  }
418  if (fd > maxfd) {
419  maxfd = fd;
420  }
421  }
422  if (errno) {
423  //throw cms::Exception("closeDescriptors") << "Unable to determine the number of fd (errno=" << errno << ", " << strerror(errno) << ").";
424  return errno;
425  }
426  closedir(dir);
427  }
428 #endif
429  // TODO: assert for an unreasonable number of fds?
430  for (fd = 3; fd < maxfd + 1; fd++) {
431  if (fd != preserve)
432  close(fd);
433  }
434  return 0;
435 }
fd
Definition: ztee.py:136

◆ endRun()

void ExternalLHEProducer::endRun ( edm::Run const &  run,
edm::EventSetup const &  es 
)
overrideprivate

Definition at line 345 of file ExternalLHEProducer.cc.

References edm::errors::EventGenerationFailure, Exception, generateConcurrently_, nextEvent(), nThreads_, MillePedeFileConverter_cfg::out, outputFile_, partonLevel_, castor_dqm_sourceclient_file_cfg::path, reader_, alignCSCRings::s, submitPVValidationJobs::t, and to_string().

345  {
346  nextEvent();
347  if (partonLevel_) {
348  // VALIDATION_RUN env variable allows to finish event processing early without errors by sending SIGINT
349  if (std::getenv("VALIDATION_RUN") != nullptr) {
350  edm::LogWarning("ExternalLHEProducer")
351  << "Event loop is over, but there are still lhe events to process, ignoring...";
352  } else {
354  << "Error in ExternalLHEProducer::endRunProduce(). "
355  << "Event loop is over, but there are still lhe events to process."
356  << "This could happen if lhe file contains more events than requested. This is never expected to happen.";
357  }
358  }
359 
360  reader_.reset();
361  if (generateConcurrently_) {
362  for (unsigned int t = 0; t < nThreads_; ++t) {
363  using namespace std::filesystem;
364  using namespace std::string_literals;
365  auto out = path("thread"s + std::to_string(t)) / path(outputFile_);
366  if (unlink(out.c_str())) {
367  throw cms::Exception("OutputDeleteError") << "Unable to delete original script output file " << out
368  << " (errno=" << errno << ", " << strerror(errno) << ").";
369  }
370  }
371  } else {
372  if (unlink(outputFile_.c_str())) {
373  throw cms::Exception("OutputDeleteError") << "Unable to delete original script output file " << outputFile_
374  << " (errno=" << errno << ", " << strerror(errno) << ").";
375  }
376  }
377 }
static std::string to_string(const XMLCh *ch)
std::unique_ptr< lhef::LHEReader > reader_
Log< level::Warning, false > LogWarning
std::shared_ptr< lhef::LHEEvent > partonLevel_

◆ executeScript()

void ExternalLHEProducer::executeScript ( std::vector< std::string > const &  args,
int  id,
bool  isPost 
) const
private

Definition at line 438 of file ExternalLHEProducer.cc.

References dir2webdir::argc, writedatasetfile::args, GCPpyPlots::argv, closeDescriptors(), Exception, free(), generateConcurrently_, mps_fire::i, NULL, castor_dqm_sourceclient_file_cfg::path, pipe::pipe(), fileinputsource_cfi::read, alignCSCRings::s, scriptName_, mps_update::status, to_string(), and writeEcalDQMStatus::write.

Referenced by beginRunProduce().

438  {
439  // Fork a script, wait until it finishes.
440 
441  int rc = 0, rc2 = 0;
442  int filedes[2], fd_flags;
443 
444  if (pipe(filedes)) {
445  throw cms::Exception("Unable to create a new pipe");
446  }
447  FileCloseSentry sentry1(filedes[0]), sentry2(filedes[1]);
448 
449  if ((fd_flags = fcntl(filedes[1], F_GETFD, NULL)) == -1) {
450  throw cms::Exception("ExternalLHEProducer")
451  << "Failed to get pipe file descriptor flags (errno=" << rc << ", " << strerror(rc) << ")";
452  }
453  if (fcntl(filedes[1], F_SETFD, fd_flags | FD_CLOEXEC) == -1) {
454  throw cms::Exception("ExternalLHEProducer")
455  << "Failed to set pipe file descriptor flags (errno=" << rc << ", " << strerror(rc) << ")";
456  }
457 
458  unsigned int argc_pre = 0;
459  // For generation command the first argument gives to the scriptName
460  if (!isPost) {
461  argc_pre = 1;
462  }
463  unsigned int argc = argc_pre + args.size();
464  // TODO: assert that we have a reasonable number of arguments
465  char** argv = new char*[argc + 1];
466  if (!isPost) {
467  argv[0] = strdup(scriptName_.c_str());
468  }
469  for (unsigned int i = 0; i < args.size(); i++) {
470  argv[argc_pre + i] = strdup(args[i].c_str());
471  }
472  argv[argc] = nullptr;
473 
474  pid_t pid = fork();
475  if (pid == 0) {
476  // The child process
477  if (!(rc = closeDescriptors(filedes[1]))) {
478  if (!isPost && generateConcurrently_) {
479  using namespace std::filesystem;
480  using namespace std::string_literals;
481  std::error_code ec;
482  auto newDir = path("thread"s + std::to_string(id));
483  create_directory(newDir, ec);
484  current_path(newDir, ec);
485  }
486  execvp(argv[0], argv); // If execv returns, we have an error.
487  rc = errno;
488  }
489  while ((write(filedes[1], &rc, sizeof(int)) == -1) && (errno == EINTR)) {
490  }
491  _exit(1);
492  }
493 
494  // Free the arg vector ASAP
495  for (unsigned int i = 0; i < args.size() + 1; i++) {
496  free(argv[i]);
497  }
498  delete[] argv;
499 
500  if (pid == -1) {
501  throw cms::Exception("ForkException")
502  << "Unable to fork a child (errno=" << errno << ", " << strerror(errno) << ")";
503  }
504 
505  close(filedes[1]);
506  // If the exec succeeds, the read will fail.
507  while (((rc2 = read(filedes[0], &rc, sizeof(int))) == -1) && (errno == EINTR)) {
508  rc2 = 0;
509  }
510  if ((rc2 == sizeof(int)) && rc) {
511  throw cms::Exception("ExternalLHEProducer")
512  << "Failed to execute script (errno=" << rc << ", " << strerror(rc) << ")";
513  }
514  close(filedes[0]);
515 
516  int status = 0;
517  errno = 0;
518  do {
519  if (waitpid(pid, &status, 0) < 0) {
520  if (errno == EINTR) {
521  continue;
522  } else {
523  throw cms::Exception("ExternalLHEProducer")
524  << "Failed to read child status (errno=" << errno << ", " << strerror(errno) << ")";
525  }
526  }
527  if (WIFSIGNALED(status)) {
528  throw cms::Exception("ExternalLHEProducer") << "Child exited due to signal " << WTERMSIG(status) << ".";
529  }
530  if (WIFEXITED(status)) {
531  rc = WEXITSTATUS(status);
532  break;
533  }
534  } while (true);
535  if (rc) {
536  throw cms::Exception("ExternalLHEProducer") << "Child failed with exit code " << rc << ".";
537  }
538 }
#define NULL
Definition: scimark2.h:8
static std::string to_string(const XMLCh *ch)
void free(void *ptr) noexcept
def pipe(cmdline, input=None)
Definition: pipe.py:5
int closeDescriptors(int preserve) const

◆ fillDescriptions()

void ExternalLHEProducer::fillDescriptions ( edm::ConfigurationDescriptions descriptions)
static

Definition at line 541 of file ExternalLHEProducer.cc.

References edm::ParameterSetDescription::add(), edm::ConfigurationDescriptions::addDefault(), submitPVResolutionJobs::desc, and AlCaHLTBitMon_QueryRunRegistry::string.

541  {
542  //The following says we do not know what parameters are allowed so do no validation
543  // Please change this to state exactly what you do use, even if it is no parameters
545  desc.setComment("Executes an external script and places its output file into an EDM collection");
546 
547  edm::FileInPath thePath;
548  desc.add<edm::FileInPath>("scriptName", thePath);
549  desc.add<std::string>("outputFile", "myoutput");
550  desc.add<std::vector<std::string>>("args");
551  desc.add<uint32_t>("numberOfParameters");
552  desc.addUntracked<uint32_t>("nEvents");
553  desc.addUntracked<bool>("storeXML", false);
554  desc.addUntracked<bool>("generateConcurrently", false)
555  ->setComment("If true, run the script concurrently in separate processes.");
556  desc.addUntracked<std::vector<std::string>>("postGenerationCommand", std::vector<std::string>())
557  ->setComment(
558  "Command to run after the generation script has completed. The first argument can be a relative path.");
559 
560  edm::ParameterSetDescription nPartonMappingDesc;
561  nPartonMappingDesc.add<unsigned>("idprup");
562  nPartonMappingDesc.add<std::string>("order");
563  nPartonMappingDesc.add<unsigned>("np");
564  desc.addVPSetOptional("nPartonMapping", nPartonMappingDesc);
565 
566  descriptions.addDefault(desc);
567 }
void addDefault(ParameterSetDescription const &psetDescription)
ParameterDescriptionBase * add(U const &iLabel, T const &value)

◆ generateRunInfo()

std::unique_ptr< LHERunInfoProduct > ExternalLHEProducer::generateRunInfo ( std::vector< std::string > const &  files) const
private

Definition at line 569 of file ExternalLHEProducer.cc.

References LHERunInfoProduct::addComment(), LHERunInfoProduct::addHeader(), geometryDiff::file, LHERunInfoProduct::mergeProduct(), eostools::move(), DQM::reader, submitPVValidationJobs::runInfo, and optionsL1T::skip.

Referenced by beginRunProduce().

569  {
570  std::unique_ptr<LHERunInfoProduct> retValue;
571  //read each file in turn and only get the header info
572  for (auto const& file : iFiles) {
573  unsigned int skip = 0;
574  std::vector<std::string> infiles(1, file);
575  auto reader = std::make_unique<lhef::LHEReader>(infiles, skip);
576  auto parton = reader->next();
577  if (!parton) {
578  break;
579  }
580  auto runInfo = parton->getRunInfo();
581  LHERunInfoProduct product(*runInfo->getHEPRUP());
582 
583  std::for_each(runInfo->getHeaders().begin(),
584  runInfo->getHeaders().end(),
585  std::bind(&LHERunInfoProduct::addHeader, &product, std::placeholders::_1));
586  std::for_each(runInfo->getComments().begin(),
587  runInfo->getComments().end(),
588  std::bind(&LHERunInfoProduct::addComment, &product, std::placeholders::_1));
589  if (not retValue) {
590  retValue = std::make_unique<LHERunInfoProduct>(std::move(product));
591  } else {
592  retValue->mergeProduct(product);
593  }
594  }
595 
596  return retValue;
597 }
void addHeader(const Header &header)
reader
Definition: DQM.py:105
void addComment(const std::string &line)
bool mergeProduct(const LHERunInfoProduct &other)
def move(src, dest)
Definition: eostools.py:511

◆ makeArgs()

std::vector< std::string > ExternalLHEProducer::makeArgs ( uint32_t  nEvents,
unsigned int  nThreads,
std::uint32_t  seed 
) const
private

Definition at line 379 of file ExternalLHEProducer.cc.

References writedatasetfile::args, args_, filterCSVwithJSON::copy, LogDebug, createIOVlist::nEvents, fileCollector::seed, and to_string().

Referenced by beginRunProduce().

381  {
382  std::vector<std::string> args;
383  args.reserve(3 + args_.size());
384 
385  args.push_back(args_.front());
386  args.push_back(std::to_string(nEvents));
387 
388  args.push_back(std::to_string(seed));
389 
390  args.push_back(std::to_string(nThreads));
391  std::copy(args_.begin() + 1, args_.end(), std::back_inserter(args));
392 
393  for (unsigned int iArg = 0; iArg < args.size(); iArg++) {
394  LogDebug("LHEInputArgs") << "arg [" << iArg << "] = " << args[iArg];
395  }
396 
397  return args;
398 }
static std::string to_string(const XMLCh *ch)
const std::vector< std::string > args_
#define LogDebug(id)

◆ nextEvent()

void ExternalLHEProducer::nextEvent ( )
private

Definition at line 599 of file ExternalLHEProducer.cc.

References partonLevel_, and reader_.

Referenced by beginRunProduce(), endRun(), and produce().

599  {
600  if (partonLevel_)
601  return;
602 
603  if (not reader_) {
604  return;
605  }
606 
607  partonLevel_ = reader_->next();
608  if (!partonLevel_) {
609  //see if we have another file to read;
610  bool newFileOpened;
611  do {
612  newFileOpened = false;
613  partonLevel_ = reader_->next(&newFileOpened);
614  } while (newFileOpened && !partonLevel_);
615  }
616 }
std::unique_ptr< lhef::LHEReader > reader_
std::shared_ptr< lhef::LHEEvent > partonLevel_

◆ preallocThreads()

void ExternalLHEProducer::preallocThreads ( unsigned int  iThreads)
overrideprivatevirtual

Reimplemented from edm::one::EDProducerBase.

Definition at line 174 of file ExternalLHEProducer.cc.

References nThreads_.

174 { nThreads_ = iThreads; }

◆ produce()

void ExternalLHEProducer::produce ( edm::Event iEvent,
const edm::EventSetup iSetup 
)
overrideprivatevirtual

Implements edm::one::EDProducerBase.

Definition at line 177 of file ExternalLHEProducer.cc.

References LHEEventProduct::addComment(), LHEEventProduct::addWeight(), edm::errors::EventGenerationFailure, eventPutToken_, Exception, iEvent, lhe2HepMCConverter_cff::LHEEventProduct, eostools::move(), nextEvent(), np, nPartonMapping_, eventshapeDQM_cfi::order, and partonLevel_.

177  {
178  nextEvent();
179  if (!partonLevel_) {
181  << "No lhe event found in ExternalLHEProducer::produce(). "
182  << "The likely cause is that the lhe file contains fewer events than were requested, which is possible "
183  << "in case of phase space integration or uneweighting efficiency problems.";
184  }
185 
186  std::unique_ptr<LHEEventProduct> product(
187  new LHEEventProduct(*partonLevel_->getHEPEUP(), partonLevel_->originalXWGTUP()));
188  if (partonLevel_->getPDF()) {
189  product->setPDF(*partonLevel_->getPDF());
190  }
191  std::for_each(partonLevel_->weights().begin(),
192  partonLevel_->weights().end(),
193  std::bind(&LHEEventProduct::addWeight, product.get(), std::placeholders::_1));
194  product->setScales(partonLevel_->scales());
195  product->setEvtNum(partonLevel_->evtnum());
196  if (nPartonMapping_.empty()) {
197  product->setNpLO(partonLevel_->npLO());
198  product->setNpNLO(partonLevel_->npNLO());
199  } else {
200  // overwrite npLO and npNLO values by user-specified mapping
201  unsigned processId(partonLevel_->getHEPEUP()->IDPRUP);
202  unsigned order(0);
203  unsigned np(0);
204  try {
205  auto procDef(nPartonMapping_.at(processId));
206  order = procDef.first;
207  np = procDef.second;
208  } catch (std::out_of_range&) {
209  throw cms::Exception("ExternalLHEProducer")
210  << "Unexpected IDPRUP encountered: " << partonLevel_->getHEPEUP()->IDPRUP;
211  }
212 
213  switch (order) {
214  case 0:
215  product->setNpLO(np);
216  product->setNpNLO(-1);
217  break;
218  case 1:
219  product->setNpLO(-1);
220  product->setNpNLO(np);
221  break;
222  default:
223  break;
224  }
225  }
226 
227  std::for_each(partonLevel_->getComments().begin(),
228  partonLevel_->getComments().end(),
229  std::bind(&LHEEventProduct::addComment, product.get(), std::placeholders::_1));
230 
231  iEvent.put(eventPutToken_, std::move(product));
232 
233  partonLevel_.reset();
234  return;
235 }
void addComment(const std::string &line)
void addWeight(const WGT &wgt)
edm::EDPutTokenT< LHEEventProduct > eventPutToken_
int iEvent
Definition: GenABIO.cc:224
int np
Definition: AMPTWrapper.h:43
std::map< unsigned, std::pair< unsigned, unsigned > > nPartonMapping_
def move(src, dest)
Definition: eostools.py:511
std::shared_ptr< lhef::LHEEvent > partonLevel_

Member Data Documentation

◆ args_

const std::vector<std::string> ExternalLHEProducer::args_
private

◆ beginRunPutToken_

edm::EDPutTokenT<LHERunInfoProduct> ExternalLHEProducer::beginRunPutToken_
private

Definition at line 110 of file ExternalLHEProducer.cc.

Referenced by beginRunProduce(), and ExternalLHEProducer().

◆ eventPutToken_

edm::EDPutTokenT<LHEEventProduct> ExternalLHEProducer::eventPutToken_
private

Definition at line 109 of file ExternalLHEProducer.cc.

Referenced by ExternalLHEProducer(), and produce().

◆ generateConcurrently_

bool ExternalLHEProducer::generateConcurrently_ {false}
private

Definition at line 98 of file ExternalLHEProducer.cc.

Referenced by beginRunProduce(), endRun(), and executeScript().

◆ nEvents_

uint32_t ExternalLHEProducer::nEvents_
private

Definition at line 94 of file ExternalLHEProducer.cc.

Referenced by beginRunProduce().

◆ npars_

uint32_t ExternalLHEProducer::npars_
private

Definition at line 93 of file ExternalLHEProducer.cc.

Referenced by ExternalLHEProducer().

◆ nPartonMapping_

std::map<unsigned, std::pair<unsigned, unsigned> > ExternalLHEProducer::nPartonMapping_ {}
private

Definition at line 102 of file ExternalLHEProducer.cc.

Referenced by ExternalLHEProducer(), and produce().

◆ nThreads_

unsigned int ExternalLHEProducer::nThreads_ {1}
private

Definition at line 96 of file ExternalLHEProducer.cc.

Referenced by beginRunProduce(), endRun(), and preallocThreads().

◆ outputContents_

std::string ExternalLHEProducer::outputContents_
private

Definition at line 97 of file ExternalLHEProducer.cc.

◆ outputFile_

std::string ExternalLHEProducer::outputFile_
private

Definition at line 91 of file ExternalLHEProducer.cc.

Referenced by beginRunProduce(), and endRun().

◆ partonLevel_

std::shared_ptr<lhef::LHEEvent> ExternalLHEProducer::partonLevel_
private

Definition at line 105 of file ExternalLHEProducer.cc.

Referenced by endRun(), nextEvent(), and produce().

◆ postGenerationCommand_

const std::vector<std::string> ExternalLHEProducer::postGenerationCommand_
private

Definition at line 99 of file ExternalLHEProducer.cc.

Referenced by beginRunProduce().

◆ reader_

std::unique_ptr<lhef::LHEReader> ExternalLHEProducer::reader_
private

Definition at line 104 of file ExternalLHEProducer.cc.

Referenced by beginRunProduce(), endRun(), and nextEvent().

◆ scriptName_

std::string ExternalLHEProducer::scriptName_
private

Definition at line 90 of file ExternalLHEProducer.cc.

Referenced by executeScript().

◆ storeXML_

bool ExternalLHEProducer::storeXML_
private

Definition at line 95 of file ExternalLHEProducer.cc.

Referenced by beginRunProduce().

◆ wasMerged_

bool ExternalLHEProducer::wasMerged_
private

Definition at line 106 of file ExternalLHEProducer.cc.

◆ xmlPutToken_

edm::EDPutTokenT<LHEXMLStringProduct> ExternalLHEProducer::xmlPutToken_
private

Definition at line 108 of file ExternalLHEProducer.cc.

Referenced by beginRunProduce(), and ExternalLHEProducer().