CMS 3D CMS Logo

ElectronMVANtuplizer.cc
Go to the documentation of this file.
1 // -*- C++ -*-
2 //
3 // Package: RecoEgamma/ElectronIdentification
4 // Class: ElectronMVANtuplizer
5 //
13 //
14 // Original Author: Jonas REMBSER
15 // Created: Thu, 22 Mar 2018 14:54:24 GMT
16 //
17 //
18 
19 
20 // user include files
28 
30 
33 
36 
37 
41 
42 #include <TTree.h>
43 #include <TFile.h>
44 #include <Math/VectorUtil.h>
45 
46 //
47 // class declaration
48 //
49 
50 // If the analyzer does not use TFileService, please remove
51 // the template argument to the base class so the class inherits
52 // from edm::one::EDAnalyzer<>
53 // This will improve performance in multithreaded jobs.
54 //
55 
56 class ElectronMVANtuplizer : public edm::one::EDAnalyzer<edm::one::SharedResources> {
57  public:
58  explicit ElectronMVANtuplizer(const edm::ParameterSet&);
59  ~ElectronMVANtuplizer() override;
60 
61  static void fillDescriptions(edm::ConfigurationDescriptions& descriptions);
62 
63 
64  private:
65  void analyze(const edm::Event&, const edm::EventSetup&) override;
66 
67  // method called once each job just before starting event loop
68  void beginJob() override {};
69  // method called once each job just after ending the event loop
70  void endJob() override {};
71 
72  template<class T, class V>
73  int matchToTruth(const T &el, const V &genParticles, int &genIdx);
74 
75  // ----------member data ---------------------------
76 
77  //global variables
79  int genNpu_;
80  int vtxN_;
81 
82  // electron variables
83  float eleQ_;
84  int ele3Q_;
87 
88 
89  // gap variables
90  bool eleIsEB_;
91  bool eleIsEE_;
97 
98  int eleIndex_;
99 
100  // config
101  const bool isMC_;
102  const double deltaR_;
103  const double ptThreshold_;
104 
105  // ID decisions objects
106  const std::vector< std::string > eleMapTags_;
107  std::vector< edm::EDGetTokenT< edm::ValueMap<bool> > > eleMapTokens_;
108  const std::vector< std::string > eleMapBranchNames_;
109  const size_t nEleMaps_;
110 
111  // MVA values and categories (optional)
112  const std::vector< std::string > valMapTags_;
113  std::vector< edm::EDGetTokenT<edm::ValueMap<float> > > valMapTokens_;
114  const std::vector< std::string > valMapBranchNames_;
115  const size_t nValMaps_;
116 
117  const std::vector< std::string > mvaCatTags_;
118  std::vector< edm::EDGetTokenT<edm::ValueMap<int> > > mvaCatTokens_;
119  const std::vector< std::string > mvaCatBranchNames_;
120  const size_t nCats_;
121 
122  // Tokens for AOD and MiniAOD case
127 
128  // to hold ID decisions and categories
129  std::vector<int> mvaPasses_;
130  std::vector<float> mvaValues_;
131  std::vector<int> mvaCats_;
132 
133  // To get the auxiliary MVA variables
135 
136  // other
137  TTree* tree_;
138 
140  const int nVars_;
141  std::vector<float> vars_;
142 
143 };
144 
145 //
146 // constants, enums and typedefs
147 //
148 
154  }; // The last does not include tau parents
155 
156 //
157 // static data member definitions
158 //
159 
160 //
161 // constructors and destructor
162 //
164  : isMC_ (iConfig.getParameter<bool>("isMC"))
165  , deltaR_ (iConfig.getParameter<double>("deltaR"))
166  , ptThreshold_ (iConfig.getParameter<double>("ptThreshold"))
167  , eleMapTags_ (iConfig.getUntrackedParameter<std::vector<std::string>>("eleMVAs"))
168  , eleMapBranchNames_ (iConfig.getUntrackedParameter<std::vector<std::string>>("eleMVALabels"))
170  , valMapTags_ (iConfig.getUntrackedParameter<std::vector<std::string>>("eleMVAValMaps"))
171  , valMapBranchNames_ (iConfig.getUntrackedParameter<std::vector<std::string>>("eleMVAValMapLabels"))
173  , mvaCatTags_ (iConfig.getUntrackedParameter<std::vector<std::string>>("eleMVACats"))
174  , mvaCatBranchNames_ (iConfig.getUntrackedParameter<std::vector<std::string>>("eleMVACatLabels"))
176  , src_ (consumesCollector(), iConfig, "src" , "srcMiniAOD")
177  , vertices_ (src_, consumesCollector(), iConfig, "vertices" , "verticesMiniAOD")
178  , pileup_ (src_, consumesCollector(), iConfig, "pileup" , "pileupMiniAOD")
179  , genParticles_ (src_, consumesCollector(), iConfig, "genParticles", "genParticlesMiniAOD")
182  , mvaCats_ (nCats_)
184  , mvaVarMngr_ (iConfig.getParameter<std::string>("variableDefinition"))
185  , nVars_ (mvaVarMngr_.getNVars())
186  , vars_ (nVars_)
187 {
188  // eleMaps
189  for (auto const& tag : eleMapTags_) {
191  }
192  // valMaps
193  for (auto const& tag : valMapTags_) {
195  }
196  // categories
197  for (auto const& tag : mvaCatTags_) {
199  }
200 
201  // Book tree
202  usesResource(TFileService::kSharedResource);
204  tree_ = fs->make<TTree>("tree","tree");
205 
206  tree_->Branch("nEvent", &nEvent_);
207  tree_->Branch("nRun", &nRun_);
208  tree_->Branch("nLumi", &nLumi_);
209  if (isMC_) tree_->Branch("genNpu", &genNpu_);
210  tree_->Branch("vtxN", &vtxN_);
211 
212  tree_->Branch("ele_q",&eleQ_);
213  tree_->Branch("ele_3q",&ele3Q_);
214 
215  if (isMC_) {
216  tree_->Branch("matchedToGenEle", &matchedToGenEle_);
217  }
218 
219  for (int i = 0; i < nVars_; ++i) {
220  tree_->Branch(mvaVarMngr_.getName(i).c_str(), &vars_[i]);
221  }
222 
223  tree_->Branch("ele_isEB",&eleIsEB_);
224  tree_->Branch("ele_isEE",&eleIsEE_);
225  tree_->Branch("ele_isEBEtaGap",&eleIsEBEtaGap_);
226  tree_->Branch("ele_isEBPhiGap",&eleIsEBPhiGap_);
227  tree_->Branch("ele_isEBEEGap", &eleIsEBEEGap_);
228  tree_->Branch("ele_isEEDeeGap",&eleIsEEDeeGap_);
229  tree_->Branch("ele_isEERingGap",&eleIsEERingGap_);
230 
231  tree_->Branch("ele_index",&eleIndex_);
232 
233  // IDs
234  for (size_t k = 0; k < nValMaps_; ++k) {
235  tree_->Branch(valMapBranchNames_[k].c_str() , &mvaValues_[k]);
236  }
237 
238  for (size_t k = 0; k < nEleMaps_; ++k) {
239  tree_->Branch(eleMapBranchNames_[k].c_str() , &mvaPasses_[k]);
240  }
241 
242  for (size_t k = 0; k < nCats_; ++k) {
243  tree_->Branch(mvaCatBranchNames_[k].c_str() , &mvaCats_[k]);
244  }
245 }
246 
247 
249 {
250 
251  // do anything here that needs to be done at desctruction time
252  // (e.g. close files, deallocate resources etc.)
253 
254 }
255 
256 
257 //
258 // member functions
259 //
260 
261 // ------------ method called for each event ------------
262 void
264 {
265  // Fill global event info
266  nEvent_ = iEvent.id().event();
267  nRun_ = iEvent.id().run();
268  nLumi_ = iEvent.luminosityBlock();
269 
270  // Get Handles
271  auto src = src_.getValidHandle(iEvent);
272  auto vertices = vertices_.getValidHandle(iEvent);
273 
274  // Get MC only Handles, which are allowed to be non-valid
275  auto genParticles = genParticles_.getHandle(iEvent);
276  auto pileup = pileup_.getHandle(iEvent);
277 
278  vtxN_ = vertices->size();
279 
280  // Fill with true number of pileup
281  if(isMC_) {
282  for(const auto& pu : *pileup)
283  {
284  int bx = pu.getBunchCrossing();
285  if(bx == 0)
286  {
287  genNpu_ = pu.getPU_NumInteractions();
288  break;
289  }
290  }
291  }
292 
293  // Get MVA decisions
295  for (size_t k = 0; k < nEleMaps_; ++k) {
296  iEvent.getByToken(eleMapTokens_[k],decisions[k]);
297  }
298 
299  // Get MVA values
301  for (size_t k = 0; k < nValMaps_; ++k) {
302  iEvent.getByToken(valMapTokens_[k],values[k]);
303  }
304 
305  // Get MVA categories
307  for (size_t k = 0; k < nCats_; ++k) {
308  iEvent.getByToken(mvaCatTokens_[k],mvaCats[k]);
309  }
310 
311  eleIndex_ = -1;
312  for(size_t iEle = 0; iEle < src->size(); ++iEle) {
313 
314  ++eleIndex_;
315 
316  const auto ele = src->ptrAt(iEle);
317 
318  eleQ_ = ele->charge();
319  ele3Q_ = ele->chargeInfo().isGsfCtfScPixConsistent;
320 
321  if (ele->pt() < ptThreshold_) {
322  continue;
323  }
324 
325  for (int iVar = 0; iVar < nVars_; ++iVar) {
326  std::vector<float> extraVariables = variableHelper_.getAuxVariables(ele, iEvent);
327  vars_[iVar] = mvaVarMngr_.getValue(iVar, *ele, extraVariables);
328  }
329 
330  if (isMC_) {
332  }
333 
334  // gap variables
335  eleIsEB_ = ele->isEB();
336  eleIsEE_ = ele->isEE();
337  eleIsEBEEGap_ = ele->isEBEEGap();
338  eleIsEBEtaGap_ = ele->isEBEtaGap();
339  eleIsEBPhiGap_ = ele->isEBPhiGap();
340  eleIsEEDeeGap_ = ele->isEEDeeGap();
341  eleIsEERingGap_ = ele->isEERingGap();
342 
343  //
344  // Look up and save the ID decisions
345  //
346  for (size_t k = 0; k < nEleMaps_; ++k) {
347  mvaPasses_[k] = static_cast<int>((*decisions[k])[ele]);
348  }
349 
350  for (size_t k = 0; k < nValMaps_; ++k) {
351  mvaValues_[k] = (*values[k])[ele];
352  }
353 
354  for (size_t k = 0; k < nCats_; ++k) {
355  mvaCats_[k] = (*mvaCats[k])[ele];
356  }
357 
358 
359  tree_->Fill();
360  }
361 
362 }
363 
364 template<class T, class V>
365 int ElectronMVANtuplizer::matchToTruth(const T &el, const V &genParticles, int &genIdx){
366 
367  genIdx = -1;
368 
369  //
370  // Explicit loop and geometric matching method (advised by Josh Bendavid)
371  //
372 
373  // Find the closest status 1 gen electron to the reco electron
374  double dR = 999;
375  for(size_t i=0; i<genParticles->size();i++){
376  const auto particle = genParticles->ptrAt(i);
377  // Drop everything that is not electron or not status 1
378  if( abs(particle->pdgId()) != 11 || particle->status() != 1 )
379  continue;
380  //
381  double dRtmp = ROOT::Math::VectorUtil::DeltaR( el->p4(), particle->p4() );
382  if( dRtmp < dR ){
383  dR = dRtmp;
384  genIdx = i;
385  }
386  }
387  // See if the closest electron is close enough. If not, no match found.
388  if( genIdx == -1 || dR >= deltaR_ ) {
389  return UNMATCHED;
390  }
391 
392  const auto closestElectron = genParticles->ptrAt(genIdx);
393 
394  if( closestElectron->fromHardProcessFinalState() )
395  return TRUE_PROMPT_ELECTRON;
396 
397  if( closestElectron->isDirectHardProcessTauDecayProductFinalState() )
398  return TRUE_ELECTRON_FROM_TAU;
399 
400  // What remains is true non-prompt electrons
402 }
403 
404 // ------------ method fills 'descriptions' with the allowed parameters for the module ------------
405 void
407 {
409  desc.add<edm::InputTag>("src", edm::InputTag("gedGsfElectrons"));
410  desc.add<edm::InputTag>("vertices", edm::InputTag("offlinePrimaryVertices"));
411  desc.add<edm::InputTag>("pileup", edm::InputTag("addPileupInfo"));
412  desc.add<edm::InputTag>("genParticles", edm::InputTag("genParticles"));
413  desc.add<edm::InputTag>("srcMiniAOD", edm::InputTag("slimmedElectrons"));
414  desc.add<edm::InputTag>("verticesMiniAOD", edm::InputTag("offlineSlimmedPrimaryVertices"));
415  desc.add<edm::InputTag>("pileupMiniAOD", edm::InputTag("slimmedAddPileupInfo"));
416  desc.add<edm::InputTag>("genParticlesMiniAOD", edm::InputTag("prunedGenParticles"));
417  desc.add<std::string>("variableDefinition");
418  desc.add<bool>("isMC", true);
419  desc.add<double>("deltaR", 0.1);
420  desc.add<double>("ptThreshold", 5.0);
421  desc.addUntracked<std::vector<std::string>>("eleMVAs", {});
422  desc.addUntracked<std::vector<std::string>>("eleMVALabels", {});
423  desc.addUntracked<std::vector<std::string>>("eleMVAValMaps", {});
424  desc.addUntracked<std::vector<std::string>>("eleMVAValMapLabels", {});
425  desc.addUntracked<std::vector<std::string>>("eleMVACats", {});
426  desc.addUntracked<std::vector<std::string>>("eleMVACatLabels", {});
427  descriptions.addDefault(desc);
428 
429 }
430 
431 //define this as a plug-in
RunNumber_t run() const
Definition: EventID.h:39
size
Write out results.
static const std::string kSharedResource
Definition: TFileService.h:76
static void fillDescriptions(edm::ConfigurationDescriptions &descriptions)
EventNumber_t event() const
Definition: EventID.h:41
const std::string & getName(int index) const
ParameterDescriptionBase * addUntracked(U const &iLabel, T const &value)
const MVAVariableHelper< reco::GsfElectron > variableHelper_
bool getByToken(EDGetToken token, Handle< PROD > &result) const
Definition: Event.h:579
#define DEFINE_FWK_MODULE(type)
Definition: MakerMacros.h:17
const MultiTokenT< edm::View< reco::GenParticle > > genParticles_
edm::LuminosityBlockNumber_t luminosityBlock() const
Definition: EventBase.h:63
T * make(const Args &...args) const
make new ROOT object
Definition: TFileService.h:64
float getValue(int index, const ParticleType &particle, const std::vector< float > &auxVariables) const
std::vector< edm::EDGetTokenT< edm::ValueMap< int > > > mvaCatTokens_
std::vector< float > mvaValues_
EDGetTokenT< ProductType > consumes(edm::InputTag const &tag)
int iEvent
Definition: GenABIO.cc:230
void addDefault(ParameterSetDescription const &psetDescription)
ConsumesCollector consumesCollector()
Use a ConsumesCollector to gather consumes information from helper functions.
std::vector< int > mvaPasses_
const std::vector< std::string > valMapBranchNames_
Abs< T >::type abs(const T &t)
Definition: Abs.h:22
std::vector< int > mvaCats_
ElectronMVANtuplizer(const edm::ParameterSet &)
int matchToTruth(const T &el, const V &genParticles, int &genIdx)
edm::Handle< T > getValidHandle(const edm::Event &iEvent) const
Definition: MultiToken.h:95
ParameterDescriptionBase * add(U const &iLabel, T const &value)
int k[5][pyjets_maxn]
const std::vector< std::string > eleMapBranchNames_
const std::vector< float > getAuxVariables(edm::Ptr< ParticleType > const &particlePtr, const edm::Event &iEvent) const
std::vector< float > vars_
const MultiTokenT< std::vector< PileupSummaryInfo > > pileup_
MVAVariableManager< reco::GsfElectron > mvaVarMngr_
std::vector< edm::EDGetTokenT< edm::ValueMap< float > > > valMapTokens_
void analyze(const edm::Event &, const edm::EventSetup &) override
edm::EventID id() const
Definition: EventBase.h:60
edm::Handle< T > getHandle(const edm::Event &iEvent) const
Definition: MultiToken.h:69
const MultiTokenT< std::vector< reco::Vertex > > vertices_
const std::vector< std::string > mvaCatTags_
std::vector< edm::EDGetTokenT< edm::ValueMap< bool > > > eleMapTokens_
const MultiTokenT< edm::View< reco::GsfElectron > > src_
long double T
const std::vector< std::string > mvaCatBranchNames_
const std::vector< std::string > eleMapTags_
const std::vector< std::string > valMapTags_