CMS 3D CMS Logo

RivetAnalyzer.cc
Go to the documentation of this file.
2 
6 
9 
10 #include "Rivet/Run.hh"
11 #include "Rivet/AnalysisHandler.hh"
12 #include "Rivet/Analysis.hh"
13 
14 #include <regex>
15 
16 using namespace Rivet;
17 using namespace edm;
18 
20  : _isFirstEvent(true),
21  _outFileName(pset.getParameter<std::string>("OutputFile")),
22  _analysisNames(pset.getParameter<std::vector<std::string> >("AnalysisNames")),
23  //decide whether to finalize the plots or not.
24  //deciding not to finalize them can be useful for further harvesting of many jobs
25  _doFinalize(pset.getParameter<bool>("DoFinalize")),
26  _produceDQM(pset.getParameter<bool>("ProduceDQMOutput")),
27  _lheLabel(pset.getParameter<edm::InputTag>("LHECollection")),
28  _xsection(-1.) {
29  usesResource("Rivet");
30 
31  _hepmcCollection = consumes<HepMCProduct>(pset.getParameter<edm::InputTag>("HepMCCollection"));
32  _genLumiInfoToken = consumes<GenLumiInfoHeader, edm::InLumi>(pset.getParameter<edm::InputTag>("genLumiInfo"));
33 
34  _useLHEweights = pset.getParameter<bool>("useLHEweights");
35  if (_useLHEweights) {
36  _lheRunInfoToken = consumes<LHERunInfoProduct, edm::InRun>(_lheLabel);
37  _LHECollection = consumes<LHEEventProduct>(_lheLabel);
38  }
39 
40  _weightCap = pset.getParameter<double>("weightCap");
41  _NLOSmearing = pset.getParameter<double>("NLOSmearing");
42  _skipMultiWeights = pset.getParameter<bool>("skipMultiWeights");
43  _selectMultiWeights = pset.getParameter<std::string>("selectMultiWeights");
44  _deselectMultiWeights = pset.getParameter<std::string>("deselectMultiWeights");
45  _setNominalWeightName = pset.getParameter<std::string>("setNominalWeightName");
46 
47  //set user cross section if needed
48  _xsection = pset.getParameter<double>("CrossSection");
49 
50  if (_produceDQM) {
51  // book stuff needed for DQM
52  dbe = nullptr;
54  }
55 }
56 
58 
60  //set the environment, very ugly but rivet is monolithic when it comes to paths
61  char* cmsswbase = std::getenv("CMSSW_BASE");
62  char* cmsswrelease = std::getenv("CMSSW_RELEASE_BASE");
63  if (!std::getenv("RIVET_REF_PATH")) {
64  const std::string rivetref = string(cmsswbase) +
65  "/src/GeneratorInterface/RivetInterface/data:" + string(cmsswrelease) +
66  "/src/GeneratorInterface/RivetInterface/data:.";
67  char* rivetrefCstr = strdup(rivetref.c_str());
68  setenv("RIVET_REF_PATH", rivetrefCstr, 1);
69  free(rivetrefCstr);
70  }
71  if (!std::getenv("RIVET_INFO_PATH")) {
72  const std::string rivetinfo = string(cmsswbase) +
73  "/src/GeneratorInterface/RivetInterface/data:" + string(cmsswrelease) +
74  "/src/GeneratorInterface/RivetInterface/data:.";
75  char* rivetinfoCstr = strdup(rivetinfo.c_str());
76  setenv("RIVET_INFO_PATH", rivetinfoCstr, 1);
77  free(rivetinfoCstr);
78  }
79 }
80 
81 void RivetAnalyzer::beginRun(const edm::Run& iRun, const edm::EventSetup& iSetup) {
82  if (_useLHEweights) {
83  edm::Handle<LHERunInfoProduct> lheRunInfoHandle;
84  iRun.getByLabel(_lheLabel, lheRunInfoHandle);
85  typedef std::vector<LHERunInfoProduct::Header>::const_iterator headers_const_iterator;
86 
87  std::regex reg("<weight.*> ?(.*?) ?<\\/weight>");
88  for (headers_const_iterator iter = lheRunInfoHandle->headers_begin(); iter != lheRunInfoHandle->headers_end();
89  iter++) {
90  std::vector<std::string> lines = iter->lines();
91  for (unsigned int iLine = 0; iLine < lines.size(); iLine++) {
92  std::smatch match;
93  std::regex_search(lines.at(iLine), match, reg);
94  if (!match.empty()) {
95  _lheWeightNames.push_back(match[1]);
96  }
97  }
98  }
99  }
100 }
101 
103  edm::Handle<GenLumiInfoHeader> genLumiInfoHandle;
104  if (iLumi.getByToken(_genLumiInfoToken, genLumiInfoHandle)) {
105  _weightNames = genLumiInfoHandle->weightNames();
106  }
107 
108  // need to reset the default weight name (or plotting will fail)
109  if (!_weightNames.empty()) {
110  _weightNames[0] = "";
111  } else { // Summer16 samples have 1 weight stored in HepMC but no weightNames
112  _weightNames.push_back("");
113  }
114 }
115 
116 void RivetAnalyzer::endLuminosityBlock(const edm::LuminosityBlock& iLumi, const edm::EventSetup& iSetup) { return; }
117 
119  //finalize weight names on the first event
120  if (_isFirstEvent) {
121  if (_useLHEweights) {
122  _weightNames.insert(_weightNames.end(), _lheWeightNames.begin(), _lheWeightNames.end());
123  }
124  // clean weight names to be accepted by Rivet plotting
125  for (const std::string& wn : _weightNames) {
126  _cleanedWeightNames.push_back(std::regex_replace(wn, std::regex("[^A-Za-z\\d\\._=]"), "_"));
127  }
128  }
129 
130  //get the hepmc product from the event
132  iEvent.getByToken(_hepmcCollection, evt);
133 
134  // get HepMC GenEvent
135  const HepMC::GenEvent* myGenEvent = evt->GetEvent();
136  std::unique_ptr<HepMC::GenEvent> tmpGenEvtPtr;
137  //if you want to use an external weight or set the cross section we have to clone the GenEvent and change the weight
138  tmpGenEvtPtr = std::make_unique<HepMC::GenEvent>(*(evt->GetEvent()));
139 
140  if (_xsection > 0) {
141  HepMC::GenCrossSection xsec;
142  xsec.set_cross_section(_xsection);
143  tmpGenEvtPtr->set_cross_section(xsec);
144  }
145 
146  std::vector<double> mergedWeights;
147  for (unsigned int i = 0; i < tmpGenEvtPtr->weights().size(); i++) {
148  mergedWeights.push_back(tmpGenEvtPtr->weights()[i]);
149  }
150 
151  if (_useLHEweights) {
152  edm::Handle<LHEEventProduct> lheEventHandle;
153  iEvent.getByToken(_LHECollection, lheEventHandle);
154  for (unsigned int i = 0; i < _lheWeightNames.size(); i++) {
155  mergedWeights.push_back(tmpGenEvtPtr->weights()[0] * lheEventHandle->weights().at(i).wgt /
156  lheEventHandle->originalXWGTUP());
157  }
158  }
159 
160  tmpGenEvtPtr->weights().clear();
161  for (unsigned int i = 0; i < _cleanedWeightNames.size(); i++) {
162  tmpGenEvtPtr->weights()[_cleanedWeightNames[i]] = mergedWeights[i];
163  }
164  myGenEvent = tmpGenEvtPtr.get();
165 
166  //apply the beams initialization on the first event
167  if (_isFirstEvent) {
168  _analysisHandler = std::make_unique<Rivet::AnalysisHandler>();
169  _analysisHandler->addAnalyses(_analysisNames);
170 
172  _analysisHandler->skipMultiWeights(_skipMultiWeights);
173  _analysisHandler->selectMultiWeights(_selectMultiWeights);
174  _analysisHandler->deselectMultiWeights(_deselectMultiWeights);
175  _analysisHandler->setNominalWeightName(_setNominalWeightName);
176  _analysisHandler->setWeightCap(_weightCap);
177  _analysisHandler->setNLOSmearing(_NLOSmearing);
178 
179  _analysisHandler->init(*myGenEvent);
180 
181  _isFirstEvent = false;
182  }
183 
184  //run the analysis
185  _analysisHandler->analyze(*myGenEvent);
186 }
187 
188 void RivetAnalyzer::endRun(const edm::Run& iRun, const edm::EventSetup& iSetup) {
189  if (_doFinalize)
190  _analysisHandler->finalize();
191  else {
192  //if we don't finalize we just want to do the transformation from histograms to DPS
194  //normalizeTree();
195  }
196  _analysisHandler->writeData(_outFileName);
197 
198  return;
199 }
200 
201 //from Rivet 2.X: Analysis.hh (cls 18Feb2014)
203 //const vector<AnalysisObjectPtr>& analysisObjects() const {
204 //return _analysisobjects;
205 //}
206 
208 
210  using namespace YODA;
211  std::vector<string> analyses = _analysisHandler->analysisNames();
212 
213  //tree.ls(".", true);
214  const string tmpdir = "/RivetNormalizeTmp";
215  //tree.mkdir(tmpdir);
216  for (const string& analysis : analyses) {
217  if (_produceDQM) {
218  dbe->setCurrentFolder("Rivet/" + analysis);
219  //global variables that are always present
220  //sumOfWeights
221  TH1F nevent("nEvt", "n analyzed Events", 1, 0., 1.);
222  nevent.SetBinContent(1, _analysisHandler->sumW());
223  _mes.push_back(dbe->book1D("nEvt", &nevent));
224  }
225  //cross section
226  //TH1F xsection("xSection", "Cross Section", 1, 0., 1.);
227  //xsection.SetBinContent(1,_analysisHandler->crossSection());
228  //_mes.push_back(dbe->book1D("xSection",&xsection));
229  //now loop over the histograms
230 
231  /*
232  const vector<string> paths = tree.listObjectNames("/"+analysis, true); // args set recursive listing
233  std::cout << "Number of objects in YODA tree for analysis " << analysis << " = " << paths.size() << std::endl;
234  foreach (const string& path, paths) {
235  IManagedObject* hobj = tree.find(path);
236  if (hobj) {
237  // Weird seg fault on SLC4 when trying to dyn cast an IProfile ptr to a IHistogram
238  // Fix by attempting to cast to IProfile first, only try IHistogram if it fails.
239  IHistogram1D* histo = 0;
240  IProfile1D* prof = dynamic_cast<IProfile1D*>(hobj);
241  if (!prof) histo = dynamic_cast<IHistogram1D*>(hobj);
242 
243  std::cout << "Converting histo " << path << " to DPS" << std::endl;
244  tree.mv(path, tmpdir);
245  const size_t lastslash = path.find_last_of("/");
246  const string basename = path.substr(lastslash+1, path.length() - (lastslash+1));
247  const string tmppath = tmpdir + "/" + basename;
248 
249  // If it's a normal histo:
250  if (histo) {
251  IHistogram1D* tmphisto = dynamic_cast<IHistogram1D*>(tree.find(tmppath));
252  if (tmphisto) {
253  _analysisHandler->datapointsetFactory().create(path, *tmphisto);
254  }
255  //now convert to root and then ME
256  //need aida2flat (from Rivet 1.X) & flat2root here
257  TH1F* h = aida2root<IHistogram1D, TH1F>(histo, basename);
258  if (_produceDQM)
259  _mes.push_back(dbe->book1D(h->GetName(), h));
260  delete h;
261  tree.rm(tmppath);
262  }
263  // If it's a profile histo:
264  else if (prof) {
265  IProfile1D* tmpprof = dynamic_cast<IProfile1D*>(tree.find(tmppath));
266  if (tmpprof) {
267  _analysisHandler->datapointsetFactory().create(path, *tmpprof);
268  }
269  //now convert to root and then ME
270  //need aida2flat (from Rivet 1.X) & flat2root here
271  TProfile* p = aida2root<IProfile1D, TProfile>(prof, basename);
272  if (_produceDQM)
273  _mes.push_back(dbe->bookProfile(p->GetName(), p));
274  delete p;
275  tree.rm(tmppath);
276  }
277  }
278  }
279  */
280  }
281  //tree.rmdir(tmpdir);
282 }
283 
void analyze(const edm::Event &, const edm::EventSetup &) override
void endRun(const edm::Run &, const edm::EventSetup &) override
std::string _deselectMultiWeights
Definition: RivetAnalyzer.h:55
std::unique_ptr< Rivet::AnalysisHandler > _analysisHandler
Definition: RivetAnalyzer.h:61
double originalXWGTUP() const
headers_const_iterator headers_begin() const
void setCurrentFolder(std::string const &fullpath) override
Definition: DQMStore.h:646
std::vector< std::string > _cleanedWeightNames
Definition: RivetAnalyzer.h:71
std::string _setNominalWeightName
Definition: RivetAnalyzer.h:56
std::vector< std::string > _analysisNames
Definition: RivetAnalyzer.h:64
const std::vector< std::string > & weightNames() const
int nevent
Definition: AMPTWrapper.h:84
const edm::InputTag _lheLabel
Definition: RivetAnalyzer.h:67
headers_const_iterator headers_end() const
int iEvent
Definition: GenABIO.cc:224
void beginLuminosityBlock(const edm::LuminosityBlock &, const edm::EventSetup &) override
std::string _selectMultiWeights
Definition: RivetAnalyzer.h:54
void beginJob() override
bool getByLabel(std::string const &label, Handle< PROD > &result) const
Definition: Run.h:283
bool _skipMultiWeights
Definition: RivetAnalyzer.h:53
#define DEFINE_FWK_MODULE(type)
Definition: MakerMacros.h:16
void endLuminosityBlock(const edm::LuminosityBlock &, const edm::EventSetup &) override
void beginRun(const edm::Run &, const edm::EventSetup &) override
RivetAnalyzer(const edm::ParameterSet &)
edm::EDGetTokenT< GenLumiInfoHeader > _genLumiInfoToken
Definition: RivetAnalyzer.h:59
const HepMC::GenEvent * GetEvent() const
Definition: HepMCProduct.h:37
edm::EDGetTokenT< edm::HepMCProduct > _hepmcCollection
Definition: RivetAnalyzer.h:49
edm::EDGetTokenT< LHERunInfoProduct > _lheRunInfoToken
Definition: RivetAnalyzer.h:60
bool getByToken(EDGetToken token, Handle< PROD > &result) const
double _xsection
Definition: RivetAnalyzer.h:68
DQMStore * dbe
Definition: RivetAnalyzer.h:73
std::vector< std::string > _lheWeightNames
Definition: RivetAnalyzer.h:70
std::string _outFileName
Definition: RivetAnalyzer.h:63
HLT enums.
void endJob() override
List of registered analysis data objects.
edm::EDGetTokenT< LHEEventProduct > _LHECollection
Definition: RivetAnalyzer.h:57
std::pair< typename Association::data_type::first_type, double > match(Reference key, Association association, bool bestMatchByMaxValue)
Generic matching function.
Definition: Utils.h:10
std::vector< std::string > _weightNames
Definition: RivetAnalyzer.h:69
MonitorElement * book1D(TString const &name, TString const &title, int const nchX, double const lowX, double const highX, FUNC onbooking=NOOP())
Definition: DQMStore.h:98
const std::vector< WGT > & weights() const
void normalizeTree()
Definition: Run.h:45
double _NLOSmearing
Definition: RivetAnalyzer.h:52
std::vector< MonitorElement * > _mes
Definition: RivetAnalyzer.h:74
double _weightCap
Definition: RivetAnalyzer.h:51
~RivetAnalyzer() override