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  // other
78  TTree* tree_;
79 
81  std::vector<float> vars_;
82  int nVars_;
83 
84  //global variables
86  int genNpu_;
87  int vtxN_;
88 
89  // electron variables
90  float eleQ_;
91  int ele3Q_;
94 
95 
96  // gap variables
97  bool eleIsEB_;
98  bool eleIsEE_;
104 
105  // to hold ID decisions and categories
106  std::vector<int> mvaPasses_;
107  std::vector<float> mvaValues_;
108  std::vector<int> mvaCats_;
109 
110  // config
111  const bool isMC_;
112  const double deltaR_;
113  const double ptThreshold_;
114 
115  // ID decisions objects
116  const std::vector< std::string > eleMapTags_;
117  std::vector< edm::EDGetTokenT< edm::ValueMap<bool> > > eleMapTokens_;
118  const std::vector< std::string > eleMapBranchNames_;
119  const size_t nEleMaps_;
120 
121  // MVA values and categories (optional)
122  const std::vector< std::string > valMapTags_;
123  std::vector< edm::EDGetTokenT<edm::ValueMap<float> > > valMapTokens_;
124  const std::vector< std::string > valMapBranchNames_;
125  const size_t nValMaps_;
126 
127  const std::vector< std::string > mvaCatTags_;
128  std::vector< edm::EDGetTokenT<edm::ValueMap<int> > > mvaCatTokens_;
129  const std::vector< std::string > mvaCatBranchNames_;
130  const size_t nCats_;
131 
132  // Tokens for AOD and MiniAOD case
137 };
138 
139 //
140 // constants, enums and typedefs
141 //
142 
148  }; // The last does not include tau parents
149 
150 //
151 // static data member definitions
152 //
153 
154 //
155 // constructors and destructor
156 //
158  : mvaVarMngr_ (iConfig.getParameter<std::string>("variableDefinition"))
159  , isMC_ (iConfig.getParameter<bool>("isMC"))
160  , deltaR_ (iConfig.getParameter<double>("deltaR"))
161  , ptThreshold_ (iConfig.getParameter<double>("ptThreshold"))
162  , eleMapTags_ (iConfig.getUntrackedParameter<std::vector<std::string>>("eleMVAs"))
163  , eleMapBranchNames_ (iConfig.getUntrackedParameter<std::vector<std::string>>("eleMVALabels"))
165  , valMapTags_ (iConfig.getUntrackedParameter<std::vector<std::string>>("eleMVAValMaps"))
166  , valMapBranchNames_ (iConfig.getUntrackedParameter<std::vector<std::string>>("eleMVAValMapLabels"))
168  , mvaCatTags_ (iConfig.getUntrackedParameter<std::vector<std::string>>("eleMVACats"))
169  , mvaCatBranchNames_ (iConfig.getUntrackedParameter<std::vector<std::string>>("eleMVACatLabels"))
171  , src_ (consumesCollector(), iConfig, "src" , "srcMiniAOD")
172  , vertices_ (src_, consumesCollector(), iConfig, "vertices" , "verticesMiniAOD")
173  , pileup_ (src_, consumesCollector(), iConfig, "pileup" , "pileupMiniAOD")
174  , genParticles_ (src_, consumesCollector(), iConfig, "genParticles", "genParticlesMiniAOD")
175 {
176  // eleMaps
177  for (size_t k = 0; k < nEleMaps_; ++k) {
178 
180 
181  // Initialize vectors for holding ID decisions
182  mvaPasses_.push_back(0);
183  }
184 
185  // valMaps
186  for (size_t k = 0; k < nValMaps_; ++k) {
188 
189  // Initialize vectors for holding MVA values
190  mvaValues_.push_back(0.0);
191  }
192 
193  // categories
194  for (size_t k = 0; k < nCats_; ++k) {
196 
197  // Initialize vectors for holding MVA values
198  mvaCats_.push_back(0);
199  }
200 
201  // Book tree
202  usesResource(TFileService::kSharedResource);
204  tree_ = fs->make<TTree>("tree","tree");
205 
207 
208  tree_->Branch("nEvent", &nEvent_);
209  tree_->Branch("nRun", &nRun_);
210  tree_->Branch("nLumi", &nLumi_);
211  if (isMC_) tree_->Branch("genNpu", &genNpu_);
212  tree_->Branch("vtxN", &vtxN_);
213 
214  tree_->Branch("ele_q",&eleQ_);
215  tree_->Branch("ele_3q",&ele3Q_);
216 
217  if (isMC_) {
218  tree_->Branch("matchedToGenEle", &matchedToGenEle_);
219  }
220 
221  // Has to be in two different loops
222  for (int i = 0; i < nVars_; ++i) {
223  vars_.push_back(0.0);
224  }
225  for (int i = 0; i < nVars_; ++i) {
226  tree_->Branch(mvaVarMngr_.getName(i).c_str(), &vars_[i]);
227  }
228 
229  tree_->Branch("ele_isEB",&eleIsEB_);
230  tree_->Branch("ele_isEE",&eleIsEE_);
231  tree_->Branch("ele_isEBEtaGap",&eleIsEBEtaGap_);
232  tree_->Branch("ele_isEBPhiGap",&eleIsEBPhiGap_);
233  tree_->Branch("ele_isEBEEGap", &eleIsEBEEGap_);
234  tree_->Branch("ele_isEEDeeGap",&eleIsEEDeeGap_);
235  tree_->Branch("ele_isEERingGap",&eleIsEERingGap_);
236 
237  // IDs
238  for (size_t k = 0; k < nValMaps_; ++k) {
239  tree_->Branch(valMapBranchNames_[k].c_str() , &mvaValues_[k]);
240  }
241 
242  for (size_t k = 0; k < nEleMaps_; ++k) {
243  tree_->Branch(eleMapBranchNames_[k].c_str() , &mvaPasses_[k]);
244  }
245 
246  for (size_t k = 0; k < nCats_; ++k) {
247  tree_->Branch(mvaCatBranchNames_[k].c_str() , &mvaCats_[k]);
248  }
249 
250  // All tokens for event content needed by this MVA
251  // Tags from the variable helper
253 }
254 
255 
257 {
258 
259  // do anything here that needs to be done at desctruction time
260  // (e.g. close files, deallocate resources etc.)
261 
262 }
263 
264 
265 //
266 // member functions
267 //
268 
269 // ------------ method called for each event ------------
270 void
272 {
273  // Fill global event info
274  nEvent_ = iEvent.id().event();
275  nRun_ = iEvent.id().run();
276  nLumi_ = iEvent.luminosityBlock();
277 
278  // Get Handles
279  auto src = src_.getValidHandle(iEvent);
280  auto vertices = vertices_.getValidHandle(iEvent);
281 
282  // Get MC only Handles, which are allowed to be non-valid
283  auto genParticles = genParticles_.getHandle(iEvent);
284  auto pileup = pileup_.getHandle(iEvent);
285 
286  vtxN_ = vertices->size();
287 
288  // Fill with true number of pileup
289  if(isMC_) {
290  for(const auto& pu : *pileup)
291  {
292  int bx = pu.getBunchCrossing();
293  if(bx == 0)
294  {
295  genNpu_ = pu.getPU_NumInteractions();
296  break;
297  }
298  }
299  }
300 
301  // Get MVA decisions
303  for (size_t k = 0; k < nEleMaps_; ++k) {
304  iEvent.getByToken(eleMapTokens_[k],decisions[k]);
305  }
306 
307  // Get MVA values
309  for (size_t k = 0; k < nValMaps_; ++k) {
310  iEvent.getByToken(valMapTokens_[k],values[k]);
311  }
312 
313  // Get MVA categories
315  for (size_t k = 0; k < nCats_; ++k) {
316  iEvent.getByToken(mvaCatTokens_[k],mvaCats[k]);
317  }
318 
319  for(size_t iEle = 0; iEle < src->size(); ++iEle) {
320 
321  const auto ele = src->ptrAt(iEle);
322 
323  eleQ_ = ele->charge();
324  ele3Q_ = ele->chargeInfo().isGsfCtfScPixConsistent;
325 
326  if (ele->pt() < ptThreshold_) {
327  continue;
328  }
329 
330  for (int iVar = 0; iVar < nVars_; ++iVar) {
331  vars_[iVar] = mvaVarMngr_.getValue(iVar, ele, iEvent);
332  }
333 
334  if (isMC_) {
336  }
337 
338  // gap variables
339  eleIsEB_ = ele->isEB();
340  eleIsEE_ = ele->isEE();
341  eleIsEBEEGap_ = ele->isEBEEGap();
342  eleIsEBEtaGap_ = ele->isEBEtaGap();
343  eleIsEBPhiGap_ = ele->isEBPhiGap();
344  eleIsEEDeeGap_ = ele->isEEDeeGap();
345  eleIsEERingGap_ = ele->isEERingGap();
346 
347  //
348  // Look up and save the ID decisions
349  //
350  for (size_t k = 0; k < nEleMaps_; ++k) {
351  mvaPasses_[k] = (int)(*decisions[k])[ele];
352  }
353 
354  for (size_t k = 0; k < nValMaps_; ++k) {
355  mvaValues_[k] = (*values[k])[ele];
356  }
357 
358  for (size_t k = 0; k < nCats_; ++k) {
359  mvaCats_[k] = (*mvaCats[k])[ele];
360  }
361 
362 
363  tree_->Fill();
364  }
365 
366 }
367 
368 template<class T, class V>
369 int ElectronMVANtuplizer::matchToTruth(const T &el, const V &genParticles, int &genIdx){
370 
371  genIdx = -1;
372 
373  //
374  // Explicit loop and geometric matching method (advised by Josh Bendavid)
375  //
376 
377  // Find the closest status 1 gen electron to the reco electron
378  double dR = 999;
379  for(size_t i=0; i<genParticles->size();i++){
380  const auto particle = genParticles->ptrAt(i);
381  // Drop everything that is not electron or not status 1
382  if( abs(particle->pdgId()) != 11 || particle->status() != 1 )
383  continue;
384  //
385  double dRtmp = ROOT::Math::VectorUtil::DeltaR( el->p4(), particle->p4() );
386  if( dRtmp < dR ){
387  dR = dRtmp;
388  genIdx = i;
389  }
390  }
391  // See if the closest electron is close enough. If not, no match found.
392  if( genIdx == -1 || dR >= deltaR_ ) {
393  return UNMATCHED;
394  }
395 
396  const auto closestElectron = genParticles->ptrAt(genIdx);
397 
398  if( closestElectron->fromHardProcessFinalState() )
399  return TRUE_PROMPT_ELECTRON;
400 
401  if( closestElectron->isDirectHardProcessTauDecayProductFinalState() )
402  return TRUE_ELECTRON_FROM_TAU;
403 
404  // What remains is true non-prompt electrons
406 }
407 
408 // ------------ method fills 'descriptions' with the allowed parameters for the module ------------
409 void
411 
413  desc.add<edm::InputTag>("src");
414  desc.add<edm::InputTag>("vertices");
415  desc.add<edm::InputTag>("pileup");
416  desc.add<edm::InputTag>("genParticles");
417  desc.add<edm::InputTag>("srcMiniAOD");
418  desc.add<edm::InputTag>("verticesMiniAOD");
419  desc.add<edm::InputTag>("pileupMiniAOD");
420  desc.add<edm::InputTag>("genParticlesMiniAOD");
421  desc.add<std::string>("variableDefinition");
422  desc.add<bool>("isMC");
423  desc.add<double>("deltaR", 0.1);
424  desc.add<double>("ptThreshold", 5.0);
425  desc.addUntracked<std::vector<std::string>>("eleMVAs");
426  desc.addUntracked<std::vector<std::string>>("eleMVALabels");
427  desc.addUntracked<std::vector<std::string>>("eleMVAValMaps");
428  desc.addUntracked<std::vector<std::string>>("eleMVAValMapLabels");
429  desc.addUntracked<std::vector<std::string>>("eleMVACats");
430  desc.addUntracked<std::vector<std::string>>("eleMVACatLabels");
431  descriptions.addDefault(desc);
432 
433 }
434 
435 //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)
void setConsumes(edm::ConsumesCollector &&cc)
EventNumber_t event() const
Definition: EventID.h:41
const std::string & getName(int index) const
MultiTokenT< edm::View< reco::GsfElectron > > src_
edm::Handle< T > getHandle(const edm::Event &iEvent)
Definition: MultiToken.h:57
ParameterDescriptionBase * addUntracked(U const &iLabel, T const &value)
MultiTokenT< std::vector< reco::Vertex > > vertices_
bool getByToken(EDGetToken token, Handle< PROD > &result) const
Definition: Event.h:579
#define DEFINE_FWK_MODULE(type)
Definition: MakerMacros.h:17
edm::LuminosityBlockNumber_t luminosityBlock() const
Definition: EventBase.h:63
T * make(const Args &...args) const
make new ROOT object
Definition: TFileService.h:64
std::vector< edm::EDGetTokenT< edm::ValueMap< int > > > mvaCatTokens_
std::vector< float > mvaValues_
MultiTokenT< edm::View< reco::GenParticle > > genParticles_
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_
MultiTokenT< std::vector< PileupSummaryInfo > > pileup_
ElectronMVANtuplizer(const edm::ParameterSet &)
int matchToTruth(const T &el, const V &genParticles, int &genIdx)
ParameterDescriptionBase * add(U const &iLabel, T const &value)
int k[5][pyjets_maxn]
edm::Handle< T > getValidHandle(const edm::Event &iEvent)
Definition: MultiToken.h:83
const std::vector< std::string > eleMapBranchNames_
std::vector< float > vars_
MVAVariableManager< reco::GsfElectron > mvaVarMngr_
float getValue(int index, const edm::Ptr< ParticleType > &ptclPtr, const edm::EventBase &iEvent) const
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
const std::vector< std::string > mvaCatTags_
std::vector< edm::EDGetTokenT< edm::ValueMap< bool > > > eleMapTokens_
long double T
const std::vector< std::string > mvaCatBranchNames_
const std::vector< std::string > eleMapTags_
const std::vector< std::string > valMapTags_