CMS 3D CMS Logo

SherpaHadronizer.cc
Go to the documentation of this file.
1 #include <cassert>
2 #include <iostream>
3 #include <sstream>
4 #include <string>
5 #include <memory>
6 #include <cstdint>
7 #include <vector>
8 
9 #include "SHERPA/Main/Sherpa.H"
10 #include "ATOOLS/Math/Random.H"
11 
12 #include "ATOOLS/Org/Run_Parameter.H"
13 #include "ATOOLS/Org/MyStrStream.H"
14 #include "ATOOLS/Org/CXXFLAGS.H"
15 #include "ATOOLS/Org/CXXFLAGS_PACKAGES.H"
16 #include "ATOOLS/Org/My_MPI.H"
17 
23 
24 #include "CLHEP/Random/RandomEngine.h"
25 
26 //This unnamed namespace is used (instead of static variables) to pass the
27 //randomEngine passed to doSetRandomEngine to the External Random
28 //Number Generator CMS_SHERPA_RNG of sherpa
29 //The advantage of the unnamed namespace over static variables is
30 //that it is only accessible in this file
31 
32 namespace {
33  CLHEP::HepRandomEngine *ExternalEngine = nullptr;
34  CLHEP::HepRandomEngine *GetExternalEngine() { return ExternalEngine; }
35  void SetExternalEngine(CLHEP::HepRandomEngine *v) { ExternalEngine = v; }
36 } // namespace
37 
39 public:
41  ~SherpaHadronizer() override;
42 
43  bool readSettings(int) { return true; }
45  bool declareStableParticles(const std::vector<int> &pdgIds);
46  bool declareSpecialSettings(const std::vector<std::string> &) { return true; }
47  void statistics();
49  bool decay();
51  bool residualDecay();
52  void finalizeEvent();
53  std::unique_ptr<GenLumiInfoHeader> getGenLumiInfoHeader() const override;
54  const char *classname() const { return "SherpaHadronizer"; }
55 
56 private:
57  void doSetRandomEngine(CLHEP::HepRandomEngine *v) override;
58 
66  unsigned int maxEventsToPrint;
67  std::vector<std::string> arguments;
71  std::vector<std::string> weightlist;
72  std::vector<std::string> variationweightlist;
73 };
74 
75 class CMS_SHERPA_RNG : public ATOOLS::External_RNG {
76 public:
78  edm::LogVerbatim("SherpaHadronizer") << "Use stored reference for the external RNG";
79  setRandomEngine(GetExternalEngine());
80  }
81  void setRandomEngine(CLHEP::HepRandomEngine *v) { randomEngine = v; }
82 
83 private:
84  double Get() override;
85  CLHEP::HepRandomEngine *randomEngine;
86 };
87 
88 void SherpaHadronizer::doSetRandomEngine(CLHEP::HepRandomEngine *v) {
89  CMS_SHERPA_RNG *cmsSherpaRng = dynamic_cast<CMS_SHERPA_RNG *>(ATOOLS::ran->GetExternalRng());
90  if (cmsSherpaRng == nullptr) {
91  //First time call to this function makes the interface store the reference in the unnamed namespace
92  if (!isRNGinitialized) {
93  isRNGinitialized = true;
94  edm::LogVerbatim("SherpaHadronizer") << "Store assigned reference of the randomEngine";
95  SetExternalEngine(v);
96  // Throw exception if there is no reference to an external RNG and it is not the first call!
97  } else {
98  throw edm::Exception(edm::errors::LogicError) << "The Sherpa interface got a randomEngine reference but there is "
99  "no reference to the external RNG to hand it over to\n";
100  }
101  } else {
102  cmsSherpaRng->setRandomEngine(v);
103  }
104 }
105 
107  : BaseHadronizer(params),
108  SherpaParameterSet(params.getParameter<edm::ParameterSet>("SherpaParameters")),
109  isRNGinitialized(false) {
110  if (!params.exists("SherpaProcess"))
111  SherpaProcess = "";
112  else
113  SherpaProcess = params.getParameter<std::string>("SherpaProcess");
114  if (!params.exists("SherpaPath"))
115  SherpaPath = "";
116  else
117  SherpaPath = params.getParameter<std::string>("SherpaPath");
118  if (!params.exists("SherpaPathPiece"))
119  SherpaPathPiece = "";
120  else
121  SherpaPathPiece = params.getParameter<std::string>("SherpaPathPiece");
122  if (!params.exists("SherpaResultDir"))
123  SherpaResultDir = "Result";
124  else
125  SherpaResultDir = params.getParameter<std::string>("SherpaResultDir");
126  if (!params.exists("SherpaDefaultWeight"))
127  SherpaDefaultWeight = 1.;
128  else
129  SherpaDefaultWeight = params.getParameter<double>("SherpaDefaultWeight");
130  if (!params.exists("maxEventsToPrint"))
131  maxEventsToPrint = 0;
132  else
133  maxEventsToPrint = params.getParameter<int>("maxEventsToPrint");
134  // if hepmcextendedweights is used the event weights have to be reordered ( unordered list can be accessed via event->weights().write() )
135  // two lists have to be provided:
136  // 1) SherpaWeights
137  // - containing nominal event weight, combined matrix element and phase space weight, event normalization, and possibly other sherpa weights
138  // 2) SherpaVariationsWeights
139  // - containing weights from scale and PDF variations ( have to be defined in the runcard )
140  // - in case of unweighted events these weights are also divided by the event normalization (see list 1 )
141  // Sherpa Documentation: http://sherpa.hepforge.org/doc/SHERPA-MC-2.2.0.html#Scale-and-PDF-variations
142  if (!params.exists("SherpaWeightsBlock")) {
143  rearrangeWeights = false;
144  } else {
145  rearrangeWeights = true;
146  edm::ParameterSet WeightsBlock = params.getParameter<edm::ParameterSet>("SherpaWeightsBlock");
147  if (WeightsBlock.exists("SherpaWeights"))
148  weightlist = WeightsBlock.getParameter<std::vector<std::string> >("SherpaWeights");
149  else
150  throw cms::Exception("SherpaInterface") << "SherpaWeights does not exists in SherpaWeightsBlock" << std::endl;
151  if (WeightsBlock.exists("SherpaVariationWeights"))
152  variationweightlist = WeightsBlock.getParameter<std::vector<std::string> >("SherpaVariationWeights");
153  else
154  throw cms::Exception("SherpaInterface")
155  << "SherpaVariationWeights does not exists in SherpaWeightsBlock" << std::endl;
156  edm::LogVerbatim("SherpaHadronizer") << "SherpaHadronizer will try rearrange the event weights according to "
157  "SherpaWeights and SherpaVariationWeights";
158  }
159 
160  spf::SherpackFetcher Fetcher(params);
161  int retval = Fetcher.Fetch();
162  if (retval != 0) {
163  throw cms::Exception("SherpaInterface") << "SherpaHadronizer: Preparation of Sherpack failed ... ";
164  }
165  // The ids (names) of parameter sets to be read (Analysis,Run) to create Analysis.dat, Run.dat
166  //They are given as a vstring.
167  std::vector<std::string> setNames = SherpaParameterSet.getParameter<std::vector<std::string> >("parameterSets");
168  //Loop all set names...
169  for (unsigned i = 0; i < setNames.size(); ++i) {
170  // ...and read the parameters for each set given in vstrings
171  std::vector<std::string> pars = SherpaParameterSet.getParameter<std::vector<std::string> >(setNames[i]);
172  edm::LogVerbatim("SherpaHadronizer") << "Write Sherpa parameter set " << setNames[i] << " to " << setNames[i]
173  << ".dat ";
174  std::string datfile = SherpaPath + "/" + setNames[i] + ".dat";
175  std::ofstream os(datfile.c_str());
176  // Loop over all strings and write the according *.dat
177  for (std::vector<std::string>::const_iterator itPar = pars.begin(); itPar != pars.end(); ++itPar) {
178  os << (*itPar) << std::endl;
179  }
180  }
181 
182  //To be conform to the default Sherpa usage create a command line:
183  //name of executable (only for demonstration, could also be empty)
184  std::string shRun = "./Sherpa";
185  //Path where the Sherpa libraries are stored
186  std::string shPath = "PATH=" + SherpaPath;
187  // new for Sherpa 1.3.0, suggested by authors
188  std::string shPathPiece = "PATH_PIECE=" + SherpaPathPiece;
189  //Path where results are stored
190  std::string shRes = "RESULT_DIRECTORY=" + SherpaResultDir; // from Sherpa 1.2.0 on
191  //Name of the external random number class
192  std::string shRng = "EXTERNAL_RNG=CMS_SHERPA_RNG";
193 
194  //create the command line
195  arguments.push_back(shRun);
196  arguments.push_back(shPath);
197  arguments.push_back(shPathPiece);
198  arguments.push_back(shRes);
199  arguments.push_back(shRng);
200  isInitialized = false;
201  //initialization of Sherpa moved to initializeForInternalPartons
202 }
203 
205  Generator->~Sherpa();
206 #ifdef USING__MPI
207  MPI::Finalize();
208 #endif
209 }
210 
212  //initialize Sherpa but only once
213  if (!isInitialized) {
214  int argc = arguments.size();
215  char *argv[argc];
216  for (int l = 0; l < argc; l++)
217  argv[l] = (char *)arguments[l].c_str();
218 #ifdef USING__MPI
219  MPI::Init();
220 #endif
221  Generator->InitializeTheRun(argc, argv);
222  Generator->InitializeTheEventHandler();
223  isInitialized = true;
224  }
225  return true;
226 }
227 
228 bool SherpaHadronizer::declareStableParticles(const std::vector<int> &pdgIds) { return false; }
229 
231  //calculate statistics
232  Generator->SummarizeRun();
233 
234  //get the xsec & err
235  double xsec_val = Generator->TotalXS();
236  double xsec_err = Generator->TotalErr();
237 
238  //set the internal cross section in pb in GenRunInfoProduct
239  runInfo().setInternalXSec(GenRunInfoProduct::XSec(xsec_val, xsec_err));
240 }
241 
243  //get the next event and check if it produced
244  bool rc = false;
245  int itry = 0;
246  bool gen_event = true;
247  while ((itry < 3) && gen_event) {
248  try {
249  rc = Generator->GenerateOneEvent();
250  gen_event = false;
251  } catch (...) {
252  ++itry;
253  std::cerr << "Exception from Generator->GenerateOneEvent() catch. Call # " << itry << " for this event\n";
254  }
255  }
256  if (rc) {
257  //convert it to HepMC2
258  auto evt = std::make_unique<HepMC::GenEvent>();
259  Generator->FillHepMCEvent(*evt);
260 
261  // in case of unweighted events sherpa puts the max weight as event weight.
262  // this is not optimal, we want 1 for unweighted events, so we check
263  // whether we are producing unweighted events ("EVENT_GENERATION_MODE" == "1")
264  // the information about the weights to the HepMC weight vector:
265  // [0] event weight
266  // [1] combined matrix element and phase space weight (missing only PDF information, thus directly suitable for PDF reweighting)
267  // [2] event weight normalisation (in case of unweighted events event weights of ~ +/-1 can be obtained by (event weight)/(event weight normalisation))
268  // [3] number of trials.
269  // see also: https://sherpa.hepforge.org/doc/SHERPA-MC-2.1.0.html#Event-output-formats
270  bool unweighted = false;
271  double weight_normalization = -1;
272  if (ATOOLS::ToType<int>(ATOOLS::rpa->gen.Variable("EVENT_GENERATION_MODE")) == 1) {
273  if (evt->weights().size() > 2) {
274  unweighted = true;
275  weight_normalization = evt->weights()[2];
276  } else {
277  throw cms::Exception("SherpaInterface")
278  << "Requested unweighted production. Missing normalization weight." << std::endl;
279  }
280  }
281 
282  // vector to fill new weights in correct order
283  std::vector<double> newWeights;
284  if (rearrangeWeights) {
285  for (auto &i : weightlist) {
286  if (evt->weights().has_key(i)) {
287  newWeights.push_back(evt->weights()[i]);
288  } else {
289  throw cms::Exception("SherpaInterface")
290  << "Missing weights! Key " << i << " not found, please check the weight definition!" << std::endl;
291  }
292  }
293  for (auto &i : variationweightlist) {
294  if (evt->weights().has_key(i)) {
295  if (unweighted) {
296  newWeights.push_back(evt->weights()[i] / weight_normalization);
297  } else {
298  newWeights.push_back(evt->weights()[i]);
299  }
300  } else {
301  throw cms::Exception("SherpaInterface")
302  << "Missing weights! Key " << i << " not found, please check the weight definition!" << std::endl;
303  }
304  }
305 
306  //Change original weights for reordered ones
307  evt->weights().clear();
308  for (auto &elem : newWeights) {
309  evt->weights().push_back(elem);
310  }
311  }
312 
313  if (unweighted) {
314  evt->weights()[0] /= weight_normalization;
315  }
316  resetEvent(std::move(evt));
317  return true;
318  } else {
319  return false;
320  }
321 }
322 
323 bool SherpaHadronizer::decay() { return true; }
324 
325 bool SherpaHadronizer::residualDecay() { return true; }
326 
328  //******** Verbosity *******
329  if (maxEventsToPrint > 0) {
331  event()->print();
332  }
333 }
334 
335 //GETTER for the external random numbers
336 DECLARE_GETTER(CMS_SHERPA_RNG, "CMS_SHERPA_RNG", ATOOLS::External_RNG, ATOOLS::RNG_Key);
337 
338 ATOOLS::External_RNG *ATOOLS::Getter<ATOOLS::External_RNG, ATOOLS::RNG_Key, CMS_SHERPA_RNG>::operator()(
339  const ATOOLS::RNG_Key &) const {
340  return new CMS_SHERPA_RNG();
341 }
342 
343 void ATOOLS::Getter<ATOOLS::External_RNG, ATOOLS::RNG_Key, CMS_SHERPA_RNG>::PrintInfo(std::ostream &str,
344  const size_t) const {
345  str << "CMS_SHERPA_RNG interface";
346 }
347 
349  if (randomEngine == nullptr) {
350  throw edm::Exception(edm::errors::LogicError) << "The Sherpa code attempted to a generate random number while\n"
351  << "the engine pointer was null. This might mean that the code\n"
352  << "was modified to generate a random number outside the event and\n"
353  << "beginLuminosityBlock methods, which is not allowed.\n";
354  }
355  return randomEngine->flat();
356 }
357 std::unique_ptr<GenLumiInfoHeader> SherpaHadronizer::getGenLumiInfoHeader() const {
358  auto genLumiInfoHeader = BaseHadronizer::getGenLumiInfoHeader();
359 
360  if (rearrangeWeights) {
361  edm::LogPrint("SherpaHadronizer") << "The order of event weights was changed!";
362  for (auto &i : weightlist) {
363  genLumiInfoHeader->weightNames().push_back(i);
364  edm::LogVerbatim("SherpaHadronizer") << i;
365  }
366  for (auto &i : variationweightlist) {
367  genLumiInfoHeader->weightNames().push_back(i);
368  edm::LogVerbatim("SherpaHadronizer") << i;
369  }
370  }
371  return genLumiInfoHeader;
372 }
374 
spf::SherpackFetcher::Fetch
int Fetch()
Definition: SherpackFetcher.cc:28
genWeightsTable_cfi.genLumiInfoHeader
genLumiInfoHeader
Definition: genWeightsTable_cfi.py:5
cmsBatch.argv
argv
Definition: cmsBatch.py:279
SherpaHadronizer
Definition: SherpaHadronizer.cc:38
mps_fire.i
i
Definition: mps_fire.py:428
funct::false
false
Definition: Factorize.h:29
SherpaHadronizer::SherpaProcess
std::string SherpaProcess
Definition: SherpaHadronizer.cc:59
SherpaHadronizer::SherpaResultDir
std::string SherpaResultDir
Definition: SherpaHadronizer.cc:63
dir2webdir.argc
argc
Definition: dir2webdir.py:39
edm::errors::LogicError
Definition: EDMException.h:37
summarizeEdmComparisonLogfiles.ran
ran
Definition: summarizeEdmComparisonLogfiles.py:113
CalibrationSummaryClient_cfi.params
params
Definition: CalibrationSummaryClient_cfi.py:14
edm
HLT enums.
Definition: AlignableModifier.h:19
BaseHadronizer.h
ExternalDecayDriver.h
edm::LogPrint
Log< level::Warning, true > LogPrint
Definition: MessageLogger.h:130
GenRunInfoProduct::setInternalXSec
void setInternalXSec(const XSec &xsec)
Definition: GenRunInfoProduct.h:26
SherpaHadronizer::isRNGinitialized
bool isRNGinitialized
Definition: SherpaHadronizer.cc:70
findQualityFiles.v
v
Definition: findQualityFiles.py:179
SherpaHadronizer::readSettings
bool readSettings(int)
Definition: SherpaHadronizer.cc:43
gen::BaseHadronizer
Definition: BaseHadronizer.h:46
CMS_SHERPA_RNG::CMS_SHERPA_RNG
CMS_SHERPA_RNG()
Definition: SherpaHadronizer.cc:77
SherpaHadronizer::doSetRandomEngine
void doSetRandomEngine(CLHEP::HepRandomEngine *v) override
Definition: SherpaHadronizer.cc:88
DEFINE_FWK_MODULE
#define DEFINE_FWK_MODULE(type)
Definition: MakerMacros.h:16
edm::GeneratorFilter
Definition: GeneratorFilter.h:40
str
#define str(s)
Definition: TestProcessor.cc:53
ParameterCollector.h
gen
Definition: PythiaDecays.h:13
gen::BaseHadronizer::resetEvent
void resetEvent(std::unique_ptr< HepMC::GenEvent > event)
Definition: BaseHadronizer.h:58
SherpaHadronizer::SherpaHadronizer
SherpaHadronizer(const edm::ParameterSet &params)
Definition: SherpaHadronizer.cc:106
edm::ParameterSet::exists
bool exists(std::string const &parameterName) const
checks if a parameter exists
Definition: ParameterSet.cc:681
CMS_SHERPA_RNG::randomEngine
CLHEP::HepRandomEngine * randomEngine
Definition: SherpaHadronizer.cc:85
MuScleFit_cfi.Sherpa
Sherpa
Definition: MuScleFit_cfi.py:8
edm::ParameterSet
Definition: ParameterSet.h:47
GenRunInfoProduct::XSec
Definition: GenRunInfoProduct.h:32
SherpaHadronizer::isInitialized
bool isInitialized
Definition: SherpaHadronizer.cc:69
ParameterSet
Definition: Functions.h:16
SherpaHadronizer::SherpaPathPiece
std::string SherpaPathPiece
Definition: SherpaHadronizer.cc:62
GeneratorFilter.h
SherpaHadronizer::arguments
std::vector< std::string > arguments
Definition: SherpaHadronizer.cc:67
CosmicGenFilterHelix_cfi.pdgIds
pdgIds
Definition: CosmicGenFilterHelix_cfi.py:5
SherpaHadronizer::SherpaChecksum
std::string SherpaChecksum
Definition: SherpaHadronizer.cc:60
SherpaHadronizer::maxEventsToPrint
unsigned int maxEventsToPrint
Definition: SherpaHadronizer.cc:66
SherpaHadronizer::declareStableParticles
bool declareStableParticles(const std::vector< int > &pdgIds)
Definition: SherpaHadronizer.cc:228
spf::SherpackFetcher
Definition: SherpackFetcher.h:20
AlCaHLTBitMon_QueryRunRegistry.string
string string
Definition: AlCaHLTBitMon_QueryRunRegistry.py:256
SherpaHadronizer::finalizeEvent
void finalizeEvent()
Definition: SherpaHadronizer.cc:327
DECLARE_GETTER
DECLARE_GETTER(CMS_SHERPA_RNG, "CMS_SHERPA_RNG", ATOOLS::External_RNG, ATOOLS::RNG_Key)
cmsLHEtoEOSManager.l
l
Definition: cmsLHEtoEOSManager.py:204
HadronizerFilter.h
SherpaHadronizer::SherpaParameterSet
edm::ParameterSet SherpaParameterSet
Definition: SherpaHadronizer.cc:65
CMS_SHERPA_RNG::Get
double Get() override
Definition: SherpaHadronizer.cc:348
Generator
Definition: Generator.h:19
SherpaHadronizer::initializeForInternalPartons
bool initializeForInternalPartons()
Definition: SherpaHadronizer.cc:211
eostools.move
def move(src, dest)
Definition: eostools.py:511
gen::BaseHadronizer::event
std::unique_ptr< HepMC::GenEvent > & event()
Definition: BaseHadronizer.h:86
SherpaHadronizer::statistics
void statistics()
Definition: SherpaHadronizer.cc:230
edm::LogVerbatim
Log< level::Info, true > LogVerbatim
Definition: MessageLogger.h:128
Exception
Definition: hltDiff.cc:245
SherpaHadronizer::decay
bool decay()
Definition: SherpaHadronizer.cc:323
SherpaHadronizer::SherpaPath
std::string SherpaPath
Definition: SherpaHadronizer.cc:61
SherpaHadronizer::variationweightlist
std::vector< std::string > variationweightlist
Definition: SherpaHadronizer.cc:72
edm::ParameterSet::getParameter
T getParameter(std::string const &) const
Definition: ParameterSet.h:303
SherpaHadronizer::getGenLumiInfoHeader
std::unique_ptr< GenLumiInfoHeader > getGenLumiInfoHeader() const override
Definition: SherpaHadronizer.cc:357
SherpackFetcher.h
SherpaHadronizer::classname
const char * classname() const
Definition: SherpaHadronizer.cc:54
SherpaHadronizer::declareSpecialSettings
bool declareSpecialSettings(const std::vector< std::string > &)
Definition: SherpaHadronizer.cc:46
SherpaHadronizer::weightlist
std::vector< std::string > weightlist
Definition: SherpaHadronizer.cc:71
SherpaHadronizer::~SherpaHadronizer
~SherpaHadronizer() override
Definition: SherpaHadronizer.cc:204
EcnaPython_AdcPeg12_S1_10_R170298_1_0_150_Dee0.cerr
cerr
Definition: EcnaPython_AdcPeg12_S1_10_R170298_1_0_150_Dee0.py:8
gen::BaseHadronizer::runInfo
GenRunInfoProduct & runInfo()
Definition: BaseHadronizer.h:85
SherpaHadronizer::SherpaDefaultWeight
double SherpaDefaultWeight
Definition: SherpaHadronizer.cc:64
SherpaHadronizer::generatePartonsAndHadronize
bool generatePartonsAndHadronize()
Definition: SherpaHadronizer.cc:242
SherpaHadronizer::rearrangeWeights
bool rearrangeWeights
Definition: SherpaHadronizer.cc:50
SherpaGeneratorFilter
edm::GeneratorFilter< SherpaHadronizer, gen::ExternalDecayDriver > SherpaGeneratorFilter
Definition: SherpaHadronizer.cc:375
CMS_SHERPA_RNG::setRandomEngine
void setRandomEngine(CLHEP::HepRandomEngine *v)
Definition: SherpaHadronizer.cc:81
CMS_SHERPA_RNG
Definition: SherpaHadronizer.cc:75
SherpaHadronizer::residualDecay
bool residualDecay()
Definition: SherpaHadronizer.cc:325