CMS 3D CMS Logo

 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Pages
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 <stdint.h>
7 #include <vector>
8 
9 
10 #include "SHERPA/Main/Sherpa.H"
11 #include "ATOOLS/Math/Random.H"
12 
13 #include "ATOOLS/Org/Run_Parameter.H"
14 #include "ATOOLS/Org/MyStrStream.H"
15 
21 
22 #include "CLHEP/Random/RandomEngine.h"
23 
24 
25 //This unnamed namespace is used (instead of static variables) to pass the
26 //randomEngine passed to doSetRandomEngine to the External Random
27 //Number Generator CMS_SHERPA_RNG of sherpa
28 //The advantage of the unnamed namespace over static variables is
29 //that it is only accessible in this file
30 
31 namespace {
32  CLHEP::HepRandomEngine* ExternalEngine=nullptr;
33  CLHEP::HepRandomEngine* GetExternalEngine() { return ExternalEngine; }
34  void SetExternalEngine(CLHEP::HepRandomEngine* v) { ExternalEngine=v; }
35 }
36 
38 public:
39  SherpaHadronizer(const edm::ParameterSet &params);
41 
42  bool readSettings( int ) { return true; }
44  bool declareStableParticles(const std::vector<int> &pdgIds);
45  bool declareSpecialSettings( const std::vector<std::string>& ) { return true; }
46  void statistics();
48  bool decay();
49  bool residualDecay();
50  void finalizeEvent();
51  const char *classname() const { return "SherpaHadronizer"; }
52 
53 
54 private:
55 
56  virtual void doSetRandomEngine(CLHEP::HepRandomEngine* v) override;
57 
65  unsigned int maxEventsToPrint;
66  std::vector<std::string> arguments;
69 };
70 
71 
72 
73 
74 class CMS_SHERPA_RNG: public ATOOLS::External_RNG {
75 public:
76 
78  std::cout << "Use stored reference for the external RNG" << std::endl;
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 
89 void SherpaHadronizer::doSetRandomEngine(CLHEP::HepRandomEngine* v) {
90  CMS_SHERPA_RNG* cmsSherpaRng = dynamic_cast<CMS_SHERPA_RNG*>(ATOOLS::ran->GetExternalRng());
91  //~ assert(cmsSherpaRng != nullptr);
92  if (cmsSherpaRng ==nullptr) {
93  //First time call to this function makes the interface store the reference in the unnamed namespace
94  if (!isRNGinitialized){
95  isRNGinitialized=true;
96  std::cout << "Store assigned reference of the randomEngine" << std::endl;
97  SetExternalEngine(v);
98  // Throw exception if there is no reference to an external RNG and it is not the first call!
99  } else {
101  << "The Sherpa interface got a randomEngine reference but there is no reference to the external RNG to hand it over to\n";
102  }
103  } else {
104  cmsSherpaRng->setRandomEngine(v);
105  }
106 }
107 
109  BaseHadronizer(params),
110  SherpaParameterSet(params.getParameter<edm::ParameterSet>("SherpaParameters")),
111  isRNGinitialized(false)
112 {
113  if (!params.exists("SherpaProcess")) SherpaProcess="";
114  else SherpaProcess=params.getParameter<std::string>("SherpaProcess");
115  if (!params.exists("SherpaPath")) SherpaPath="";
116  else SherpaPath=params.getParameter<std::string>("SherpaPath");
117  if (!params.exists("SherpaPathPiece")) SherpaPathPiece="";
118  else SherpaPathPiece=params.getParameter<std::string>("SherpaPathPiece");
119  if (!params.exists("SherpaResultDir")) SherpaResultDir="Result";
120  else SherpaResultDir=params.getParameter<std::string>("SherpaResultDir");
121  if (!params.exists("SherpaDefaultWeight")) SherpaDefaultWeight=1.;
122  else SherpaDefaultWeight=params.getParameter<double>("SherpaDefaultWeight");
123  if (!params.exists("maxEventsToPrint")) maxEventsToPrint=0;
124  else maxEventsToPrint=params.getParameter<int>("maxEventsToPrint");
125 
126 
127  spf::SherpackFetcher Fetcher(params);
128  int retval=Fetcher.Fetch();
129  if (retval != 0) {
130  std::cout << "SherpaHadronizer: Preparation of Sherpack failed ... " << std::endl;
131  std::cout << "SherpaHadronizer: Error code: " << retval << std::endl;
132  std::terminate();
133 
134  }
135  // The ids (names) of parameter sets to be read (Analysis,Run) to create Analysis.dat, Run.dat
136  //They are given as a vstring.
137  std::vector<std::string> setNames = SherpaParameterSet.getParameter<std::vector<std::string> >("parameterSets");
138  //Loop all set names...
139  for ( unsigned i=0; i<setNames.size(); ++i ) {
140  // ...and read the parameters for each set given in vstrings
141  std::vector<std::string> pars = SherpaParameterSet.getParameter<std::vector<std::string> >(setNames[i]);
142  std::cout << "Write Sherpa parameter set " << setNames[i] <<" to "<<setNames[i]<<".dat "<<std::endl;
143  std::string datfile = SherpaPath + "/" + setNames[i] +".dat";
144  std::ofstream os(datfile.c_str());
145  // Loop over all strings and write the according *.dat
146  for(std::vector<std::string>::const_iterator itPar = pars.begin(); itPar != pars.end(); ++itPar ) {
147  os<<(*itPar)<<std::endl;
148  }
149  }
150 
151  //To be conform to the default Sherpa usage create a command line:
152  //name of executable (only for demonstration, could also be empty)
153  std::string shRun = "./Sherpa";
154  //Path where the Sherpa libraries are stored
155  std::string shPath = "PATH=" + SherpaPath;
156  // new for Sherpa 1.3.0, suggested by authors
157  std::string shPathPiece = "PATH_PIECE=" + SherpaPathPiece;
158  //Path where results are stored
159  std::string shRes = "RESULT_DIRECTORY=" + SherpaResultDir; // from Sherpa 1.2.0 on
160  //Name of the external random number class
161  std::string shRng = "EXTERNAL_RNG=CMS_SHERPA_RNG";
162  //switch off multithreading
163  std::string shNoMT = "-j1";
164 
165  //create the command line
166  arguments.push_back(shRun.c_str());
167  arguments.push_back(shPath.c_str());
168  arguments.push_back(shPathPiece.c_str());
169  arguments.push_back(shRes.c_str());
170  arguments.push_back(shRng.c_str());
171  arguments.push_back(shNoMT.c_str());
172 
173  //initialization of Sherpa moved to initializeForInternalPartons
174 }
175 
177 {
178 }
179 
181 {
182  int argc=arguments.size();
183  char* argv[argc];
184  for (int l=0; l<argc; l++) argv[l]=(char*)arguments[l].c_str();
185 
186  Generator.InitializeTheRun(argc,argv);
187  //initialize Sherpa
188  Generator.InitializeTheEventHandler();
189 
190  return true;
191 }
192 
193 #if 0
194 // naive Sherpa HepMC status fixup //FIXME
195 static int getStatus(const HepMC::GenParticle *p)
196 {
197  return status;
198 }
199 #endif
200 
201 //FIXME
202 bool SherpaHadronizer::declareStableParticles(const std::vector<int> &pdgIds)
203 {
204 #if 0
205  for(std::vector<int>::const_iterator iter = pdgIds.begin();
206  iter != pdgIds.end(); ++iter)
207  if (!markStable(*iter))
208  return false;
209 
210  return true;
211 #else
212  return false;
213 #endif
214 }
215 
216 
218 {
219  //calculate statistics
220  Generator.SummarizeRun();
221 
222  //get the xsec & err
223  double xsec_val = Generator.TotalXS();
224  double xsec_err = Generator.TotalErr();
225 
226  //set the internal cross section in pb in GenRunInfoProduct
227  runInfo().setInternalXSec(GenRunInfoProduct::XSec(xsec_val,xsec_err));
228 
229 }
230 
231 
233 {
234  //get the next event and check if it produced
235  bool rc = false;
236  int itry = 0;
237  bool gen_event = true;
238  while((itry < 3) && gen_event){
239  try{
240  rc = Generator.GenerateOneEvent();
241  gen_event = false;
242  } catch(...){
243  ++itry;
244  std::cerr << "Exception from Generator.GenerateOneEvent() catch. Call # "
245  << itry << " for this event\n";
246  }
247  }
248  if (rc) {
249  //convert it to HepMC2
250  HepMC::GenEvent* evt = new HepMC::GenEvent();
251  Generator.FillHepMCEvent(*evt);
252 
253  // in case of unweighted events sherpa puts the max weight as event weight.
254  // this is not optimal, we want 1 for unweighted events, so we check
255  // whether we are producing unweighted events ("EVENT_GENERATION_MODE" == "1")
256  // the information about the weights to the HepMC weight vector:
257  // [0] event weight
258  // [1] combined matrix element and phase space weight (missing only PDF information, thus directly suitable for PDF reweighting)
259  // [2] event weight normalisation (in case of unweighted events event weights of ~ +/-1 can be obtained by (event weight)/(event weight normalisation))
260  // [3] number of trials.
261  // see also: https://sherpa.hepforge.org/doc/SHERPA-MC-2.1.0.html#Event-output-formats
262  if(ATOOLS::ToType<int>(ATOOLS::rpa->gen.Variable("EVENT_GENERATION_MODE")) == 1){
263  if (evt->weights().size()>2) {
264  evt->weights()[0]/=evt->weights()[2];
265  }
266  }
267  resetEvent(evt);
268  return true;
269  }
270  else {
271  return false;
272  }
273 }
274 
276 {
277  return true;
278 }
279 
281 {
282  return true;
283 }
284 
286 {
287 #if 0
288  for(HepMC::GenEvent::particle_iterator iter = event->particles_begin();
289  iter != event->particles_end(); iter++)
290  (*iter)->set_status(getStatus(*iter));
291 #endif
292  //******** Verbosity *******
293  if (maxEventsToPrint > 0) {
295  event()->print();
296  }
297 }
298 
299 
300 //GETTER for the external random numbers
301 DECLARE_GETTER(CMS_SHERPA_RNG,"CMS_SHERPA_RNG",ATOOLS::External_RNG,ATOOLS::RNG_Key);
302 
303 ATOOLS::External_RNG *ATOOLS::Getter<ATOOLS::External_RNG,ATOOLS::RNG_Key,CMS_SHERPA_RNG>::operator()(const ATOOLS::RNG_Key &) const
304 { return new CMS_SHERPA_RNG(); }
305 
306 void ATOOLS::Getter<ATOOLS::External_RNG,ATOOLS::RNG_Key,CMS_SHERPA_RNG>::PrintInfo(std::ostream &str,const size_t) const
307 { str<<"CMS_SHERPA_RNG interface"; }
308 
310  if(randomEngine == nullptr) {
312  << "The Sherpa code attempted to a generate random number while\n"
313  << "the engine pointer was null. This might mean that the code\n"
314  << "was modified to generate a random number outside the event and\n"
315  << "beginLuminosityBlock methods, which is not allowed.\n";
316  }
317  return randomEngine->flat();
318 
319 }
320 
322 
T getParameter(std::string const &) const
int i
Definition: DBlmapReader.cc:9
#define DEFINE_FWK_MODULE(type)
Definition: MakerMacros.h:17
CLHEP::HepRandomEngine * randomEngine
bool exists(std::string const &parameterName) const
checks if a parameter exists
std::string SherpaPathPiece
unsigned int maxEventsToPrint
edm::GeneratorFilter< SherpaHadronizer, gen::ExternalDecayDriver > SherpaGeneratorFilter
#define nullptr
void setInternalXSec(const XSec &xsec)
bool declareStableParticles(const std::vector< int > &pdgIds)
std::auto_ptr< HepMC::GenEvent > & event()
GenRunInfoProduct & runInfo()
edm::ParameterSet SherpaParameterSet
bool initializeForInternalPartons()
SHERPA::Sherpa Generator
bool generatePartonsAndHadronize()
std::string SherpaPath
bool declareSpecialSettings(const std::vector< std::string > &)
void setRandomEngine(CLHEP::HepRandomEngine *v)
virtual void doSetRandomEngine(CLHEP::HepRandomEngine *v) override
std::string SherpaProcess
tuple argc
Definition: dir2webdir.py:38
std::string SherpaResultDir
std::vector< std::string > arguments
SherpaHadronizer(const edm::ParameterSet &params)
tuple cout
Definition: gather_cfg.py:121
void resetEvent(HepMC::GenEvent *event)
volatile std::atomic< bool > shutdown_flag false
tuple status
Definition: ntuplemaker.py:245
DECLARE_GETTER(CMS_SHERPA_RNG,"CMS_SHERPA_RNG", ATOOLS::External_RNG, ATOOLS::RNG_Key)
const char * classname() const
std::string SherpaChecksum
double Get() override