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  _lheLabel(pset.getParameter<edm::InputTag>("LHECollection")),
27  _xsection(-1.) {
28  usesResource("Rivet");
29 
30  _hepmcCollection = consumes<HepMCProduct>(pset.getParameter<edm::InputTag>("HepMCCollection"));
31  _genLumiInfoToken = consumes<GenLumiInfoHeader, edm::InLumi>(pset.getParameter<edm::InputTag>("genLumiInfo"));
32 
33  _useLHEweights = pset.getParameter<bool>("useLHEweights");
34  if (_useLHEweights) {
35  _lheRunInfoToken = consumes<LHERunInfoProduct, edm::InRun>(_lheLabel);
36  _LHECollection = consumes<LHEEventProduct>(_lheLabel);
37  }
38 
39  _weightCap = pset.getParameter<double>("weightCap");
40  _NLOSmearing = pset.getParameter<double>("NLOSmearing");
41  _setIgnoreBeams = pset.getParameter<bool>("setIgnoreBeams");
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 
52 
54  //set the environment, very ugly but rivet is monolithic when it comes to paths
55  char* cmsswbase = std::getenv("CMSSW_BASE");
56  char* cmsswrelease = std::getenv("CMSSW_RELEASE_BASE");
57  if (!std::getenv("RIVET_REF_PATH")) {
58  const std::string rivetref = string(cmsswbase) +
59  "/src/GeneratorInterface/RivetInterface/data:" + string(cmsswrelease) +
60  "/src/GeneratorInterface/RivetInterface/data:.";
61  char* rivetrefCstr = strdup(rivetref.c_str());
62  setenv("RIVET_REF_PATH", rivetrefCstr, 1);
63  free(rivetrefCstr);
64  }
65  if (!std::getenv("RIVET_INFO_PATH")) {
66  const std::string rivetinfo = string(cmsswbase) +
67  "/src/GeneratorInterface/RivetInterface/data:" + string(cmsswrelease) +
68  "/src/GeneratorInterface/RivetInterface/data:.";
69  char* rivetinfoCstr = strdup(rivetinfo.c_str());
70  setenv("RIVET_INFO_PATH", rivetinfoCstr, 1);
71  free(rivetinfoCstr);
72  }
73 }
74 
75 void RivetAnalyzer::beginRun(const edm::Run& iRun, const edm::EventSetup& iSetup) {
76  if (_useLHEweights) {
77  edm::Handle<LHERunInfoProduct> lheRunInfoHandle;
78  iRun.getByLabel(_lheLabel, lheRunInfoHandle);
79  typedef std::vector<LHERunInfoProduct::Header>::const_iterator headers_const_iterator;
80 
81  std::regex reg("<weight.*> ?(.*?) ?<\\/weight>");
82  for (headers_const_iterator iter = lheRunInfoHandle->headers_begin(); iter != lheRunInfoHandle->headers_end();
83  iter++) {
84  std::vector<std::string> lines = iter->lines();
85  for (unsigned int iLine = 0; iLine < lines.size(); iLine++) {
86  std::smatch match;
87  std::regex_search(lines.at(iLine), match, reg);
88  if (!match.empty()) {
89  _lheWeightNames.push_back(match[1]);
90  }
91  }
92  }
93  }
94 }
95 
97  //finalize weight names on the first event
98  if (_isFirstEvent) {
99  auto genLumiInfoHandle = iEvent.getLuminosityBlock().getHandle(_genLumiInfoToken);
100  if (genLumiInfoHandle.isValid()) {
101  _weightNames = genLumiInfoHandle->weightNames();
102  }
103 
104  // need to reset the default weight name (or plotting will fail)
105  if (!_weightNames.empty()) {
106  _weightNames[0] = "";
107  } else { // Summer16 samples have 1 weight stored in HepMC but no weightNames
108  _weightNames.push_back("");
109  }
110  if (_useLHEweights) {
111  // Some samples have weights but no weight names -> assign generic names lheN
112  if (_lheWeightNames.empty()) {
113  edm::Handle<LHEEventProduct> lheEventHandle;
114  iEvent.getByToken(_LHECollection, lheEventHandle);
115  for (unsigned int i = 0; i < lheEventHandle->weights().size(); i++) {
116  _lheWeightNames.push_back("lhe" + std::to_string(i + 1)); // start with 1 to match LHE weight IDs
117  }
118  }
119  _weightNames.insert(_weightNames.end(), _lheWeightNames.begin(), _lheWeightNames.end());
120  }
121  // clean weight names to be accepted by Rivet plotting
122  for (const std::string& wn : _weightNames) {
123  _cleanedWeightNames.push_back(std::regex_replace(wn, std::regex("[^A-Za-z\\d\\._=]"), "_"));
124  }
125  }
126 
127  //get the hepmc product from the event
129  iEvent.getByToken(_hepmcCollection, evt);
130 
131  // get HepMC GenEvent
132  const HepMC::GenEvent* myGenEvent = evt->GetEvent();
133  std::unique_ptr<HepMC::GenEvent> tmpGenEvtPtr;
134  //if you want to use an external weight or set the cross section we have to clone the GenEvent and change the weight
135  tmpGenEvtPtr = std::make_unique<HepMC::GenEvent>(*(evt->GetEvent()));
136 
137  if (_xsection > 0) {
138  HepMC::GenCrossSection xsec;
139  xsec.set_cross_section(_xsection);
140  tmpGenEvtPtr->set_cross_section(xsec);
141  }
142 
143  std::vector<double> mergedWeights;
144  for (unsigned int i = 0; i < tmpGenEvtPtr->weights().size(); i++) {
145  mergedWeights.push_back(tmpGenEvtPtr->weights()[i]);
146  }
147 
148  if (_useLHEweights) {
149  edm::Handle<LHEEventProduct> lheEventHandle;
150  iEvent.getByToken(_LHECollection, lheEventHandle);
151  for (unsigned int i = 0; i < _lheWeightNames.size(); i++) {
152  mergedWeights.push_back(tmpGenEvtPtr->weights()[0] * lheEventHandle->weights().at(i).wgt /
153  lheEventHandle->originalXWGTUP());
154  }
155  }
156 
157  tmpGenEvtPtr->weights().clear();
158  for (unsigned int i = 0; i < _cleanedWeightNames.size(); i++) {
159  tmpGenEvtPtr->weights()[_cleanedWeightNames[i]] = mergedWeights[i];
160  }
161  myGenEvent = tmpGenEvtPtr.get();
162 
163  //apply the beams initialization on the first event
164  if (_isFirstEvent) {
165  _analysisHandler = std::make_unique<Rivet::AnalysisHandler>();
166  _analysisHandler->addAnalyses(_analysisNames);
167 
169  _analysisHandler->setIgnoreBeams(_setIgnoreBeams);
170  _analysisHandler->skipMultiWeights(_skipMultiWeights);
171  _analysisHandler->selectMultiWeights(_selectMultiWeights);
172  _analysisHandler->deselectMultiWeights(_deselectMultiWeights);
173  _analysisHandler->setNominalWeightName(_setNominalWeightName);
174  _analysisHandler->setWeightCap(_weightCap);
175  _analysisHandler->setNLOSmearing(_NLOSmearing);
176 
177  _analysisHandler->init(*myGenEvent);
178 
179  _isFirstEvent = false;
180  }
181 
182  //run the analysis
183  _analysisHandler->analyze(*myGenEvent);
184 }
185 
186 void RivetAnalyzer::endRun(const edm::Run& iRun, const edm::EventSetup& iSetup) {
187  if (_doFinalize)
188  _analysisHandler->finalize();
189  _analysisHandler->writeData(_outFileName);
190 
191  return;
192 }
193 
195 
void analyze(const edm::Event &, const edm::EventSetup &) override
void endRun(const edm::Run &, const edm::EventSetup &) override
std::string _deselectMultiWeights
Definition: RivetAnalyzer.h:46
std::unique_ptr< Rivet::AnalysisHandler > _analysisHandler
Definition: RivetAnalyzer.h:52
double originalXWGTUP() const
headers_const_iterator headers_begin() const
std::vector< std::string > _cleanedWeightNames
Definition: RivetAnalyzer.h:61
std::string _setNominalWeightName
Definition: RivetAnalyzer.h:47
std::vector< std::string > _analysisNames
Definition: RivetAnalyzer.h:55
bool _setIgnoreBeams
Definition: RivetAnalyzer.h:43
static std::string to_string(const XMLCh *ch)
const edm::InputTag _lheLabel
Definition: RivetAnalyzer.h:57
headers_const_iterator headers_end() const
int iEvent
Definition: GenABIO.cc:224
std::string _selectMultiWeights
Definition: RivetAnalyzer.h:45
void beginJob() override
bool getByLabel(std::string const &label, Handle< PROD > &result) const
Definition: Run.h:283
bool _skipMultiWeights
Definition: RivetAnalyzer.h:44
#define DEFINE_FWK_MODULE(type)
Definition: MakerMacros.h:16
void beginRun(const edm::Run &, const edm::EventSetup &) override
RivetAnalyzer(const edm::ParameterSet &)
edm::EDGetTokenT< GenLumiInfoHeader > _genLumiInfoToken
Definition: RivetAnalyzer.h:50
const HepMC::GenEvent * GetEvent() const
Definition: HepMCProduct.h:37
edm::EDGetTokenT< edm::HepMCProduct > _hepmcCollection
Definition: RivetAnalyzer.h:39
edm::EDGetTokenT< LHERunInfoProduct > _lheRunInfoToken
Definition: RivetAnalyzer.h:51
double _xsection
Definition: RivetAnalyzer.h:58
std::vector< std::string > _lheWeightNames
Definition: RivetAnalyzer.h:60
std::string _outFileName
Definition: RivetAnalyzer.h:54
HLT enums.
void endJob() override
edm::EDGetTokenT< LHEEventProduct > _LHECollection
Definition: RivetAnalyzer.h:48
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:59
const std::vector< WGT > & weights() const
Definition: Run.h:45
double _NLOSmearing
Definition: RivetAnalyzer.h:42
double _weightCap
Definition: RivetAnalyzer.h:41
~RivetAnalyzer() override